Upgrade dagger2 to 347cfe1352469381f4391091e8bfa242214c68cc am: 311df9bffa Original change: https://android-review.googlesource.com/c/platform/external/dagger2/+/3446311 Change-Id: I89f8b73361cb8789be8e89ff1601a372ac883e49 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.allstar/binary_artifacts.yaml b/.allstar/binary_artifacts.yaml index 38e18be..61d0f0b 100644 --- a/.allstar/binary_artifacts.yaml +++ b/.allstar/binary_artifacts.yaml
@@ -9,3 +9,5 @@ - java/dagger/internal/codegen/kythe/kythe_plugin_deploy.jar # TODO(b/235380696): remove this - java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar - java/dagger/internal/codegen/xprocessing/xprocessing.jar +- tools/jarjar/test/test-library1.jar +- tools/jarjar/test/test-library2.jar \ No newline at end of file
diff --git a/.bazelrc b/.bazelrc index ecd54a5..e02e83d 100644 --- a/.bazelrc +++ b/.bazelrc
@@ -6,3 +6,27 @@ # TODO(ronshapiro): explore how much work it would be to reenable this build --javacopt="-Xep:BetaApi:OFF" build --host_javacopt="-Xep:BetaApi:OFF" + +# Note: This flag is required to prevent actions from clashing with each other +# 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 + +# Sets the JDK for compiling sources and executing tests. +build --java_language_version=18 +build --tool_java_language_version=18 +build --java_runtime_version=remotejdk_18 +build --tool_java_runtime_version=remotejdk_18 + +# Default source/target versions. +build --javacopt="-source 8 -target 8" + +# Workaround for https://openjdk.java.net/jeps/411. +# See https://github.com/bazelbuild/bazel/issues/14502#issuecomment-1018366245. +build --jvmopt="-Djava.security.manager=allow" +build --jvmopt="--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"
diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 0000000..c0be8a7 --- /dev/null +++ b/.bazelversion
@@ -0,0 +1 @@ +6.4.0 \ No newline at end of file
diff --git a/.github/actions/artifact-android-emulator-tests/action.yml b/.github/actions/artifact-android-emulator-tests/action.yml index 2fc2987..93494f0 100644 --- a/.github/actions/artifact-android-emulator-tests/action.yml +++ b/.github/actions/artifact-android-emulator-tests/action.yml
@@ -10,9 +10,9 @@ using: "composite" steps: - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -21,12 +21,12 @@ restore-keys: | ${{ runner.os }}-gradle- - name: 'Download local snapshot for tests' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: local-snapshot path: ~/.m2/repository/com/google/dagger - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' @@ -38,7 +38,7 @@ script: ./util/run-local-emulator-tests.sh - name: 'Upload test reports (API ${{ inputs.api-level }})' if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: androidTests-report-api-${{ inputs.api-level }} path: ${{ github.workspace }}/**/build/reports/androidTests/connected/*
diff --git a/.github/actions/artifact-android-local-tests/action.yml b/.github/actions/artifact-android-local-tests/action.yml index c4b24eb..b16ab13 100644 --- a/.github/actions/artifact-android-local-tests/action.yml +++ b/.github/actions/artifact-android-local-tests/action.yml
@@ -7,9 +7,7 @@ required: true type: choice options: - - '7.0.0' - - '7.1.2' - - '8.1.0' + - '8.1.1' jdk: description: 'The version of JDK to test with.' required: true @@ -22,9 +20,9 @@ using: "composite" steps: - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -33,12 +31,12 @@ restore-keys: | ${{ runner.os }}-gradle- - name: 'Download local snapshot for tests' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: local-snapshot path: ~/.m2/repository/com/google/dagger - name: 'Install Java ${{ inputs.jdk }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ inputs.jdk }}' @@ -47,7 +45,7 @@ shell: bash - name: 'Upload test reports (AGP ${{ inputs.agp }})' if: ${{ always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: tests-reports-agp-${{ inputs.agp }} path: ${{ github.workspace }}/**/build/reports/tests/*
diff --git a/.github/actions/artifact-java-local-tests/action.yml b/.github/actions/artifact-java-local-tests/action.yml index e3cf770..bfe997a 100644 --- a/.github/actions/artifact-java-local-tests/action.yml +++ b/.github/actions/artifact-java-local-tests/action.yml
@@ -5,9 +5,9 @@ using: "composite" steps: - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -16,7 +16,7 @@ restore-keys: | ${{ runner.os }}-gradle- - name: 'Download local snapshot for tests' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: local-snapshot path: ~/.m2/repository/com/google/dagger
diff --git a/.github/actions/artifact-verification-tests/action.yml b/.github/actions/artifact-verification-tests/action.yml new file mode 100644 index 0000000..30b44fd --- /dev/null +++ b/.github/actions/artifact-verification-tests/action.yml
@@ -0,0 +1,25 @@ +name: 'Artifact verification tests' +description: 'Runs verification tests on the Dagger LOCAL-SNAPSHOT artifacts.' + +runs: + using: "composite" + steps: + - name: 'Check out repository' + uses: actions/checkout@v4 + - name: 'Cache Gradle files' + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: 'Download local snapshot for tests' + uses: actions/download-artifact@v4 + with: + name: local-snapshot + path: ~/.m2/repository/com/google/dagger + - name: 'Validate artifact jars' + run: ./util/validate-artifacts.sh + shell: bash
diff --git a/.github/actions/bazel-build/action.yml b/.github/actions/bazel-build/action.yml index c464dfe..ab820b4 100644 --- a/.github/actions/bazel-build/action.yml +++ b/.github/actions/bazel-build/action.yml
@@ -5,14 +5,14 @@ using: "composite" steps: - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel key: ${{ runner.os }}-bazel-build-${{ github.sha }} @@ -28,7 +28,7 @@ run: ./util/install-local-snapshot.sh shell: bash - name: 'Upload local snapshot for tests' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: local-snapshot path: ~/.m2/repository/com/google/dagger
diff --git a/.github/actions/bazel-test/action.yml b/.github/actions/bazel-test/action.yml index d84f061..9f82546 100644 --- a/.github/actions/bazel-test/action.yml +++ b/.github/actions/bazel-test/action.yml
@@ -5,14 +5,14 @@ using: "composite" steps: - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache local Maven repository' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.m2/repository @@ -21,7 +21,7 @@ restore-keys: | ${{ runner.os }}-maven- - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel # Note: we could use the same key as bazel-build, but we separate them @@ -31,7 +31,7 @@ restore-keys: | ${{ runner.os }}-bazel-test- - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches
diff --git a/.github/actions/build-gradle-plugin/action.yml b/.github/actions/build-gradle-plugin/action.yml index 4fb3293..31a5367 100644 --- a/.github/actions/build-gradle-plugin/action.yml +++ b/.github/actions/build-gradle-plugin/action.yml
@@ -10,14 +10,14 @@ using: "composite" steps: - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache local Maven repository' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.m2/repository @@ -26,14 +26,14 @@ restore-keys: | ${{ runner.os }}-maven- - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel key: ${{ runner.os }}-bazel-build-${{ github.sha }} restore-keys: | ${{ runner.os }}-bazel-build- - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches
diff --git a/.github/actions/cleanup-caches/action.yml b/.github/actions/cleanup-caches/action.yml index 294d624..0197d8f 100644 --- a/.github/actions/cleanup-caches/action.yml +++ b/.github/actions/cleanup-caches/action.yml
@@ -5,7 +5,7 @@ using: "composite" steps: - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cleanup caches' run: python ./util/cleanup-github-caches.py shell: bash
diff --git a/.github/actions/gradle-build/action.yml b/.github/actions/gradle-build/action.yml new file mode 100644 index 0000000..14d372c --- /dev/null +++ b/.github/actions/gradle-build/action.yml
@@ -0,0 +1,25 @@ +name: 'Gradle Build' +description: 'Builds artifacts using Gradle.' + +runs: + using: "composite" + steps: + - name: 'Install Java ${{ env.USE_JAVA_VERSION_FOR_GRADLE }}' + uses: actions/setup-java@v4 + with: + distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' + java-version: '${{ env.USE_JAVA_VERSION_FOR_GRADLE }}' + - name: 'Check out repository' + uses: actions/checkout@v4 + - name: 'Cache Gradle files' + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: 'Build Gradle version' + run: ./util/build-gradle.sh + shell: bash
diff --git a/.github/actions/prechecks/action.yml b/.github/actions/prechecks/action.yml index 09dc5d9..1a04552 100644 --- a/.github/actions/prechecks/action.yml +++ b/.github/actions/prechecks/action.yml
@@ -11,7 +11,7 @@ with: access_token: ${{ github.token }} - name: 'Check out gh-pages repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: 'refs/heads/gh-pages' path: gh-pages @@ -21,7 +21,7 @@ env: GH_TOKEN: ${{ github.token }} - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cleanup caches' run: python ./util/cleanup-github-caches.py shell: bash
diff --git a/.github/actions/test-gradle-plugin/action.yml b/.github/actions/test-gradle-plugin/action.yml index bd57472..3205174 100644 --- a/.github/actions/test-gradle-plugin/action.yml +++ b/.github/actions/test-gradle-plugin/action.yml
@@ -4,15 +4,15 @@ runs: using: "composite" steps: - - name: 'Install Java ${{ env.USE_JAVA_VERSION_FOR_PLUGIN }}' - uses: actions/setup-java@v3 + - name: 'Install Java ${{ env.USE_JAVA_VERSION_FOR_GRADLE_PLUGIN }}' + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' - java-version: '${{ env.USE_JAVA_VERSION_FOR_PLUGIN }}' + java-version: '${{ env.USE_JAVA_VERSION_FOR_GRADLE_PLUGIN }}' - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache local Maven repository' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.m2/repository @@ -21,14 +21,14 @@ restore-keys: | ${{ runner.os }}-maven- - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel key: ${{ runner.os }}-bazel-build-${{ github.sha }} restore-keys: | ${{ runner.os }}-bazel-build- - name: 'Cache Gradle files' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -37,7 +37,7 @@ restore-keys: | ${{ runner.os }}-gradle- - name: 'Download local snapshot for tests' - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: local-snapshot path: ~/.m2/repository/com/google/dagger
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d50fcec..d0d89f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml
@@ -11,11 +11,10 @@ env: USE_JAVA_DISTRIBUTION: 'zulu' USE_JAVA_VERSION: '11' - # 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: '6.4.0' + # This is required by Gradle 8.0+. + USE_JAVA_VERSION_FOR_GRADLE_PLUGIN: '17' + # Required by JDK Toolchain Configuration + USE_JAVA_VERSION_FOR_GRADLE: '18' # 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' @@ -25,37 +24,52 @@ name: 'Validate Dagger version' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/prechecks bazel-build: name: 'Bazel build' needs: validate-latest-dagger-version runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/bazel-build bazel-test: name: 'Bazel tests' needs: validate-latest-dagger-version runs-on: - group: large-runner + group: large-runner-group labels: ubuntu-22.04-16core steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/bazel-test + gradle-build: + name: 'Gradle build' + runs-on: + group: large-runner-group + labels: ubuntu-22.04-16core + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/gradle-build + artifact-verification-tests: + name: 'Artifact verification tests' + needs: bazel-build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/artifact-verification-tests artifact-java-local-tests: name: 'Artifact Java local tests' needs: bazel-build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/artifact-java-local-tests test-gradle-plugin: name: 'Test Hilt Gradle plugin' needs: bazel-build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/test-gradle-plugin artifact-android-local-tests: name: 'Artifact Android local tests (AGP ${{ matrix.agp }})' @@ -64,14 +78,10 @@ strategy: matrix: include: - - agp: '7.0.0' - jdk: '11' - - agp: '7.1.2' - jdk: '11' - - agp: '8.1.0' + - agp: '8.1.1' jdk: '17' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/artifact-android-local-tests with: agp: '${{ matrix.agp }}' @@ -89,7 +99,7 @@ matrix: # Run on 16 (PreL), 21 (L), and 26 (O). api-level: [16, 21, 26, 30] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/artifact-android-emulator-tests timeout-minutes: 35 with: @@ -98,12 +108,18 @@ name: 'Publish snapshot' # 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] + needs: [ + bazel-test, + artifact-verification-tests, + artifact-java-local-tests, + artifact-android-local-tests, + test-gradle-plugin + ] if: github.event_name == 'push' && github.repository == 'google/dagger' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest steps: - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' @@ -111,9 +127,9 @@ server-username: CI_DEPLOY_USERNAME server-password: CI_DEPLOY_PASSWORD - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache local Maven repository' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.m2/repository @@ -122,14 +138,14 @@ restore-keys: | ${{ runner.os }}-maven- - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel key: ${{ runner.os }}-bazel-build-${{ github.sha }} restore-keys: | ${{ runner.os }}-bazel-build- - name: 'Cache Gradle files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -169,7 +185,7 @@ needs: bazel-build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/build-gradle-plugin with: agp: '+' @@ -177,8 +193,14 @@ 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] + needs: [ + bazel-test, + artifact-verification-tests, + artifact-java-local-tests, + artifact-android-local-tests, + test-gradle-plugin + ] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/cleanup-caches
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b16c0d5..9557611 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml
@@ -10,11 +10,10 @@ env: USE_JAVA_DISTRIBUTION: 'zulu' USE_JAVA_VERSION: '11' - # 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: '6.4.0' + # This is required by Gradle 8.0+. + USE_JAVA_VERSION_FOR_GRADLE_PLUGIN: '17' + # Required by JDK Toolchain Configuration + USE_JAVA_VERSION_FOR_GRADLE: '18' 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 @@ -27,37 +26,44 @@ name: 'Validate Dagger version' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/prechecks bazel-build: name: 'Bazel build' needs: validate-latest-dagger-version runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/bazel-build bazel-test: name: 'Bazel tests' needs: validate-latest-dagger-version runs-on: - group: large-runner + group: large-runner-group labels: ubuntu-22.04-16core steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/bazel-test + artifact-verification-tests: + name: 'Artifact verification tests' + needs: bazel-build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/artifact-verification-tests artifact-java-local-tests: name: 'Artifact Java local tests' needs: bazel-build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/artifact-java-local-tests test-gradle-plugin: name: 'Test Hilt Gradle plugin' needs: bazel-build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/test-gradle-plugin artifact-android-local-tests: name: 'Artifact Android local tests (AGP ${{ matrix.agp }})' @@ -66,25 +72,27 @@ strategy: matrix: include: - - agp: '7.0.0' - jdk: '11' - - agp: '7.1.2' - jdk: '11' - - agp: '8.1.0' + - agp: '8.1.1' jdk: '17' steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - 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] + needs: [ + bazel-test, + artifact-verification-tests, + artifact-java-local-tests, + artifact-android-local-tests, + test-gradle-plugin + ] runs-on: ubuntu-latest steps: - name: 'Install Java ${{ env.USE_JAVA_VERSION }}' - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: '${{ env.USE_JAVA_DISTRIBUTION }}' java-version: '${{ env.USE_JAVA_VERSION }}' @@ -94,9 +102,9 @@ gpg-private-key: ${{ secrets.CI_GPG_PRIVATE_KEY }} gpg-passphrase: CI_GPG_PASSPHRASE - name: 'Check out repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Cache local Maven repository' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.m2/repository @@ -105,14 +113,14 @@ restore-keys: | ${{ runner.os }}-maven- - name: 'Cache Bazel files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.cache/bazel key: ${{ runner.os }}-bazel-build-${{ github.sha }} restore-keys: | ${{ runner.os }}-bazel-build- - name: 'Cache Gradle files' - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.gradle/caches
diff --git a/Android.bp b/Android.bp index deb6e01..f14eb2c 100644 --- a/Android.bp +++ b/Android.bp
@@ -77,8 +77,12 @@ libs: [ "guava", + "jspecify", "jsr330", ], + static_libs: [ + "jakarta.inject", + ], apex_available: [ "//apex_available:platform", "com.android.adservices", @@ -152,6 +156,7 @@ srcs: [ "java/dagger/internal/codegen/**/*.java", + "java/dagger/internal/codegen/**/*.kt", "java/dagger/internal/codegen/**/*.proto", "java/dagger/model/*.java", @@ -172,13 +177,14 @@ "dagger2-room-compiler-processing", "google_java_format", "guava", + "jakarta.inject", "javapoet", "jsr330", + "kotlin_metadata_jvm", "kotlin_symbol_processing_api", "kotlin-stdlib", "kotlin-stdlib-jdk8", "kotlinpoet", - "kotlinx_metadata_jvm", ], libs: [ @@ -507,8 +513,8 @@ "dagger2", "javapoet", "jsr330", + "kotlin_metadata_jvm", "kotlin-stdlib", - "kotlinx_metadata_jvm", "dagger2-android-annotation-stubs", ], // shade guava to avoid conflicts with guava embedded in Error Prone.
diff --git a/BUILD b/BUILD index 2c70b01..6650ea6 100644 --- a/BUILD +++ b/BUILD
@@ -12,25 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@rules_java//java:defs.bzl", "java_library") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") -load("@google_bazel_common//tools/jarjar:jarjar.bzl", "jarjar_library") load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "define_kt_toolchain") +load("@rules_java//java:defs.bzl", "java_library") +load("//tools/jarjar:jarjar.bzl", "jarjar_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") package(default_visibility = ["//visibility:public"]) -define_kt_toolchain( - name = "kotlin_toolchain", - api_version = "1.4", - jvm_target = "1.8", - language_version = "1.4", -) - package_group( name = "src", packages = ["//..."], ) +define_kt_toolchain( + name = "kotlin_toolchain", + api_version = "1.6", + jvm_target = "1.8", + language_version = "1.6", +) + java_library( name = "dagger_with_compiler", exported_plugins = ["//java/dagger/internal/codegen:component-codegen"], @@ -116,7 +116,7 @@ "//java/dagger/producers:producers-srcs", "//java/dagger/spi:spi-srcs", ], - android_api_level = 32, + android_api_level = 34, # TODO(ronshapiro): figure out how to specify the version number for release builds doctitle = "Dagger Dependency Injection API", exclude_packages = [
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8975bcb..d2ef1ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md
@@ -44,9 +44,9 @@ [download](https://developer.android.com/studio#command-tools) and unzip it first. * Install the necessary components. For example, under Linux, run: - `$ANDROID_HOME/tools/bin/sdkmanager "platforms;android-32" "build-tools;32.0.0"` + `$ANDROID_HOME/tools/bin/sdkmanager "platforms;android-34" "build-tools;34.0.0"` * If you skip this step, you will see an error similar to - `ERROR: missing input file '@androidsdk//:build-tools/32.0.0/aapt'`. + `ERROR: missing input file '@androidsdk//:build-tools/34.0.0/aapt'`. * You may also need to run `bazel sync`. * Run tests with `bazel test <target>`, or `bazel test //...` to run all tests.
diff --git a/METADATA b/METADATA index 3511a6c..4746378 100644 --- a/METADATA +++ b/METADATA
@@ -1,20 +1,20 @@ # This project was upgraded with external_updater. # 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 +# For more info, check https://cs.android.com/android/platform/superproject/main/+/main:tools/external_updater/README.md name: "dagger2" description: "A fast dependency injector for Android and Java." third_party { license_type: NOTICE last_upgrade_date { - year: 2024 - month: 3 - day: 5 + year: 2025 + month: 1 + day: 10 } homepage: "https://dagger.dev" identifier { type: "Git" value: "https://github.com/google/dagger" - version: "dagger-2.51" + version: "347cfe1352469381f4391091e8bfa242214c68cc" } }
diff --git a/README.md b/README.md index 4f5c014..ae1ca4a 100644 --- a/README.md +++ b/README.md
@@ -38,8 +38,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -DAGGER_TAG = "2.50" -DAGGER_SHA = "764993ba2465551c181b84b47e467f86fb367d8c0cd50154bd5519a4afb57753" +DAGGER_TAG = "2.55" +DAGGER_SHA = "ad2272bb59f4b15b9f1c3dad9ec806af7b75bcf5f04e83974dad8e65c581bba4" http_archive( name = "dagger", strip_prefix = "dagger-dagger-%s" % DAGGER_TAG,
diff --git a/WORKSPACE b/WORKSPACE index 0e93e98..e84385e 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") ############################# @@ -46,6 +47,26 @@ bazel_skylib_workspace() +############################# +# Load rules_java repository +############################# + +http_archive( + name = "rules_java", + sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934", + url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz", +) + +############################# +# Load Android Sdk +############################# + +android_sdk_repository( + name = "androidsdk", + api_level = 34, + build_tools_version = "34.0.0", +) + #################################################### # Load Protobuf repository (needed by bazel-common) #################################################### @@ -68,21 +89,6 @@ 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 ############################# @@ -112,13 +118,13 @@ # Load Robolectric repository ############################# -ROBOLECTRIC_VERSION = "4.4" +ROBOLECTRIC_VERSION = "4.11.1" http_archive( name = "robolectric", - sha256 = "d4f2eb078a51f4e534ebf5e18b6cd4646d05eae9b362ac40b93831bdf46112c7", + sha256 = "1ea1cfe67848decf959316e80dd69af2bbaa359ae2195efe1366cbdf3e968356", strip_prefix = "robolectric-bazel-%s" % ROBOLECTRIC_VERSION, - urls = ["https://github.com/robolectric/robolectric-bazel/archive/%s.tar.gz" % ROBOLECTRIC_VERSION], + urls = ["https://github.com/robolectric/robolectric-bazel/releases/download/%s/robolectric-bazel-%s.tar.gz" % (ROBOLECTRIC_VERSION, ROBOLECTRIC_VERSION)], ) load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories") @@ -129,33 +135,34 @@ # Load Kotlin repository ############################# -RULES_KOTLIN_TAG = "v1.8" +RULES_KOTLIN_TAG = "1.9.6" -RULES_KOTLIN_SHA = "01293740a16e474669aba5b5a1fe3d368de5832442f164e4fbfc566815a8bc3a" +RULES_KOTLIN_SHA = "3b772976fec7bdcda1d84b9d39b176589424c047eb2175bed09aac630e50af43" http_archive( name = "io_bazel_rules_kotlin", sha256 = RULES_KOTLIN_SHA, - urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/%s/rules_kotlin_release.tgz" % RULES_KOTLIN_TAG], + urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v%s/rules_kotlin-v%s.tar.gz" % (RULES_KOTLIN_TAG, RULES_KOTLIN_TAG)], ) load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") -KOTLIN_VERSION = "1.9.20" +# TODO: update to Kotlin 2 once rules_kotlin support it. +# See https://github.com/bazelbuild/rules_kotlin/issues/1176 +KOTLINC_VERSION = "1.9.24" # Get from https://github.com/JetBrains/kotlin/releases/ -KOTLINC_RELEASE_SHA = "15a8a2825b74ccf6c44e04e97672db802d2df75ce2fbb63ef0539bf3ae5006f0" +KOTLINC_RELEASE_SHA = "eb7b68e01029fa67bc8d060ee54c12018f2c60ddc438cf21db14517229aa693b" kotlin_repositories( compiler_release = kotlinc_version( - release = KOTLIN_VERSION, + release = KOTLINC_VERSION, + # Get from https://github.com/JetBrains/kotlin/releases/ sha256 = KOTLINC_RELEASE_SHA, ), ) -load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") - -kt_register_toolchains() +register_toolchains("//:kotlin_toolchain") ############################# # Load Maven dependencies @@ -176,8 +183,20 @@ ANDROID_LINT_VERSION = "30.1.0" +ANT_VERSION = "1.9.6" + +ASM_VERSION = "9.6" + AUTO_COMMON_VERSION = "1.2.1" +BYTE_BUDDY_VERSION = "1.9.10" + +CHECKER_FRAMEWORK_VERSION = "2.5.3" + +ECLIPSE_SISU_VERSION = "0.3.0" + +ERROR_PRONE_VERSION = "2.14.0" + # 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. @@ -187,13 +206,11 @@ INCAP_VERSION = "0.2" -BYTE_BUDDY_VERSION = "1.9.10" +KOTLIN_VERSION = "2.0.21" -CHECKER_FRAMEWORK_VERSION = "2.5.3" +KSP_VERSION = KOTLIN_VERSION + "-1.0.28" -ERROR_PRONE_VERSION = "2.14.0" - -KSP_VERSION = KOTLIN_VERSION + "-1.0.14" +MAVEN_VERSION = "3.3.3" maven_install( artifacts = [ @@ -233,6 +250,8 @@ "com.google.code.findbugs:jsr305:3.0.1", "com.google.devtools.ksp:symbol-processing:%s" % KSP_VERSION, "com.google.devtools.ksp:symbol-processing-api:%s" % KSP_VERSION, + "com.google.devtools.ksp:symbol-processing-common-deps:%s" % KSP_VERSION, + "com.google.devtools.ksp:symbol-processing-aa-embeddable:%s" % KSP_VERSION, "com.google.errorprone:error_prone_annotation:%s" % ERROR_PRONE_VERSION, "com.google.errorprone:error_prone_annotations:%s" % ERROR_PRONE_VERSION, "com.google.errorprone:error_prone_check_api:%s" % ERROR_PRONE_VERSION, @@ -253,6 +272,7 @@ "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, "jakarta.inject:jakarta.inject-api:2.0.1", "javax.annotation:javax.annotation-api:1.3.2", + "javax.enterprise:cdi-api:1.0", "javax.inject:javax.inject:1", "javax.inject:javax.inject-tck:1", "junit:junit:4.13", @@ -260,20 +280,34 @@ "net.bytebuddy:byte-buddy-agent:%s" % BYTE_BUDDY_VERSION, "net.ltgt.gradle.incap:incap:%s" % INCAP_VERSION, "net.ltgt.gradle.incap:incap-processor:%s" % INCAP_VERSION, + "org.apache.ant:ant:%s" % ANT_VERSION, + "org.apache.ant:ant-launcher:%s" % ANT_VERSION, + "org.apache.maven:maven-artifact:%s" % MAVEN_VERSION, + "org.apache.maven:maven-model:%s" % MAVEN_VERSION, + "org.apache.maven:maven-plugin-api:%s" % MAVEN_VERSION, "org.checkerframework:checker-compat-qual:%s" % CHECKER_FRAMEWORK_VERSION, "org.checkerframework:dataflow:%s" % CHECKER_FRAMEWORK_VERSION, "org.checkerframework:javacutil:%s" % CHECKER_FRAMEWORK_VERSION, + "org.codehaus.plexus:plexus-utils:3.0.20", + "org.codehaus.plexus:plexus-classworlds:2.5.2", + "org.codehaus.plexus:plexus-component-annotations:1.5.5", + "org.eclipse.sisu:org.eclipse.sisu.plexus:%s" % ECLIPSE_SISU_VERSION, + "org.eclipse.sisu:org.eclipse.sisu.inject:%s" % ECLIPSE_SISU_VERSION, "org.hamcrest:hamcrest-core:1.3", "org.jetbrains.kotlin:kotlin-annotation-processing-embeddable:%s" % KOTLIN_VERSION, "org.jetbrains.kotlin:kotlin-compiler-embeddable:%s" % KOTLIN_VERSION, "org.jetbrains.kotlin:kotlin-daemon-embeddable:%s" % KOTLIN_VERSION, + "org.jetbrains.kotlin:kotlin-metadata-jvm:%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.jspecify:jspecify:1.0.0", "org.mockito:mockito-core:2.28.2", + "org.pantsbuild:jarjar:1.7.2", "org.objenesis:objenesis:1.0", - "org.robolectric:robolectric:4.4", - "org.robolectric:shadows-framework:4.4", # For ActivityController + "org.ow2.asm:asm:%s" % ASM_VERSION, + "org.ow2.asm:asm-tree:%s" % ASM_VERSION, + "org.ow2.asm:asm-commons:%s" % ASM_VERSION, + "org.robolectric:robolectric:%s" % ROBOLECTRIC_VERSION, + "org.robolectric:shadows-framework:%s" % ROBOLECTRIC_VERSION, # For ActivityController ], repositories = [ "https://repo1.maven.org/maven2",
diff --git a/buildSrc/README.md b/buildSrc/README.md new file mode 100644 index 0000000..7ebd532 --- /dev/null +++ b/buildSrc/README.md
@@ -0,0 +1,3 @@ +### Dagger's Gradle build logic + +See https://docs.gradle.org/current/userguide/organizing_gradle_projects.html#sec:build_sources \ No newline at end of file
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..66dc027 --- /dev/null +++ b/buildSrc/build.gradle.kts
@@ -0,0 +1,30 @@ +plugins { + `kotlin-dsl` +} + +kotlin { + jvmToolchain { + languageVersion.set(libs.versions.jdk.map(JavaLanguageVersion::of)) + } +} + +dependencies { + implementation(gradleApi()) + implementation(libs.kotlin.gradlePlugin) + implementation(libs.publishPlugin) +} + +gradlePlugin { + plugins { + register("kotlinJvm") { + id = libs.plugins.dagger.kotlinJvm.get().pluginId + implementationClass = "dagger.gradle.build.KotlinJvmConventionPlugin" + } + } + plugins { + register("publish") { + id = libs.plugins.dagger.publish.get().pluginId + implementationClass = "dagger.gradle.build.PublishConventionPlugin" + } + } +} \ No newline at end of file
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..c4843c5 --- /dev/null +++ b/buildSrc/settings.gradle.kts
@@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositories { + google() + mavenCentral() + } + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/dagger/gradle/build/KotlinJvmConventionPlugin.kt b/buildSrc/src/main/kotlin/dagger/gradle/build/KotlinJvmConventionPlugin.kt new file mode 100644 index 0000000..e5dd52d --- /dev/null +++ b/buildSrc/src/main/kotlin/dagger/gradle/build/KotlinJvmConventionPlugin.kt
@@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 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.gradle.build + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.gradle.jvm.toolchain.JavaLanguageVersion + +class KotlinJvmConventionPlugin : Plugin<Project> { + + override fun apply(project: Project) { + project.pluginManager.apply(project.getPluginIdByName("kotlinJvm")) + + project.plugins.withId(project.getPluginIdByName("kotlinJvm")) { + val kotlinProject = project.extensions.getByName("kotlin") as KotlinJvmProjectExtension + kotlinProject.explicitApi() + kotlinProject.jvmToolchain { + languageVersion.set(JavaLanguageVersion.of(project.getVersionByName("jdk"))) + } + kotlinProject.compilerOptions.apply { + languageVersion.set(KotlinVersion.fromVersion(project.getVersionByName("kotlinTarget"))) + apiVersion.set(KotlinVersion.fromVersion(project.getVersionByName("kotlinTarget"))) + jvmTarget.set(JvmTarget.fromTarget(project.getVersionByName("jvmTarget"))) + } + } + } +} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/dagger/gradle/build/PublishConventionPlugin.kt b/buildSrc/src/main/kotlin/dagger/gradle/build/PublishConventionPlugin.kt new file mode 100644 index 0000000..360ff71 --- /dev/null +++ b/buildSrc/src/main/kotlin/dagger/gradle/build/PublishConventionPlugin.kt
@@ -0,0 +1,73 @@ +/* + * Copyright (C) 2025 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.gradle.build + +import com.vanniktech.maven.publish.MavenPublishBaseExtension +import com.vanniktech.maven.publish.SonatypeHost +import org.gradle.api.Plugin +import org.gradle.api.Project + +class PublishConventionPlugin : Plugin<Project> { + override fun apply(project: Project) { + project.pluginManager.apply(project.getPluginIdByName("publish")) + + project.plugins.withId(project.getPluginIdByName("publish")) { + val publishExtension = project.extensions.getByName("mavenPublishing") as MavenPublishBaseExtension + publishExtension.apply { + coordinates( + groupId = "com.google.dagger", + artifactId = project.name, + version = project.findProperty("PUBLISH_VERSION").toString() + ) + publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + pom { + name.set(project.name.asPomName()) + description.set("A fast dependency injector for Android and Java.") + url.set("https://github.com/google/dagger") + scm { + url.set("https://github.com/google/dagger/") + connection.set("scm:git:git://github.com/google/dagger.git") + } + issueManagement { + system.set("GitHub Issues") + url.set("https://github.com/google/dagger/issues") + } + licenses { + license { + name.set("The Apache Software License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + organization { + name.set("Google, Inc.") + url.set("https://www.google.com") + } + } + } + } + } + + /** + * Converts the Gradle project name to a more appropriate name for the POM file. + * + * For example: 'dagger-compiler' to 'Dagger Compiler' + */ + private fun String.asPomName(): String { + val parts = split("-").map { first().uppercaseChar() + drop(1) } + return parts.joinToString(separator = " ") + } +} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/dagger/gradle/build/ResourceCopyTask.kt b/buildSrc/src/main/kotlin/dagger/gradle/build/ResourceCopyTask.kt new file mode 100644 index 0000000..06bb8e8 --- /dev/null +++ b/buildSrc/src/main/kotlin/dagger/gradle/build/ResourceCopyTask.kt
@@ -0,0 +1,69 @@ +/* + * Copyright (C) 2025 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.gradle.build + +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.MapProperty +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault + +/** + * A task for copying JAR resources files located in the repository structure into a generated resource source set + * that matches the JAR's resources structure. This is necessary due to the repository's structure not being the + * standard Gradle source set structure. + */ +@DisableCachingByDefault(because = "Not worth caching") +abstract class ResourceCopyTask : DefaultTask() { + + /** + * Specifications of resource files to copy and their destination directory within the JAR. + */ + @get:Input + abstract val resourceSpecs: MapProperty<String, String> + + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val inputFiles: ListProperty<RegularFile> + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun execute() { + val specMap = resourceSpecs.get() + inputFiles.get().forEach { resourceFile -> + val inputFile = resourceFile.asFile + check(inputFile.exists()) { + "Resource file does not exist: $inputFile" + } + check(inputFile.isFile) { + "Resource file must be a file not a directory: $inputFile" + } + val jarOutputDir = specMap.getValue(inputFile.path) + val outputFile = outputDirectory.get().dir(jarOutputDir).file(inputFile.name).asFile + inputFile.copyTo(outputFile, overwrite = true) + } + } +} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/dagger/gradle/build/SourceSetConfiguration.kt b/buildSrc/src/main/kotlin/dagger/gradle/build/SourceSetConfiguration.kt new file mode 100644 index 0000000..06975cc --- /dev/null +++ b/buildSrc/src/main/kotlin/dagger/gradle/build/SourceSetConfiguration.kt
@@ -0,0 +1,189 @@ +/* + * 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.gradle.build + +import org.gradle.api.NamedDomainObjectContainer +import org.gradle.api.Project +import org.gradle.api.file.SourceDirectorySet +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.tasks.TaskProvider +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import java.nio.file.Path +import kotlin.io.path.Path +import kotlin.io.path.isDirectory + +private typealias JavaSourceSet = org.gradle.api.tasks.SourceSet + +@DslMarker +annotation class DaggerGradleDsl + +@DaggerGradleDsl +class DaggerSourceSet( + private val project: Project, + private val kotlinSourceSets: NamedDomainObjectContainer<KotlinSourceSet>, + private val javaSourceSets: NamedDomainObjectContainer<JavaSourceSet>, +) { + private val resourceCopyTask: TaskProvider<ResourceCopyTask> = + project.tasks.register("copyResources", ResourceCopyTask::class.java) { + outputDirectory.set(project.layout.buildDirectory.dir("generated/resources")) + } + + init { + listOf(resourceCopyTask.map { it.outputDirectory }).let { + kotlinSourceSets.named("main").configure { resources.setSrcDirs(it) } + javaSourceSets.named("main").configure { resources.setSrcDirs(it) } + } + } + + /** + * The main source set whose based path is `<root>/java` + */ + val main: SourceSet = object : SourceSet { + override fun setPackages(packages: List<String>) { + val packagePaths = packages.map { Path(it) } + kotlinSourceSets.named("main").configure { + kotlin.includePackages("${project.rootDir}/java", packagePaths) + } + javaSourceSets.named("main").configure { + java.includePackages("${project.rootDir}/java", packagePaths) + } + } + + override fun setResources(resources: Map<String, String>) { + resourceCopyTask.configure { + val baseDir = project.rootProject.layout.projectDirectory.dir("java") + resources.forEach { (resourceFilePath, jarDirectoryPath) -> + val resource = baseDir.file(resourceFilePath) + resourceSpecs.put(resource.asFile.path, jarDirectoryPath) + inputFiles.add(resource) + } + } + } + } + + /** + * The main source set whose based path is `<root>/javatests` + */ + val test: SourceSet = object : SourceSet { + override fun setPackages(packages: List<String>) { + val packagePaths = packages.map { Path(it) } + kotlinSourceSets.named("test").configure { + kotlin.includePackages("${project.rootDir}/javatests", packagePaths) + } + javaSourceSets.named("test").configure { + java.includePackages("${project.rootDir}/javatests", packagePaths) + } + } + + override fun setResources(resources: Map<String, String>) { + throw UnsupportedOperationException( + "Resources are only configurable for the 'main' source set." + ) + } + } + + interface SourceSet { + /** + * Sets the list of source packages that are part of the project's source set. + * + * Only sources directly in those packages are included and not in its subpackages. + * + * Example usage: + * ``` + * daggerSources { + * main.setPackages( + * listOf( + * "dagger", + * "dagger/assisted", + * "dagger/internal", + * "dagger/multibindings", + * ) + * ) + * } + * ``` + * @see daggerSources + */ + fun setPackages(packages: List<String>) + + /** + * Sets the resource file paths and their corresponding artifact location. + * + * Example usage: + * ``` + * daggerSources { + * main.setResources( + * mapOf("dagger/r8.pro" to "META-INF/com.android.tools/r8/") + * ) + * } + * ``` + * @see daggerSources + */ + fun setResources(resources: Map<String, String>) + } +} + +/** + * Configure project's source set based on Dagger's project structure. + * + * Specifically it will include sources in the packages specified by + * [DaggerSourceSet.SourceSet.setPackages] and resources as specified by + * [DaggerSourceSet.SourceSet.setResources]. + */ +fun Project.daggerSources(block: DaggerSourceSet.() -> Unit) { + val kotlinExtension = extensions.findByType(KotlinProjectExtension::class.java) + ?: error("The daggerSources() configuration must be applied to a Kotlin (JVM) project.") + val javaExtension = extensions.findByType(JavaPluginExtension::class.java) + ?: error("The daggerSources() configuration must be applied to a Kotlin (JVM) project.") + val daggerSources = DaggerSourceSet(this, kotlinExtension.sourceSets, javaExtension.sourceSets) + block.invoke(daggerSources) +} + +/** + * Includes sources from the given [packages] into this source set. + * + * Only sources within the package directory are included and not its sub-packages. + */ +private fun SourceDirectorySet.includePackages( + basePath: String, + packages: Iterable<Path>, +) { + val packagesDirectories = packages.flatMap { it.expandParts() }.toSet() + setSrcDirs(listOf(basePath)).include { + val path = Path(it.path) + if (Path(basePath).resolve(path).isDirectory()) { + path in packagesDirectories + } else { + path.parent in packages + } + } +} + +/** + * Expands a [Path] to includes it parents. + * + * i.e. for `"foo/bar"` it will expand to `setOf("foo", foo/bar")` + */ +private fun Path.expandParts(): Set<Path> { + return buildSet { + var path: Path? = this@expandParts + while (path != null) { + add(path) + path = path.parent + } + } +} \ No newline at end of file
diff --git a/buildSrc/src/main/kotlin/dagger/gradle/build/VersionCatalogs.kt b/buildSrc/src/main/kotlin/dagger/gradle/build/VersionCatalogs.kt new file mode 100644 index 0000000..c9f034b --- /dev/null +++ b/buildSrc/src/main/kotlin/dagger/gradle/build/VersionCatalogs.kt
@@ -0,0 +1,42 @@ +/* + * Copyright (C) 2025 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.gradle.build + +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalog +import org.gradle.api.artifacts.VersionCatalogsExtension + +internal val Project.versionCatalog: VersionCatalog + get() = project.extensions.getByType(VersionCatalogsExtension::class.java).find("libs").get() + +internal fun Project.getVersionByName(name: String): String { + val version = versionCatalog.findVersion(name) + return if (version.isPresent) { + version.get().requiredVersion + } else { + error("Could not find a version for `$name`") + } +} + +internal fun Project.getPluginIdByName(name: String): String { + val plugin = versionCatalog.findPlugin(name) + return if (plugin.isPresent) { + plugin.get().map { it.pluginId }.get() + } else { + error("Could not find plugin id for `$name`") + } +} \ No newline at end of file
diff --git a/build_defs.bzl b/build_defs.bzl index 70afaf0..3dd0647 100644 --- a/build_defs.bzl +++ b/build_defs.bzl
@@ -18,8 +18,6 @@ DOCLINT_REFERENCES = ["-Xdoclint:reference"] -JAVA_RELEASE_MIN = [ - "-source 7 -target 7", -] +JAVA_RELEASE_MIN = ["-source 8 -target 8"] POM_VERSION = "${project.version}"
diff --git a/examples/bazel/.bazelversion b/examples/bazel/.bazelversion new file mode 100644 index 0000000..c0be8a7 --- /dev/null +++ b/examples/bazel/.bazelversion
@@ -0,0 +1 @@ +6.4.0 \ No newline at end of file
diff --git a/examples/bazel/WORKSPACE b/examples/bazel/WORKSPACE index 3ad378c..7c9a8db 100644 --- a/examples/bazel/WORKSPACE +++ b/examples/bazel/WORKSPACE
@@ -41,8 +41,8 @@ android_sdk_repository( name = "androidsdk", - api_level = 32, - build_tools_version = "32.0.0", + api_level = 34, + build_tools_version = "34.0.0", ) ############################# @@ -51,10 +51,13 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +ROBOLECTRIC_VERSION = "4.11.1" + http_archive( name = "robolectric", - strip_prefix = "robolectric-bazel-4.1", - urls = ["https://github.com/robolectric/robolectric-bazel/archive/4.1.tar.gz"], + sha256 = "1ea1cfe67848decf959316e80dd69af2bbaa359ae2195efe1366cbdf3e968356", + strip_prefix = "robolectric-bazel-%s" % ROBOLECTRIC_VERSION, + urls = ["https://github.com/robolectric/robolectric-bazel/releases/download/%s/robolectric-bazel-%s.tar.gz" % (ROBOLECTRIC_VERSION, ROBOLECTRIC_VERSION)], ) load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories") @@ -84,8 +87,8 @@ "androidx.test:runner:1.1.1", "com.google.truth:truth:1.0.1", "junit:junit:4.13", - "org.robolectric:robolectric:4.1", - "org.robolectric:annotations:4.1", + "org.robolectric:robolectric:%s" % ROBOLECTRIC_VERSION, + "org.robolectric:annotations:%s" % ROBOLECTRIC_VERSION, ], repositories = DAGGER_REPOSITORIES + HILT_ANDROID_REPOSITORIES, )
diff --git a/gradle-projects/README.md b/gradle-projects/README.md new file mode 100644 index 0000000..2024ba6 --- /dev/null +++ b/gradle-projects/README.md
@@ -0,0 +1,6 @@ +### Dagger's Gradle projects directories + +Each directory is a Gradle sub-project that maps to an artifact and whose sources are part of the +Bazel project structure. At the root of the repository is the parent project that includes the +ones in these directory. +
diff --git a/gradle-projects/dagger-runtime/api/dagger.api b/gradle-projects/dagger-runtime/api/dagger.api new file mode 100644 index 0000000..36ed2a3 --- /dev/null +++ b/gradle-projects/dagger-runtime/api/dagger.api
@@ -0,0 +1,282 @@ +public abstract interface annotation class dagger/Binds : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/BindsInstance : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/BindsOptionalOf : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/Component : java/lang/annotation/Annotation { + public abstract fun dependencies ()[Ljava/lang/Class; + public abstract fun modules ()[Ljava/lang/Class; +} + +public abstract interface annotation class dagger/Component$Builder : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/Component$Factory : java/lang/annotation/Annotation { +} + +public abstract interface class dagger/Lazy { + public abstract fun get ()Ljava/lang/Object; +} + +public abstract interface annotation class dagger/MapKey : java/lang/annotation/Annotation { + public abstract fun unwrapValue ()Z +} + +public abstract interface class dagger/MembersInjector { + public abstract fun injectMembers (Ljava/lang/Object;)V +} + +public abstract interface annotation class dagger/Module : java/lang/annotation/Annotation { + public abstract fun includes ()[Ljava/lang/Class; + public abstract fun subcomponents ()[Ljava/lang/Class; +} + +public abstract interface annotation class dagger/Provides : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/Reusable : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/Subcomponent : java/lang/annotation/Annotation { + public abstract fun modules ()[Ljava/lang/Class; +} + +public abstract interface annotation class dagger/Subcomponent$Builder : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/Subcomponent$Factory : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/assisted/Assisted : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/String; +} + +public abstract interface annotation class dagger/assisted/AssistedFactory : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/assisted/AssistedInject : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/internal/Beta : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/internal/ComponentDefinitionType : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/Class; +} + +public final class dagger/internal/DaggerCollections { + public static fun hasDuplicates (Ljava/util/List;)Z + public static fun newLinkedHashMapWithExpectedSize (I)Ljava/util/LinkedHashMap; + public static fun presizedList (I)Ljava/util/List; +} + +public abstract interface annotation class dagger/internal/DaggerGenerated : java/lang/annotation/Annotation { +} + +public final class dagger/internal/DelegateFactory : dagger/internal/Factory { + public fun <init> ()V + public fun get ()Ljava/lang/Object; + public static fun setDelegate (Ldagger/internal/Provider;Ldagger/internal/Provider;)V + public static fun setDelegate (Ljavax/inject/Provider;Ljavax/inject/Provider;)V + public fun setDelegatedProvider (Ldagger/internal/Provider;)V + public fun setDelegatedProvider (Ljavax/inject/Provider;)V +} + +public final class dagger/internal/DoubleCheck : dagger/Lazy, dagger/internal/Provider { + public fun get ()Ljava/lang/Object; + public static fun lazy (Ldagger/internal/Provider;)Ldagger/Lazy; + public static fun lazy (Ljavax/inject/Provider;)Ldagger/Lazy; + public static fun provider (Ldagger/internal/Provider;)Ldagger/internal/Provider; + public static fun provider (Ljavax/inject/Provider;)Ljavax/inject/Provider; +} + +public abstract interface class dagger/internal/Factory : dagger/internal/Provider { +} + +public abstract interface annotation class dagger/internal/GwtIncompatible : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/internal/IdentifierNameString : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/internal/InjectedFieldSignature : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/String; +} + +public final class dagger/internal/InstanceFactory : dagger/Lazy, dagger/internal/Factory { + public static fun create (Ljava/lang/Object;)Ldagger/internal/Factory; + public static fun createNullable (Ljava/lang/Object;)Ldagger/internal/Factory; + public fun get ()Ljava/lang/Object; +} + +public abstract interface annotation class dagger/internal/KeepFieldType : java/lang/annotation/Annotation { +} + +public final class dagger/internal/LazyClassKeyMap : java/util/Map { + public fun clear ()V + public fun containsKey (Ljava/lang/Object;)Z + public fun containsValue (Ljava/lang/Object;)Z + public fun entrySet ()Ljava/util/Set; + public fun get (Ljava/lang/Object;)Ljava/lang/Object; + public fun isEmpty ()Z + public fun keySet ()Ljava/util/Set; + public static fun of (Ljava/util/Map;)Ljava/util/Map; + public fun put (Ljava/lang/Class;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun putAll (Ljava/util/Map;)V + public fun remove (Ljava/lang/Object;)Ljava/lang/Object; + public fun size ()I + public fun values ()Ljava/util/Collection; +} + +public class dagger/internal/LazyClassKeyMap$MapFactory : dagger/internal/Factory { + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Map; + public static fun of (Ldagger/internal/Factory;)Ldagger/internal/LazyClassKeyMap$MapFactory; +} + +public class dagger/internal/LazyClassKeyMap$MapProviderFactory : dagger/internal/Factory { + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Map; + public static fun of (Ldagger/internal/Factory;)Ldagger/internal/LazyClassKeyMap$MapProviderFactory; +} + +public final class dagger/internal/MapBuilder { + public fun build ()Ljava/util/Map; + public static fun newMapBuilder (I)Ldagger/internal/MapBuilder; + public fun put (Ljava/lang/Object;Ljava/lang/Object;)Ldagger/internal/MapBuilder; + public fun putAll (Ljava/util/Map;)Ldagger/internal/MapBuilder; +} + +public final class dagger/internal/MapFactory { + public static fun builder (I)Ldagger/internal/MapFactory$Builder; + public static fun emptyMapProvider ()Ldagger/internal/Provider; + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Map; +} + +public final class dagger/internal/MapFactory$Builder { + public fun build ()Ldagger/internal/MapFactory; + public synthetic fun put (Ljava/lang/Object;Ldagger/internal/Provider;)Ldagger/internal/AbstractMapFactory$Builder; + public fun put (Ljava/lang/Object;Ldagger/internal/Provider;)Ldagger/internal/MapFactory$Builder; + public fun put (Ljava/lang/Object;Ljavax/inject/Provider;)Ldagger/internal/MapFactory$Builder; + public synthetic fun putAll (Ldagger/internal/Provider;)Ldagger/internal/AbstractMapFactory$Builder; + public fun putAll (Ldagger/internal/Provider;)Ldagger/internal/MapFactory$Builder; + public fun putAll (Ljavax/inject/Provider;)Ldagger/internal/MapFactory$Builder; +} + +public final class dagger/internal/MapProviderFactory : dagger/Lazy { + public static fun builder (I)Ldagger/internal/MapProviderFactory$Builder; + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Map; +} + +public final class dagger/internal/MapProviderFactory$Builder { + public fun build ()Ldagger/internal/MapProviderFactory; + public synthetic fun put (Ljava/lang/Object;Ldagger/internal/Provider;)Ldagger/internal/AbstractMapFactory$Builder; + public fun put (Ljava/lang/Object;Ldagger/internal/Provider;)Ldagger/internal/MapProviderFactory$Builder; + public fun put (Ljava/lang/Object;Ljavax/inject/Provider;)Ldagger/internal/MapProviderFactory$Builder; + public synthetic fun putAll (Ldagger/internal/Provider;)Ldagger/internal/AbstractMapFactory$Builder; + public fun putAll (Ldagger/internal/Provider;)Ldagger/internal/MapProviderFactory$Builder; + public fun putAll (Ljavax/inject/Provider;)Ldagger/internal/MapProviderFactory$Builder; +} + +public final class dagger/internal/MembersInjectors { + public static fun noOp ()Ldagger/MembersInjector; +} + +public final class dagger/internal/Preconditions { + public static fun checkBuilderRequirement (Ljava/lang/Object;Ljava/lang/Class;)V + public static fun checkNotNull (Ljava/lang/Object;)Ljava/lang/Object; + public static fun checkNotNull (Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object; + public static fun checkNotNull (Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; + public static fun checkNotNullFromComponent (Ljava/lang/Object;)Ljava/lang/Object; + public static fun checkNotNullFromProvides (Ljava/lang/Object;)Ljava/lang/Object; +} + +public abstract interface class dagger/internal/Provider : jakarta/inject/Provider, javax/inject/Provider { +} + +public final class dagger/internal/ProviderOfLazy : dagger/internal/Provider { + public static fun create (Ldagger/internal/Provider;)Ldagger/internal/Provider; + public static fun create (Ljavax/inject/Provider;)Ldagger/internal/Provider; + public fun get ()Ldagger/Lazy; + public synthetic fun get ()Ljava/lang/Object; +} + +public final class dagger/internal/Providers { + public static fun asDaggerProvider (Ljavax/inject/Provider;)Ldagger/internal/Provider; +} + +public abstract interface annotation class dagger/internal/QualifierMetadata : java/lang/annotation/Annotation { + public abstract fun value ()[Ljava/lang/String; +} + +public abstract interface annotation class dagger/internal/ScopeMetadata : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/String; +} + +public final class dagger/internal/SetBuilder { + public fun add (Ljava/lang/Object;)Ldagger/internal/SetBuilder; + public fun addAll (Ljava/util/Collection;)Ldagger/internal/SetBuilder; + public fun build ()Ljava/util/Set; + public static fun newSetBuilder (I)Ldagger/internal/SetBuilder; +} + +public final class dagger/internal/SetFactory : dagger/internal/Factory { + public static fun builder (II)Ldagger/internal/SetFactory$Builder; + public static fun empty ()Ldagger/internal/Factory; + public synthetic fun get ()Ljava/lang/Object; + public fun get ()Ljava/util/Set; +} + +public final class dagger/internal/SetFactory$Builder { + public fun addCollectionProvider (Ldagger/internal/Provider;)Ldagger/internal/SetFactory$Builder; + public fun addCollectionProvider (Ljavax/inject/Provider;)Ldagger/internal/SetFactory$Builder; + public fun addProvider (Ldagger/internal/Provider;)Ldagger/internal/SetFactory$Builder; + public fun addProvider (Ljavax/inject/Provider;)Ldagger/internal/SetFactory$Builder; + public fun build ()Ldagger/internal/SetFactory; +} + +public final class dagger/internal/SingleCheck : dagger/internal/Provider { + public fun get ()Ljava/lang/Object; + public static fun provider (Ldagger/internal/Provider;)Ldagger/internal/Provider; + public static fun provider (Ljavax/inject/Provider;)Ljavax/inject/Provider; +} + +public abstract interface annotation class dagger/multibindings/ClassKey : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/Class; +} + +public abstract interface annotation class dagger/multibindings/ElementsIntoSet : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/multibindings/IntKey : java/lang/annotation/Annotation { + public abstract fun value ()I +} + +public abstract interface annotation class dagger/multibindings/IntoMap : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/multibindings/IntoSet : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/multibindings/LazyClassKey : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/Class; +} + +public abstract interface annotation class dagger/multibindings/LongKey : java/lang/annotation/Annotation { + public abstract fun value ()J +} + +public abstract interface annotation class dagger/multibindings/Multibinds : java/lang/annotation/Annotation { +} + +public abstract interface annotation class dagger/multibindings/StringKey : java/lang/annotation/Annotation { + public abstract fun value ()Ljava/lang/String; +} +
diff --git a/gradle-projects/dagger-runtime/build.gradle.kts b/gradle-projects/dagger-runtime/build.gradle.kts new file mode 100644 index 0000000..fa1bf61 --- /dev/null +++ b/gradle-projects/dagger-runtime/build.gradle.kts
@@ -0,0 +1,40 @@ +import dagger.gradle.build.daggerSources + +plugins { + alias(libs.plugins.dagger.kotlinJvm) + alias(libs.plugins.dagger.publish) + alias(libs.plugins.binaryCompatibilityValidator) +} + +daggerSources { + main.setPackages( + listOf( + "dagger", + "dagger/assisted", + "dagger/internal", + "dagger/multibindings", + ) + ) + main.setResources( + mapOf( + "dagger/proguard.pro" to "META-INF/com.android.tools/proguard", + "dagger/r8.pro" to "META-INF/com.android.tools/r8" + ) + ) + test.setPackages( + listOf( + "dagger", + "dagger/internal", + ) + ) +} + +dependencies { + api(libs.javax.inject) + api(libs.jakarta.inject) + api(libs.jspecify) + + testImplementation(libs.junit) + testImplementation(libs.truth) + testImplementation(libs.guava.jre) +} \ No newline at end of file
diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..9b5bb06 --- /dev/null +++ b/gradle.properties
@@ -0,0 +1,25 @@ +# Project-wide Gradle settings. +# IDE (e.g. IntelliJ or Android Studio) users: +# Gradle settings configured through the IDE *will override* any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx4g -Xms4g -Dfile.encoding=UTF-8 +kotlin.daemon.jvmargs=-Xmx4g -Xms4g -Dfile.encoding=UTF-8 + +# Enable caching between builds. +org.gradle.caching=true + +# Enable configuration caching between builds. +org.gradle.configuration-cache=true + +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official + +# Don't include the stdlib as a dependency by default +kotlin.stdlib.default.dependency=false + +# Publish version +# TODO(danysantiago): Find a configurable location for the publishing version. +PUBLISH_VERSION=LOCAL-SNAPSHOT \ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..57cd6a0 --- /dev/null +++ b/gradle/libs.versions.toml
@@ -0,0 +1,27 @@ +[versions] +guava = "33.0.0-jre" +jdk = "18" +junit = "4.13" +jvmTarget = "1.8" +kotlin = "2.0.21" +kotlinTarget = "1.9" +publish = "0.30.0" +truth = "1.4.0" + +[libraries] +guava-jre = { module = "com.google.guava:guava", version.ref = "guava" } +jakarta-inject = { module = "jakarta.inject:jakarta.inject-api", version = "2.0.1" } +javax-inject = { module = "javax.inject:javax.inject", version = "1" } +jspecify = { module = "org.jspecify:jspecify", version = "1.0.0" } +junit = { module = "junit:junit", version.ref = "junit" } +kotlin-gradlePlugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } +publishPlugin = { module = "com.vanniktech:gradle-maven-publish-plugin", version.ref = "publish" } +truth = { module = "com.google.truth:truth", version.ref = "truth" } + +[plugins] +binaryCompatibilityValidator = { id = "org.jetbrains.kotlinx.binary-compatibility-validator", version = "0.17.0" } +dagger-kotlinJvm = { id = "dagger.gradle.build.jvm" } +dagger-publish = { id = "dagger.gradle.build.publish" } +kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +publish = { id = "com.vanniktech.maven.publish", version.ref = "publish" } \ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..a4b76b9 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.jar Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..94113f2 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..f5feea6 --- /dev/null +++ b/gradlew
@@ -0,0 +1,252 @@ +#!/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. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# 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/platforms/jvm/plugins-application/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 -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || 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/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9d21a21 --- /dev/null +++ b/gradlew.bat
@@ -0,0 +1,94 @@ +@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 +@rem SPDX-License-Identifier: Apache-2.0 +@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. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +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/gwt/BUILD b/gwt/BUILD index 5aa9110..59cd4a5 100644 --- a/gwt/BUILD +++ b/gwt/BUILD
@@ -16,13 +16,14 @@ # GWT-specific files for Dagger load("@rules_java//java:defs.bzl", "java_library") -load("//tools:maven.bzl", "pom_file") -load("//:build_defs.bzl", "POM_VERSION") +load("//:build_defs.bzl", "JAVA_RELEASE_MIN", "POM_VERSION") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) java_library( name = "gwt", + javacopts = JAVA_RELEASE_MIN, resource_strip_prefix = "gwt/", resources = glob(["**/*.gwt.xml"]), tags = ["maven_coordinates=com.google.dagger:dagger-gwt:" + POM_VERSION], @@ -36,12 +37,14 @@ name = "manual_deps", tags = [ "maven_coordinates=com.google.dagger:dagger:%s:jar:sources" % POM_VERSION, + "maven_coordinates=jakarta.inject:jakarta.inject-api:2.0.1:jar:sources", "maven_coordinates=javax.inject:javax.inject:1:jar:sources", + "maven_coordinates=org.jspecify:jspecify:1.0.0:jar:sources", ], visibility = ["//visibility:private"], ) -pom_file( +dagger_pom_file( name = "pom", artifact_id = "dagger-gwt", artifact_name = "Dagger GWT",
diff --git a/gwt/dagger/Dagger.gwt.xml b/gwt/dagger/Dagger.gwt.xml index ad106fd..4298a32 100644 --- a/gwt/dagger/Dagger.gwt.xml +++ b/gwt/dagger/Dagger.gwt.xml
@@ -15,6 +15,7 @@ --> <module> <inherits name="javax.inject.Inject" /> - + <inherits name="jakarta.inject.Inject" /> + <inherits name="org.jspecify.Jspecify" /> <source path=""/> </module>
diff --git a/gwt/jakarta/inject/Inject.gwt.xml b/gwt/jakarta/inject/Inject.gwt.xml new file mode 100644 index 0000000..cf56dfb --- /dev/null +++ b/gwt/jakarta/inject/Inject.gwt.xml
@@ -0,0 +1,18 @@ +<!-- + 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. +--> +<module> + <source path=""/> +</module> \ No newline at end of file
diff --git a/gwt/org/jspecify/Jspecify.gwt.xml b/gwt/org/jspecify/Jspecify.gwt.xml new file mode 100644 index 0000000..cf56dfb --- /dev/null +++ b/gwt/org/jspecify/Jspecify.gwt.xml
@@ -0,0 +1,18 @@ +<!-- + 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. +--> +<module> + <source path=""/> +</module> \ No newline at end of file
diff --git a/java/dagger/BUILD b/java/dagger/BUILD index 9183408..dc67ced 100644 --- a/java/dagger/BUILD +++ b/java/dagger/BUILD
@@ -22,7 +22,7 @@ "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -33,7 +33,9 @@ tags = ["maven_coordinates=com.google.dagger:dagger:" + POM_VERSION], exports = ["//third_party/java/jsr330_inject"], deps = [ + "//third_party/java/jspecify_annotations", "//third_party/java/jsr330_inject", + "@maven//:jakarta_inject_jakarta_inject_api", ], ) @@ -43,6 +45,8 @@ artifact_name = "Dagger", artifact_target = ":core", artifact_target_maven_deps = [ + "org.jspecify:jspecify", + "jakarta.inject:jakarta.inject-api", "javax.inject:javax.inject", ], javadoc_root_packages = ["dagger"],
diff --git a/java/dagger/android/BUILD b/java/dagger/android/BUILD index 686e6ae..fe2183b 100644 --- a/java/dagger/android/BUILD +++ b/java/dagger/android/BUILD
@@ -17,13 +17,15 @@ load( "//:build_defs.bzl", + "DOCLINT_HTML_AND_SYNTAX", + "JAVA_RELEASE_MIN", "POM_VERSION", ) load("//tools:dejetify.bzl", "dejetified_library") load( - "//tools:maven.bzl", + "//tools/maven:maven.bzl", + "dagger_pom_file", "gen_maven_artifact", - "pom_file", ) package(default_visibility = ["//:src"]) @@ -43,6 +45,7 @@ android_library( name = "android", srcs = SRCS, + javacopts = JAVA_RELEASE_MIN + DOCLINT_HTML_AND_SYNTAX, plugins = [ "//java/dagger/android/internal/proguard:plugin", ], @@ -68,7 +71,7 @@ "com.google.dagger:dagger", "com.google.dagger:dagger-lint-aar", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_root_packages = [ "dagger.android", ], @@ -94,7 +97,7 @@ ], ) -pom_file( +dagger_pom_file( name = "legacy-pom", artifact_id = "dagger-android-legacy", artifact_name = "Dagger Android Legacy",
diff --git a/java/dagger/android/processor/BUILD b/java/dagger/android/processor/BUILD index f70c091..16b662e 100644 --- a/java/dagger/android/processor/BUILD +++ b/java/dagger/android/processor/BUILD
@@ -22,7 +22,7 @@ "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"])
diff --git a/java/dagger/android/support/BUILD b/java/dagger/android/support/BUILD index 2f4c407..aa01899 100644 --- a/java/dagger/android/support/BUILD +++ b/java/dagger/android/support/BUILD
@@ -17,13 +17,15 @@ load( "//:build_defs.bzl", + "DOCLINT_HTML_AND_SYNTAX", + "JAVA_RELEASE_MIN", "POM_VERSION", ) load("//tools:dejetify.bzl", "dejetified_library") load( - "//tools:maven.bzl", + "//tools/maven:maven.bzl", + "dagger_pom_file", "gen_maven_artifact", - "pom_file", ) package(default_visibility = ["//:src"]) @@ -36,6 +38,7 @@ android_library( name = "support", srcs = glob(["*.java"]), + javacopts = JAVA_RELEASE_MIN + DOCLINT_HTML_AND_SYNTAX, tags = ["maven_coordinates=com.google.dagger:dagger-android-support:" + POM_VERSION], deps = [ "//:dagger_with_compiler", @@ -67,7 +70,7 @@ "com.google.dagger:dagger", "com.google.dagger:dagger-android", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_root_packages = [ "dagger.android.support", ], @@ -95,7 +98,7 @@ ], ) -pom_file( +dagger_pom_file( name = "legacy-pom", artifact_id = "dagger-android-support-legacy", artifact_name = "Dagger Android Legacy Support",
diff --git a/java/dagger/grpc/server/BUILD b/java/dagger/grpc/server/BUILD index 8aa82be..49d23b0 100644 --- a/java/dagger/grpc/server/BUILD +++ b/java/dagger/grpc/server/BUILD
@@ -5,10 +5,11 @@ "//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES", + "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) @@ -21,7 +22,7 @@ java_library( name = "annotations", srcs = ANNOTATIONS_SRCS, - javacopts = DOCLINT_HTML_AND_SYNTAX, + javacopts = DOCLINT_HTML_AND_SYNTAX + JAVA_RELEASE_MIN, tags = ["maven_coordinates=com.google.dagger:dagger-grpc-server-annotations:" + POM_VERSION], deps = [ "//third_party/java/jsr330_inject", @@ -36,7 +37,7 @@ exclude = ANNOTATIONS_SRCS, ), exported_plugins = ["//java/dagger/grpc/server/processor:plugin"], - javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES + JAVA_RELEASE_MIN, tags = ["maven_coordinates=com.google.dagger:dagger-grpc-server:" + POM_VERSION], exports = [":annotations"], deps = [ @@ -53,14 +54,14 @@ ], ) -pom_file( +dagger_pom_file( name = "annotations-pom", artifact_id = "dagger-grpc-server-annotations", artifact_name = "Dagger gRPC Server Annotations", targets = [":annotations"], ) -pom_file( +dagger_pom_file( name = "server-pom", artifact_id = "dagger-grpc-server", artifact_name = "Dagger gRPC Server",
diff --git a/java/dagger/grpc/server/processor/BUILD b/java/dagger/grpc/server/processor/BUILD index ed28836..79a2cfb 100644 --- a/java/dagger/grpc/server/processor/BUILD +++ b/java/dagger/grpc/server/processor/BUILD
@@ -4,8 +4,8 @@ "DOCLINT_HTML_AND_SYNTAX", "POM_VERSION", ) -load("//tools:maven.bzl", "pom_file") -load("@google_bazel_common//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") +load("//tools/maven:maven.bzl", "dagger_pom_file") package(default_visibility = ["//:src"]) @@ -28,7 +28,7 @@ ], ) -pom_file( +dagger_pom_file( name = "pom", artifact_id = "dagger-grpc-server-processor", artifact_name = "Dagger gRPC Server Processor",
diff --git a/java/dagger/hilt/BUILD b/java/dagger/hilt/BUILD index 8d25adc..5a2af5b 100644 --- a/java/dagger/hilt/BUILD +++ b/java/dagger/hilt/BUILD
@@ -12,8 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("//tools:maven.bzl", "gen_maven_artifact") +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "POM_VERSION") +load("//tools/maven:maven.bzl", "gen_maven_artifact") # Description: # A library that wraps the Dagger API to make DI usage and testing easier. @@ -186,12 +187,12 @@ name = "artifact-core-lib", tags = ["maven_coordinates=com.google.dagger:hilt-core:" + POM_VERSION], exports = [ - ":define_component", - ":entry_point", - ":generates_root_input", - ":install_in", ":package_info", "//java/dagger:core", + "//java/dagger/hilt:define_component", + "//java/dagger/hilt:entry_point", + "//java/dagger/hilt:generates_root_input", + "//java/dagger/hilt:install_in", "//java/dagger/hilt/components", "//java/dagger/hilt/migration:alias_of", "//java/dagger/hilt/migration:disable_install_in_check",
diff --git a/java/dagger/hilt/android/BUILD b/java/dagger/hilt/android/BUILD index b30f662..d543c3e 100644 --- a/java/dagger/hilt/android/BUILD +++ b/java/dagger/hilt/android/BUILD
@@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@rules_java//java:defs.bzl", "java_library") + # Description: # A library based on Hilt that provides standard components and automated injection for Android. load("//:build_defs.bzl", "POM_VERSION") load("//tools:bazel_compat.bzl", "compat_kt_android_library") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -68,9 +70,9 @@ "//java/dagger/hilt/processor/internal/root:root_plugin", ], exports = [ - ":activity_retained_lifecycle", "//:dagger_with_compiler", "//java/dagger/hilt:install_in", + "//java/dagger/hilt/android:activity_retained_lifecycle", "//java/dagger/hilt/android/components", "//java/dagger/hilt/android/internal/builders", "//java/dagger/hilt/android/internal/legacy:aggregated_element_proxy", @@ -247,7 +249,7 @@ "com.google.guava:guava", "javax.annotation:javax.annotation-api", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_exclude_packages = [ "dagger.hilt.android.internal", ],
diff --git a/java/dagger/hilt/android/components/BUILD b/java/dagger/hilt/android/components/BUILD index 655ccd1..5e52c7f 100644 --- a/java/dagger/hilt/android/components/BUILD +++ b/java/dagger/hilt/android/components/BUILD
@@ -15,6 +15,8 @@ # Description: # Hilt Android components +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) android_library(
diff --git a/java/dagger/hilt/android/internal/builders/FragmentComponentBuilder.java b/java/dagger/hilt/android/internal/builders/FragmentComponentBuilder.java index 11cc89f..4f95c07 100644 --- a/java/dagger/hilt/android/internal/builders/FragmentComponentBuilder.java +++ b/java/dagger/hilt/android/internal/builders/FragmentComponentBuilder.java
@@ -25,5 +25,6 @@ @DefineComponent.Builder public interface FragmentComponentBuilder { FragmentComponentBuilder fragment(@BindsInstance Fragment fragment); + FragmentComponent build(); }
diff --git a/java/dagger/hilt/android/internal/earlyentrypoint/BUILD b/java/dagger/hilt/android/internal/earlyentrypoint/BUILD index ab1478a..5b5ed32 100644 --- a/java/dagger/hilt/android/internal/earlyentrypoint/BUILD +++ b/java/dagger/hilt/android/internal/earlyentrypoint/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor that aggregates metadata about Hilt @EarlyEntryPoint annotations +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/internal/legacy/BUILD b/java/dagger/hilt/android/internal/legacy/BUILD index 0814af0..4b18881 100644 --- a/java/dagger/hilt/android/internal/legacy/BUILD +++ b/java/dagger/hilt/android/internal/legacy/BUILD
@@ -15,6 +15,8 @@ # Description: # Internal Hilt libraries for legacy code. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java b/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java index 3fa4910..f05fea2 100644 --- a/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java +++ b/java/dagger/hilt/android/internal/managers/ActivityComponentManager.java
@@ -36,7 +36,9 @@ * because even the injector interface type is not a valid type if we have a hilt base class. * */ -public class ActivityComponentManager implements GeneratedComponentManager<Object> { +public class ActivityComponentManager + implements + GeneratedComponentManager<Object> { /** Entrypoint for {@link ActivityComponentBuilder}. */ @EntryPoint @InstallIn(ActivityRetainedComponent.class)
diff --git a/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java b/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java index dc3539c..3f53a6b 100644 --- a/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java +++ b/java/dagger/hilt/android/internal/managers/ActivityRetainedComponentManager.java
@@ -120,6 +120,8 @@ @Override public ActivityRetainedComponent generatedComponent() { + // TODO(bcorso): don't need the component lock since the component is stored in ViewModel + // which does its own locking if (component == null) { synchronized (componentLock) { if (component == null) {
diff --git a/java/dagger/hilt/android/internal/managers/BUILD b/java/dagger/hilt/android/internal/managers/BUILD index 950b511..ab1321f 100644 --- a/java/dagger/hilt/android/internal/managers/BUILD +++ b/java/dagger/hilt/android/internal/managers/BUILD
@@ -34,7 +34,9 @@ "ServiceComponentManager.java", "ViewComponentManager.java", ], - exports = [":saved_state_handle_holder"], + exports = [ + ":saved_state_handle_holder", + ], deps = [ ":component_supplier", ":saved_state_handle_holder",
diff --git a/java/dagger/hilt/android/internal/testing/BUILD b/java/dagger/hilt/android/internal/testing/BUILD index 899ab94..dea7ebc 100644 --- a/java/dagger/hilt/android/internal/testing/BUILD +++ b/java/dagger/hilt/android/internal/testing/BUILD
@@ -15,6 +15,8 @@ # Description: # Internal Hilt android testing libraries +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/internal/uninstallmodules/BUILD b/java/dagger/hilt/android/internal/uninstallmodules/BUILD index 583964b..1a49dc7 100644 --- a/java/dagger/hilt/android/internal/uninstallmodules/BUILD +++ b/java/dagger/hilt/android/internal/uninstallmodules/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor that aggregates metadata about Hilt @UninstallModules annotations +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/lifecycle/BUILD b/java/dagger/hilt/android/lifecycle/BUILD index 26394f0..1c7b23b 100644 --- a/java/dagger/hilt/android/lifecycle/BUILD +++ b/java/dagger/hilt/android/lifecycle/BUILD
@@ -15,6 +15,7 @@ # Description: # Hilt ViewModel integration. +load("@rules_java//java:defs.bzl", "java_library") load("//tools:bazel_compat.bzl", "compat_kt_android_library") package(default_visibility = ["//:src"])
diff --git a/java/dagger/hilt/android/migration/BUILD b/java/dagger/hilt/android/migration/BUILD index 3694560..6ee7465 100644 --- a/java/dagger/hilt/android/migration/BUILD +++ b/java/dagger/hilt/android/migration/BUILD
@@ -15,6 +15,8 @@ # Description: # Helpers for migrating to Hilt. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) android_library(
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 deleted file mode 100644 index 5509261..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/build.gradle +++ /dev/null
@@ -1,15 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -compileKotlin { - kotlinOptions { - jvmTarget = 11 - } -} - -dependencies { - implementation project(':agp-wrapper') - compileOnly gradleApi() - compileOnly "com.android.tools.build:gradle:7.0.0" -} \ No newline at end of file
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi70Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi70Impl.kt deleted file mode 100644 index 1f50794..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi70Impl.kt +++ /dev/null
@@ -1,42 +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.hilt.android.plugin.util - -import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.api.variant.ApplicationVariant -import com.android.build.api.variant.LibraryVariant -import org.gradle.api.Project - -class AndroidComponentsExtensionCompatApi70Impl( - private val project: Project -) : AndroidComponentsExtensionCompat { - - override fun onAllVariants(block: (ComponentCompat) -> Unit) { - val actual = project.extensions.getByType(AndroidComponentsExtension::class.java) - actual.onVariants { variant -> - block.invoke(ComponentCompatApi70Impl(variant)) - - when (variant) { - is ApplicationVariant -> variant.androidTest - is LibraryVariant -> variant.androidTest - else -> null - }?.let { block.invoke(ComponentCompatApi70Impl(it)) } - - variant.unitTest?.let { block.invoke(ComponentCompatApi70Impl(it)) } - } - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi70Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi70Impl.kt deleted file mode 100644 index 36c7d77..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-0/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi70Impl.kt +++ /dev/null
@@ -1,43 +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.hilt.android.plugin.util - -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 com.android.build.api.variant.Component - -internal class ComponentCompatApi70Impl(private val component: Component) : ComponentCompat() { - - override val name: String - get() = component.name - - @Suppress("UnstableApiUsage") // Due to ASM pipeline APIs - override fun <ParamT : InstrumentationParameters> transformClassesWith( - classVisitorFactoryImplClass: Class<out AsmClassVisitorFactory<ParamT>>, - scope: InstrumentationScope, - instrumentationParamsConfig: (ParamT) -> Unit - ) { - component.transformClassesWith(classVisitorFactoryImplClass, scope, instrumentationParamsConfig) - } - - @Suppress("UnstableApiUsage") // Due to ASM pipeline APIs - override fun setAsmFramesComputationMode(mode: FramesComputationMode) { - component.setAsmFramesComputationMode(mode) - } -}
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 deleted file mode 100644 index 982949a..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/build.gradle +++ /dev/null
@@ -1,15 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -compileKotlin { - kotlinOptions { - jvmTarget = 11 - } -} - -dependencies { - implementation project(':agp-wrapper') - compileOnly gradleApi() - compileOnly "com.android.tools.build:gradle:7.1.0" -} \ No newline at end of file
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi71Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi71Impl.kt deleted file mode 100644 index dc8704f..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi71Impl.kt +++ /dev/null
@@ -1,37 +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.hilt.android.plugin.util - -import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.api.variant.HasAndroidTest -import org.gradle.api.Project - -class AndroidComponentsExtensionCompatApi71Impl( - private val project: Project -) : AndroidComponentsExtensionCompat { - - override fun onAllVariants(block: (ComponentCompat) -> Unit) { - val actual = project.extensions.getByType(AndroidComponentsExtension::class.java) - actual.onVariants { variant -> - block.invoke(ComponentCompatApi71Impl(variant)) - - (variant as? HasAndroidTest)?.androidTest?.let { block.invoke(ComponentCompatApi71Impl(it)) } - - variant.unitTest?.let { block.invoke(ComponentCompatApi71Impl(it)) } - } - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi71Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi71Impl.kt deleted file mode 100644 index d7c9658..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-1/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi71Impl.kt +++ /dev/null
@@ -1,41 +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.hilt.android.plugin.util - -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 com.android.build.api.variant.Component - -internal class ComponentCompatApi71Impl(private val component: Component) : ComponentCompat() { - - override val name: String - get() = component.name - - override fun <ParamT : InstrumentationParameters> transformClassesWith( - classVisitorFactoryImplClass: Class<out AsmClassVisitorFactory<ParamT>>, - scope: InstrumentationScope, - instrumentationParamsConfig: (ParamT) -> Unit - ) { - component.transformClassesWith(classVisitorFactoryImplClass, scope, instrumentationParamsConfig) - } - - override fun setAsmFramesComputationMode(mode: FramesComputationMode) { - component.setAsmFramesComputationMode(mode) - } -}
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 deleted file mode 100644 index e0331c2..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/build.gradle +++ /dev/null
@@ -1,15 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -compileKotlin { - kotlinOptions { - jvmTarget = 11 - } -} - -dependencies { - implementation project(':agp-wrapper') - compileOnly gradleApi() - compileOnly "com.android.tools.build:gradle:7.2.0" -} \ No newline at end of file
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi72Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi72Impl.kt deleted file mode 100644 index 24ee5fd..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompatApi72Impl.kt +++ /dev/null
@@ -1,37 +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.hilt.android.plugin.util - -import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.api.variant.HasAndroidTest -import org.gradle.api.Project - -class AndroidComponentsExtensionCompatApi72Impl( - private val project: Project -) : AndroidComponentsExtensionCompat { - - override fun onAllVariants(block: (ComponentCompat) -> Unit) { - val actual = project.extensions.getByType(AndroidComponentsExtension::class.java) - actual.onVariants { variant -> - block.invoke(ComponentCompatApi72Impl(variant)) - - (variant as? HasAndroidTest)?.androidTest?.let { block.invoke(ComponentCompatApi72Impl(it)) } - - variant.unitTest?.let { block.invoke(ComponentCompatApi72Impl(it)) } - } - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi72Impl.kt b/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi72Impl.kt deleted file mode 100644 index ac4abf5..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-7-2/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompatApi72Impl.kt +++ /dev/null
@@ -1,45 +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.hilt.android.plugin.util - -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 com.android.build.api.variant.Component - -internal class ComponentCompatApi72Impl(private val component: Component) : ComponentCompat() { - - override val name: String - get() = component.name - - override fun <ParamT : InstrumentationParameters> transformClassesWith( - classVisitorFactoryImplClass: Class<out AsmClassVisitorFactory<ParamT>>, - scope: InstrumentationScope, - instrumentationParamsConfig: (ParamT) -> Unit - ) { - component.instrumentation.transformClassesWith( - classVisitorFactoryImplClass, - scope, - instrumentationParamsConfig - ) - } - - override fun setAsmFramesComputationMode(mode: FramesComputationMode) { - component.instrumentation.setAsmFramesComputationMode(mode) - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle deleted file mode 100644 index f270efb..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-impl/build.gradle +++ /dev/null
@@ -1,21 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -compileKotlin { - kotlinOptions { - jvmTarget = 11 - } -} - -dependencies { - api project(':agp-wrapper') - implementation project(':agp-wrapper-7-0') - implementation project(':agp-wrapper-7-1') - implementation project(':agp-wrapper-7-2') - compileOnly gradleApi() - compileOnly "com.android.tools.build:gradle:$agp_version" - - testImplementation 'junit:junit:4.12' - testImplementation 'com.google.truth:truth:1.0.1' -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/AGPVersionCompat.kt b/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/AGPVersionCompat.kt deleted file mode 100644 index 3ddd484..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/AGPVersionCompat.kt +++ /dev/null
@@ -1,37 +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.hilt.android.plugin.util - -import org.gradle.api.Project - -fun getAndroidComponentsExtension(project: Project): AndroidComponentsExtensionCompat { - val version = SimpleAGPVersion.ANDROID_GRADLE_PLUGIN_VERSION - return when { - version >= SimpleAGPVersion(7, 2) -> { - AndroidComponentsExtensionCompatApi72Impl(project) - } - version >= SimpleAGPVersion(7, 1) -> { - AndroidComponentsExtensionCompatApi71Impl(project) - } - version >= SimpleAGPVersion(7, 0) -> { - AndroidComponentsExtensionCompatApi70Impl(project) - } - else -> { - error("Android Gradle Plugin $version is not supported") - } - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/SimpleAGPVersion.kt b/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/SimpleAGPVersion.kt deleted file mode 100644 index 6c5e781..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/main/kotlin/dagger/hilt/android/plugin/util/SimpleAGPVersion.kt +++ /dev/null
@@ -1,77 +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.hilt.android.plugin.util - -/** - * Simple Android Gradle Plugin version class since there is no public API one. b/175816217 - */ -data class SimpleAGPVersion( - val major: Int, - val minor: Int, -) : Comparable<SimpleAGPVersion> { - - override fun toString(): String { - return "$major.$minor" - } - - override fun compareTo(other: SimpleAGPVersion): Int { - return compareValuesBy( - this, - other, - compareBy(SimpleAGPVersion::major).thenBy(SimpleAGPVersion::minor) - ) { it } - } - - companion object { - - // TODO(danysantiago): Migrate to AndroidPluginVersion once it is available (b/175816217) - val ANDROID_GRADLE_PLUGIN_VERSION by lazy { - val clazz = - findClass("com.android.Version") - ?: findClass("com.android.builder.model.Version") - if (clazz != null) { - return@lazy parse(clazz.getField("ANDROID_GRADLE_PLUGIN_VERSION").get(null) as String) - } - error( - "Unable to obtain AGP version. It is likely that the AGP version being used is too old." - ) - } - - fun parse(version: String?) = - tryParse(version) ?: error("Unable to parse AGP version: $version") - - private fun tryParse(version: String?): SimpleAGPVersion? { - if (version == null) { - return null - } - - val parts = version.split('.') - if (parts.size == 1) { - return SimpleAGPVersion(parts[0].toInt(), 0) - } - - return SimpleAGPVersion(parts[0].toInt(), parts[1].toInt()) - } - - private fun findClass(fqName: String) = - try { - Class.forName(fqName) - } catch (ex: ClassNotFoundException) { - null - } - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/test/kotlin/util/SimpleAGPVersionTest.kt b/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/test/kotlin/util/SimpleAGPVersionTest.kt deleted file mode 100644 index 155cb0c..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper-impl/src/test/kotlin/util/SimpleAGPVersionTest.kt +++ /dev/null
@@ -1,56 +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 util - -import com.google.common.truth.Truth.assertThat -import dagger.hilt.android.plugin.util.SimpleAGPVersion -import org.junit.Test - -class SimpleAGPVersionTest { - - @Test - fun parsing() { - assertThat(SimpleAGPVersion.parse("4.2")) - .isEqualTo(SimpleAGPVersion(4, 2)) - assertThat(SimpleAGPVersion.parse("4.2.1")) - .isEqualTo(SimpleAGPVersion(4, 2)) - assertThat(SimpleAGPVersion.parse("7.0.0-alpha01")) - .isEqualTo(SimpleAGPVersion(7, 0)) - } - - @Test - fun comparing() { - assertThat(SimpleAGPVersion(4, 2)) - .isEqualTo(SimpleAGPVersion(4, 2)) - assertThat(SimpleAGPVersion(4, 2)) - .isGreaterThan(SimpleAGPVersion(3, 4)) - assertThat(SimpleAGPVersion(4, 2)) - .isLessThan(SimpleAGPVersion(7, 0)) - - assertThat(SimpleAGPVersion.parse("4.2.1")) - .isEqualTo(SimpleAGPVersion.parse("4.2.2")) - assertThat(SimpleAGPVersion.parse("4.2.1")) - .isGreaterThan(SimpleAGPVersion.parse("3.4.1")) - assertThat(SimpleAGPVersion.parse("4.2.1")) - .isLessThan(SimpleAGPVersion.parse("7.0.1")) - - assertThat(SimpleAGPVersion.parse("4.2.1")) - .isLessThan(SimpleAGPVersion.parse("7.0.0-alpha01")) - assertThat(SimpleAGPVersion.parse("7.0.0-alpha01")) - .isEqualTo(SimpleAGPVersion.parse("7.0.0-alpha02")) - } -}
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle b/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle deleted file mode 100644 index d8238e8..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper/build.gradle +++ /dev/null
@@ -1,14 +0,0 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' -} - -compileKotlin { - kotlinOptions { - jvmTarget = 11 - } -} - -dependencies { - compileOnly gradleApi() - compileOnly "com.android.tools.build:gradle:$agp_version" -} \ No newline at end of file
diff --git a/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompat.kt b/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompat.kt deleted file mode 100644 index cdbeef2..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/AndroidComponentsExtensionCompat.kt +++ /dev/null
@@ -1,32 +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.hilt.android.plugin.util - -/** - * Compatibility version of [com.android.build.api.variant.AndroidComponentsExtension] - * - In AGP 4.2 its package is 'com.android.build.api.extension' - * - In AGP 7.0 its packages is 'com.android.build.api.variant' - */ -interface AndroidComponentsExtensionCompat { - - /** - * A combined compatibility function of - * [com.android.build.api.variant.AndroidComponentsExtension.onVariants] that includes also - * [AndroidTest] and [UnitTest] variants. - */ - fun onAllVariants(block: (ComponentCompat) -> Unit) -}
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 deleted file mode 100644 index 1f0d589..0000000 --- a/java/dagger/hilt/android/plugin/agp-wrapper/src/main/kotlin/dagger/hilt/android/plugin/util/ComponentCompat.kt +++ /dev/null
@@ -1,45 +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.hilt.android.plugin.util - -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] - * - In AGP 4.2 its package is 'com.android.build.api.component' - * - In AGP 7.0 its packages is 'com.android.build.api.variant' - */ -abstract class ComponentCompat { - - /** Redeclaration of [com.android.build.api.variant.ComponentIdentity.name] */ - abstract val name: String - - /** Redeclaration of [com.android.build.api.variant.Component.transformClassesWith] */ - abstract fun <ParamT : InstrumentationParameters> transformClassesWith( - classVisitorFactoryImplClass: Class<out AsmClassVisitorFactory<ParamT>>, - scope: InstrumentationScope, - instrumentationParamsConfig: (ParamT) -> Unit - ) - - /** Redeclaration of [com.android.build.api.variant.Component.setAsmFramesComputationMode] */ - abstract fun setAsmFramesComputationMode(mode: FramesComputationMode) -}
diff --git a/java/dagger/hilt/android/plugin/build.gradle b/java/dagger/hilt/android/plugin/build.gradle index 685ea7e..e40d4ed 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.9.20" - agp_version = System.getenv('AGP_VERSION') ?: "7.2.0" - ksp_version = "$kotlin_version-1.0.14" + kotlin_version = "2.0.21" + agp_version = System.getenv('AGP_VERSION') ?: "8.1.1" + ksp_version = "$kotlin_version-1.0.28" pluginArtifactId = 'hilt-android-gradle-plugin' pluginId = 'com.google.dagger.hilt.android' } @@ -12,9 +12,7 @@ id 'org.jetbrains.kotlin.jvm' version "$kotlin_version" id 'java-gradle-plugin' id 'maven-publish' - // Use shadow version >= 7.1.1 to get log4j vulnerability patches: - // https://github.com/johnrengelman/shadow/releases/tag/7.1.1 - id 'com.github.johnrengelman.shadow' version '7.1.1' + id 'com.github.johnrengelman.shadow' version '8.1.1' id 'org.jetbrains.kotlin.android' version "$kotlin_version" apply false }
diff --git a/java/dagger/hilt/android/plugin/gradle/wrapper/gradle-wrapper.properties b/java/dagger/hilt/android/plugin/gradle/wrapper/gradle-wrapper.properties index aa991fc..e1bef7e 100644 --- a/java/dagger/hilt/android/plugin/gradle/wrapper/gradle-wrapper.properties +++ b/java/dagger/hilt/android/plugin/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.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
diff --git a/java/dagger/hilt/android/plugin/main/build.gradle b/java/dagger/hilt/android/plugin/main/build.gradle index 035ecea..bb954f7 100644 --- a/java/dagger/hilt/android/plugin/main/build.gradle +++ b/java/dagger/hilt/android/plugin/main/build.gradle
@@ -59,12 +59,16 @@ } dependencies { - shadowed project(':agp-wrapper-impl') + // Include the shared library containing the APIs in + // dagger.hilt.processor.internal.root.ir. shadowed fileTree(dir: 'libs', include: '*.jar') - implementation gradleApi() + // Use compile-only for other plugin dependencies to avoid brining those + // to projects that don't use them. 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 gradleApi() implementation 'org.ow2.asm:asm:9.6' implementation "com.squareup:javapoet:1.13.0" @@ -85,12 +89,12 @@ it.pluginClasspath.from(configurations.testPluginCompile) } -compileKotlin { - kotlinOptions { +kotlin { + compilerOptions { allWarningsAsErrors = true - freeCompilerArgs += [ "-opt-in=kotlin.ExperimentalStdlibApi" ] - jvmTarget = 11 + freeCompilerArgs.add("-opt-in=kotlin.ExperimentalStdlibApi") } + jvmToolchain(17) } // Imports a shared library from the main project. The library and its classes
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 7b03e43..34a80d1 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
@@ -16,27 +16,34 @@ package dagger.hilt.android.plugin +import com.android.build.api.AndroidPluginVersion import com.android.build.api.instrumentation.FramesComputationMode import com.android.build.api.instrumentation.InstrumentationScope +import com.android.build.api.variant.AndroidComponentsExtension +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.api.variant.Component +import com.android.build.api.variant.HasAndroidTest +import com.android.build.api.variant.HasUnitTest +import com.android.build.api.variant.LibraryAndroidComponentsExtension +import com.android.build.api.variant.TestAndroidComponentsExtension import com.android.build.gradle.AppExtension import com.android.build.gradle.BaseExtension import com.android.build.gradle.LibraryExtension import com.android.build.gradle.TestExtension -import com.android.build.gradle.api.AndroidBasePlugin import com.android.build.gradle.tasks.JdkImageInput import dagger.hilt.android.plugin.task.AggregateDepsTask -import dagger.hilt.android.plugin.util.AggregatedPackagesTransform -import dagger.hilt.android.plugin.util.ComponentCompat -import dagger.hilt.android.plugin.util.CopyTransform -import dagger.hilt.android.plugin.util.SimpleAGPVersion +import dagger.hilt.android.plugin.transform.AggregatedPackagesTransform +import dagger.hilt.android.plugin.transform.AndroidEntryPointClassVisitor +import dagger.hilt.android.plugin.transform.CopyTransform import dagger.hilt.android.plugin.util.addJavaTaskProcessorOptions import dagger.hilt.android.plugin.util.addKaptTaskProcessorOptions import dagger.hilt.android.plugin.util.addKspTaskProcessorOptions import dagger.hilt.android.plugin.util.capitalize -import dagger.hilt.android.plugin.util.getAndroidComponentsExtension +import dagger.hilt.android.plugin.util.forEachRootVariant import dagger.hilt.android.plugin.util.getKaptConfigName import dagger.hilt.android.plugin.util.getKspConfigName import dagger.hilt.android.plugin.util.isKspTask +import dagger.hilt.android.plugin.util.onAllVariants import dagger.hilt.processor.internal.optionvalues.GradleProjectType import javax.inject.Inject import org.gradle.api.JavaVersion @@ -49,23 +56,21 @@ import org.gradle.api.provider.ProviderFactory import org.gradle.api.tasks.compile.JavaCompile import org.gradle.process.CommandLineArgumentProvider -import org.gradle.util.GradleVersion import org.objectweb.asm.Opcodes /** - * A Gradle plugin that checks if the project is an Android project and if so, registers a - * bytecode transformation. + * A Gradle plugin that checks if the project is an Android project and if so, registers a bytecode + * transformation. * * The plugin also passes an annotation processor option to disable superclass validation for * classes annotated with `@AndroidEntryPoint` since the registered transform by this plugin will * update the superclass. */ -class HiltGradlePlugin @Inject constructor( - private val providers: ProviderFactory -) : Plugin<Project> { +class HiltGradlePlugin @Inject constructor(private val providers: ProviderFactory) : + Plugin<Project> { override fun apply(project: Project) { var configured = false - project.plugins.withType(AndroidBasePlugin::class.java) { + project.plugins.withId("com.android.base") { configured = true configureHilt(project) } @@ -80,80 +85,59 @@ } private fun configureHilt(project: Project) { - val hiltExtension = project.extensions.create( - HiltExtension::class.java, "hilt", HiltExtensionImpl::class.java - ) - if (SimpleAGPVersion.ANDROID_GRADLE_PLUGIN_VERSION < SimpleAGPVersion(7, 0)) { - error("The Hilt Android Gradle plugin is only compatible with Android Gradle plugin (AGP) " + - "version 7.0 or higher (found ${SimpleAGPVersion.ANDROID_GRADLE_PLUGIN_VERSION}).") + val hiltExtension = + project.extensions.create(HiltExtension::class.java, "hilt", HiltExtensionImpl::class.java) + + val androidExtension = project.extensions.findByType(AndroidComponentsExtension::class.java) + check(androidExtension != null) { "Could not find the Android Gradle Plugin (AGP) extension." } + check(androidExtension.pluginVersion >= AndroidPluginVersion(8, 1)) { + "The Hilt Android Gradle plugin is only compatible with Android Gradle plugin (AGP) " + + "version 8.1.0 or higher (found ${androidExtension.pluginVersion})." } + configureDependencyTransforms(project) configureCompileClasspath(project, hiltExtension) - configureBytecodeTransformASM(project) + configureBytecodeTransformASM(androidExtension) configureAggregatingTask(project, hiltExtension) - configureProcessorFlags(project, hiltExtension) + configureProcessorFlags(project, hiltExtension, androidExtension) } // Configures Gradle dependency transforms. - private fun configureDependencyTransforms(project: Project) = project.dependencies.apply { - registerTransform(CopyTransform::class.java) { spec -> - // Java/Kotlin library projects offer an artifact of type 'jar'. - spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "jar") - // Android library projects (with or without Kotlin) offer an artifact of type - // 'android-classes', which AGP can offer as a jar. - spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "android-classes") - spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) + private fun configureDependencyTransforms(project: Project) = + project.dependencies.apply { + registerTransform(CopyTransform::class.java) { spec -> + // Java/Kotlin library projects offer an artifact of type 'jar'. + spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "jar") + // Android library projects (with or without Kotlin) offer an artifact of type + // 'android-classes', which AGP can offer as a jar. + spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "android-classes") + spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) + } + registerTransform(CopyTransform::class.java) { spec -> + // File Collection dependencies might be an artifact of type 'directory', e.g. when + // adding as a dep the destination directory of the JavaCompile task. + spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "directory") + spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) + } + registerTransform(AggregatedPackagesTransform::class.java) { spec -> + spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) + spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, AGGREGATED_HILT_ARTIFACT_TYPE_VALUE) + } } - registerTransform(CopyTransform::class.java) { spec -> - // File Collection dependencies might be an artifact of type 'directory', e.g. when - // adding as a dep the destination directory of the JavaCompile task. - spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, "directory") - spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) - } - registerTransform(AggregatedPackagesTransform::class.java) { spec -> - spec.from.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) - spec.to.attribute(ARTIFACT_TYPE_ATTRIBUTE, AGGREGATED_HILT_ARTIFACT_TYPE_VALUE) - } - } private fun configureCompileClasspath(project: Project, hiltExtension: HiltExtension) { - val androidExtension = project.baseExtension() ?: error("Android BaseExtension not found.") + val androidExtension = + project.extensions.findByType(BaseExtension::class.java) + ?: error("Android BaseExtension not found.") androidExtension.forEachRootVariant { variant -> - configureVariantCompileClasspath(project, hiltExtension, androidExtension, variant) - } - } - - // Invokes the [block] function for each Android variant that is considered a Hilt root, where - // dependencies are aggregated and components are generated. - private fun BaseExtension.forEachRootVariant( - @Suppress("DEPRECATION") block: (variant: com.android.build.gradle.api.BaseVariant) -> Unit - ) { - when (this) { - is AppExtension -> { - // For an app project we configure the app variant and both androidTest and unitTest - // variants, Hilt components are generated in all of them. - applicationVariants.all { block(it) } - testVariants.all { block(it) } - unitTestVariants.all { block(it) } - } - is LibraryExtension -> { - // For a library project, only the androidTest and unitTest variant are configured since - // Hilt components are not generated in a library. - testVariants.all { block(it) } - unitTestVariants.all { block(it) } - } - is TestExtension -> { - applicationVariants.all { block(it) } - } - else -> error("Hilt plugin does not know how to configure '$this'") + configureVariantCompileClasspath(project, hiltExtension, variant) } } private fun configureVariantCompileClasspath( project: Project, hiltExtension: HiltExtension, - androidExtension: BaseExtension, - @Suppress("DEPRECATION") variant: com.android.build.gradle.api.BaseVariant + @Suppress("DEPRECATION") variant: com.android.build.gradle.api.BaseVariant, ) { if ( !hiltExtension.enableExperimentalClasspathAggregation || hiltExtension.enableAggregatingTask @@ -164,63 +148,34 @@ return } - if ( - androidExtension.lintOptions.isCheckReleaseBuilds && - SimpleAGPVersion.ANDROID_GRADLE_PLUGIN_VERSION < SimpleAGPVersion(7, 0) - ) { - // Sadly we have to ask users to disable lint when enableExperimentalClasspathAggregation is - // set to true and they are not in AGP 7.0+ since Lint will cause issues during the - // configuration phase. See b/158753935 and b/160392650 - error( - "Invalid Hilt plugin configuration: When 'enableExperimentalClasspathAggregation' is " + - "enabled 'android.lintOptions.checkReleaseBuilds' has to be set to false unless " + - "com.android.tools.build:gradle:7.0.0+ is used." - ) - } - - if ( - listOf( - "android.injected.build.model.only", // Sent by AS 1.0 only - "android.injected.build.model.only.advanced", // Sent by AS 1.1+ - "android.injected.build.model.only.versioned", // Sent by AS 2.4+ - "android.injected.build.model.feature.full.dependencies", // Sent by AS 2.4+ - "android.injected.build.model.v2", // Sent by AS 4.2+ - ).any { - // forUseAtConfigurationTime() is deprecated in 7.4 and later: - // https://docs.gradle.org/current/userguide/upgrading_version_7.html#changes_7.4 - if (GradleVersion.version(project.gradle.gradleVersion) < GradleVersion.version("7.4.0")) { - @Suppress("DEPRECATION") - providers.gradleProperty(it).forUseAtConfigurationTime().isPresent - } else { - providers.gradleProperty(it).isPresent - } - } - ) { + if (project.isGradleSyncRunning()) { // Do not configure compile classpath when AndroidStudio is building the model (syncing) // otherwise it will cause a freeze. return } @Suppress("DEPRECATION") // Older variant API is deprecated - val runtimeConfiguration = if (variant is com.android.build.gradle.api.TestVariant) { - // For Android test variants, the tested runtime classpath is used since the test app has - // tested dependencies removed. - variant.testedVariant.runtimeConfiguration - } else { - variant.runtimeConfiguration - } - val artifactView = runtimeConfiguration.incoming.artifactView { view -> - view.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) - view.componentFilter { identifier -> - // Filter out the project's classes from the aggregated view since this can cause - // issues with Kotlin internal members visibility. b/178230629 - if (identifier is ProjectComponentIdentifier) { - identifier.projectName != project.name - } else { - true + val runtimeConfiguration = + if (variant is com.android.build.gradle.api.TestVariant) { + // For Android test variants, the tested runtime classpath is used since the test app has + // tested dependencies removed. + variant.testedVariant.runtimeConfiguration + } else { + variant.runtimeConfiguration + } + val artifactView = + runtimeConfiguration.incoming.artifactView { view -> + view.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, DAGGER_ARTIFACT_TYPE_VALUE) + view.componentFilter { identifier -> + // Filter out the project's classes from the aggregated view since this can cause + // issues with Kotlin internal members visibility. b/178230629 + if (identifier is ProjectComponentIdentifier) { + identifier.projectName != project.name + } else { + true + } } } - } // CompileOnly config names don't follow the usual convention: // <Variant Name> -> <Config Name> @@ -230,33 +185,34 @@ // release -> releaseCompileOnly // releaseUnitTest -> testReleaseCompileOnly @Suppress("DEPRECATION") // Older variant API is deprecated - val compileOnlyConfigName = when (variant) { - is com.android.build.gradle.api.TestVariant -> - "androidTest${variant.name.substringBeforeLast("AndroidTest").capitalize()}CompileOnly" - is com.android.build.gradle.api.UnitTestVariant -> - "test${variant.name.substringBeforeLast("UnitTest").capitalize()}CompileOnly" - else -> - "${variant.name}CompileOnly" - } + val compileOnlyConfigName = + when (variant) { + is com.android.build.gradle.api.TestVariant -> + "androidTest${variant.name.substringBeforeLast("AndroidTest").capitalize()}CompileOnly" + is com.android.build.gradle.api.UnitTestVariant -> + "test${variant.name.substringBeforeLast("UnitTest").capitalize()}CompileOnly" + else -> "${variant.name}CompileOnly" + } project.dependencies.add(compileOnlyConfigName, artifactView.files) } - private fun configureBytecodeTransformASM(project: Project) { - fun registerTransform(androidComponent: ComponentCompat) { - androidComponent.transformClassesWith( + private fun configureBytecodeTransformASM(androidExtension: AndroidComponentsExtension<*, *, *>) { + androidExtension.onAllVariants { variantComponent -> + variantComponent.instrumentation.transformClassesWith( classVisitorFactoryImplClass = AndroidEntryPointClassVisitor.Factory::class.java, scope = InstrumentationScope.PROJECT, - instrumentationParamsConfig = {} + instrumentationParamsConfig = {}, ) - androidComponent.setAsmFramesComputationMode( + variantComponent.instrumentation.setAsmFramesComputationMode( FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS ) } - getAndroidComponentsExtension(project).onAllVariants { registerTransform(it) } } private fun configureAggregatingTask(project: Project, hiltExtension: HiltExtension) { - val androidExtension = project.baseExtension() ?: error("Android BaseExtension not found.") + val androidExtension = + project.extensions.findByType(BaseExtension::class.java) + ?: error("Android BaseExtension not found.") androidExtension.forEachRootVariant { variant -> configureVariantAggregatingTask(project, hiltExtension, androidExtension, variant) } @@ -266,21 +222,20 @@ project: Project, hiltExtension: HiltExtension, androidExtension: BaseExtension, - @Suppress("DEPRECATION") variant: com.android.build.gradle.api.BaseVariant + @Suppress("DEPRECATION") variant: com.android.build.gradle.api.BaseVariant, ) { if (!hiltExtension.enableAggregatingTask) { // Option is not enabled, don't configure aggregating task. return } - val hiltCompileConfiguration = project.configurations.create( - "hiltCompileOnly${variant.name.capitalize()}" - ).apply { - description = "Hilt aggregated compile only dependencies for '${variant.name}'" - isCanBeConsumed = false - isCanBeResolved = true - isVisible = false - } + val hiltCompileConfiguration = + project.configurations.create("hiltCompileOnly${variant.name.capitalize()}").apply { + description = "Hilt aggregated compile only dependencies for '${variant.name}'" + isCanBeConsumed = false + isCanBeResolved = true + isVisible = false + } // Add the JavaCompile task classpath and output dir to the config, the task's classpath // will contain: // * compileOnly dependencies @@ -290,165 +245,167 @@ // TODO(danysantiago): Revisit to support K2 compiler project.dependencies.add( hiltCompileConfiguration.name, - project.files(variant.javaCompileProvider.map { it.classpath }) + project.files(variant.javaCompileProvider.map { it.classpath }), ) project.dependencies.add( hiltCompileConfiguration.name, - project.files(variant.javaCompileProvider.map {it.destinationDirectory.get() }) + project.files(variant.javaCompileProvider.map { it.destinationDirectory.get() }), ) - val hiltAnnotationProcessorConfiguration = project.configurations.create( - "hiltAnnotationProcessor${variant.name.capitalize()}" - ).also { config -> - config.description = "Hilt annotation processor classpath for '${variant.name}'" - config.isCanBeConsumed = false - config.isCanBeResolved = true - config.isVisible = false - // Add user annotation processor configuration, so that SPI plugins and other processors - // are discoverable. - val apConfigurations: List<Configuration> = buildList { - add(variant.annotationProcessorConfiguration) - project.plugins.withId("kotlin-kapt") { - project.configurations.findByName(getKaptConfigName(variant))?.let { add(it) } + val hiltAnnotationProcessorConfiguration = + project.configurations.create("hiltAnnotationProcessor${variant.name.capitalize()}").also { + config -> + config.description = "Hilt annotation processor classpath for '${variant.name}'" + config.isCanBeConsumed = false + config.isCanBeResolved = true + config.isVisible = false + // Add user annotation processor configuration, so that SPI plugins and other processors + // are discoverable. + val apConfigurations: List<Configuration> = buildList { + add(variant.annotationProcessorConfiguration) + project.plugins.withId("kotlin-kapt") { + project.configurations.findByName(getKaptConfigName(variant))?.let { add(it) } + } + project.plugins.withId("com.google.devtools.ksp") { + // Add the main 'ksp' config since the variant aware config does not extend main. + // https://github.com/google/ksp/issues/1433 + project.configurations.findByName("ksp")?.let { add(it) } + project.configurations.findByName(getKspConfigName(variant))?.let { add(it) } + } } - project.plugins.withId("com.google.devtools.ksp") { - // Add the main 'ksp' config since the variant aware config does not extend main. - // https://github.com/google/ksp/issues/1433 - project.configurations.findByName("ksp")?.let { add(it) } - project.configurations.findByName(getKspConfigName(variant))?.let { add(it) } - } + config.extendsFrom(*apConfigurations.toTypedArray()) + // Add hilt-compiler even though it might be in the AP configurations already. + project.dependencies.add(config.name, "com.google.dagger:hilt-compiler:$HILT_VERSION") } - config.extendsFrom(*apConfigurations.toTypedArray()) - // Add hilt-compiler even though it might be in the AP configurations already. - project.dependencies.add(config.name, "com.google.dagger:hilt-compiler:$HILT_VERSION") - } fun getInputClasspath(artifactAttributeValue: String) = buildList<Configuration> { - @Suppress("DEPRECATION") // Older variant API is deprecated - if (variant is com.android.build.gradle.api.TestVariant) { - add(variant.testedVariant.runtimeConfiguration) + @Suppress("DEPRECATION") // Older variant API is deprecated + if (variant is com.android.build.gradle.api.TestVariant) { + add(variant.testedVariant.runtimeConfiguration) + } + add(variant.runtimeConfiguration) + add(hiltCompileConfiguration) } - add(variant.runtimeConfiguration) - add(hiltCompileConfiguration) - }.map { configuration -> - configuration.incoming.artifactView { view -> - view.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, artifactAttributeValue) - }.files - }.let { - project.files(*it.toTypedArray()) - } + .map { configuration -> + configuration.incoming + .artifactView { view -> + view.attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, artifactAttributeValue) + } + .files + } + .let { project.files(*it.toTypedArray()) } - val aggregatingTask = project.tasks.register( - "hiltAggregateDeps${variant.name.capitalize()}", - AggregateDepsTask::class.java - ) { - it.compileClasspath.setFrom(getInputClasspath(AGGREGATED_HILT_ARTIFACT_TYPE_VALUE)) - it.outputDir.set( - project.file(project.buildDir.resolve("generated/hilt/component_trees/${variant.name}/")) - ) - @Suppress("DEPRECATION") // Older variant API is deprecated - it.testEnvironment.set( - variant is com.android.build.gradle.api.TestVariant || - variant is com.android.build.gradle.api.UnitTestVariant || - androidExtension is com.android.build.gradle.TestExtension - ) - it.crossCompilationRootValidationDisabled.set( - hiltExtension.disableCrossCompilationRootValidation - ) - if (SimpleAGPVersion.ANDROID_GRADLE_PLUGIN_VERSION >= SimpleAGPVersion(7, 1)) { + val aggregatingTask = + project.tasks.register( + "hiltAggregateDeps${variant.name.capitalize()}", + AggregateDepsTask::class.java, + ) { + it.compileClasspath.setFrom(getInputClasspath(AGGREGATED_HILT_ARTIFACT_TYPE_VALUE)) + it.outputDir.set( + project.file(project.buildDir.resolve("generated/hilt/component_trees/${variant.name}/")) + ) + @Suppress("DEPRECATION") // Older variant API is deprecated + it.testEnvironment.set( + variant is com.android.build.gradle.api.TestVariant || + variant is com.android.build.gradle.api.UnitTestVariant || + androidExtension is com.android.build.gradle.TestExtension + ) + it.crossCompilationRootValidationDisabled.set( + hiltExtension.disableCrossCompilationRootValidation + ) it.asmApiVersion.set(Opcodes.ASM9) } - } - val componentClasses = project.files( - project.buildDir.resolve("intermediates/hilt/component_classes/${variant.name}/") - ) - val componentsJavaCompileTask = project.tasks.register( - "hiltJavaCompile${variant.name.capitalize()}", - JavaCompile::class.java - ) { compileTask -> - compileTask.source = aggregatingTask.map { it.outputDir.asFileTree }.get() - // Configure the input classpath based on Java 9 compatibility, specifically for Java 9 the - // android.jar is now included in the input classpath instead of the bootstrapClasspath. - // See: com/android/build/gradle/tasks/JavaCompileUtils.kt - val mainBootstrapClasspath = - variant.javaCompileProvider.map { it.options.bootstrapClasspath ?: project.files() }.get() - if ( - JavaVersion.current().isJava9Compatible && - androidExtension.compileOptions.targetCompatibility.isJava9Compatible - ) { - compileTask.classpath = - getInputClasspath(DAGGER_ARTIFACT_TYPE_VALUE).plus(mainBootstrapClasspath) - // Copies argument providers from original task, which should contain the JdkImageInput - variant.javaCompileProvider.get().let { originalCompileTask -> - originalCompileTask.options.compilerArgumentProviders - .filter { - it is HiltCommandLineArgumentProvider || it is JdkImageInput - } - .forEach { - compileTask.options.compilerArgumentProviders.add(it) - } - } - compileTask.options.compilerArgs.add("-XDstringConcat=inline") - } else { - compileTask.classpath = getInputClasspath(DAGGER_ARTIFACT_TYPE_VALUE) - compileTask.options.bootstrapClasspath = mainBootstrapClasspath - } - compileTask.destinationDirectory.set(componentClasses.singleFile) - compileTask.options.apply { - annotationProcessorPath = hiltAnnotationProcessorConfiguration - generatedSourceOutputDirectory.set( - project.file( - project.buildDir.resolve("generated/hilt/component_sources/${variant.name}/") - ) - ) + val componentClasses = + project.files( + project.buildDir.resolve("intermediates/hilt/component_classes/${variant.name}/") + ) + val componentsJavaCompileTask = + project.tasks.register( + "hiltJavaCompile${variant.name.capitalize()}", + JavaCompile::class.java, + ) { compileTask -> + compileTask.source = aggregatingTask.map { it.outputDir.asFileTree }.get() + // Configure the input classpath based on Java 9 compatibility, specifically for Java 9 the + // android.jar is now included in the input classpath instead of the bootstrapClasspath. + // See: com/android/build/gradle/tasks/JavaCompileUtils.kt + val mainBootstrapClasspath = + variant.javaCompileProvider.map { it.options.bootstrapClasspath ?: project.files() }.get() if ( - JavaVersion.current().isJava8Compatible && - androidExtension.compileOptions.targetCompatibility.isJava8Compatible + JavaVersion.current().isJava9Compatible && + androidExtension.compileOptions.targetCompatibility.isJava9Compatible ) { - compilerArgs.add("-parameters") + compileTask.classpath = + getInputClasspath(DAGGER_ARTIFACT_TYPE_VALUE).plus(mainBootstrapClasspath) + // Copies argument providers from original task, which should contain the JdkImageInput + variant.javaCompileProvider.get().let { originalCompileTask -> + originalCompileTask.options.compilerArgumentProviders + .filter { it is HiltCommandLineArgumentProvider || it is JdkImageInput } + .forEach { compileTask.options.compilerArgumentProviders.add(it) } + } + compileTask.options.compilerArgs.add("-XDstringConcat=inline") + } else { + compileTask.classpath = getInputClasspath(DAGGER_ARTIFACT_TYPE_VALUE) + compileTask.options.bootstrapClasspath = mainBootstrapClasspath } - compilerArgs.add("-Adagger.fastInit=enabled") - compilerArgs.add("-Adagger.hilt.internal.useAggregatingRootProcessor=false") - compilerArgs.add("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true") - encoding = androidExtension.compileOptions.encoding + compileTask.destinationDirectory.set(componentClasses.singleFile) + compileTask.options.apply { + annotationProcessorPath = hiltAnnotationProcessorConfiguration + generatedSourceOutputDirectory.set( + project.file( + project.buildDir.resolve("generated/hilt/component_sources/${variant.name}/") + ) + ) + if ( + JavaVersion.current().isJava8Compatible && + androidExtension.compileOptions.targetCompatibility.isJava8Compatible + ) { + compilerArgs.add("-parameters") + } + compilerArgs.add("-Adagger.fastInit=enabled") + compilerArgs.add("-Adagger.hilt.internal.useAggregatingRootProcessor=false") + compilerArgs.add("-Adagger.hilt.android.internal.disableAndroidSuperclassValidation=true") + encoding = androidExtension.compileOptions.encoding + } + compileTask.sourceCompatibility = + androidExtension.compileOptions.sourceCompatibility.toString() + compileTask.targetCompatibility = + androidExtension.compileOptions.targetCompatibility.toString() } - compileTask.sourceCompatibility = - androidExtension.compileOptions.sourceCompatibility.toString() - compileTask.targetCompatibility = - androidExtension.compileOptions.targetCompatibility.toString() - } componentClasses.builtBy(componentsJavaCompileTask) variant.registerPostJavacGeneratedBytecode(componentClasses) } - private fun configureProcessorFlags(project: Project, hiltExtension: HiltExtension) { - val androidExtension = project.baseExtension() ?: error("Android BaseExtension not found.") - val projectType = when (androidExtension) { - is AppExtension -> GradleProjectType.APP - is LibraryExtension -> GradleProjectType.LIBRARY - is TestExtension -> GradleProjectType.TEST - else -> error("Hilt plugin does not know how to configure '$this'") - } + private fun configureProcessorFlags( + project: Project, + hiltExtension: HiltExtension, + androidExtension: AndroidComponentsExtension<*, *, *>, + ) { + val projectType = + when (androidExtension) { + is ApplicationAndroidComponentsExtension -> GradleProjectType.APP + is LibraryAndroidComponentsExtension -> GradleProjectType.LIBRARY + is TestAndroidComponentsExtension -> GradleProjectType.TEST + else -> error("Hilt plugin does not know how to configure '$this'") + } - getAndroidComponentsExtension(project).onAllVariants { component -> + androidExtension.onAllVariants { variantComponent -> // Pass annotation processor flags via a CommandLineArgumentProvider so that plugin // options defined in the extension are populated from the user's build file. val argsProducer: (Task) -> CommandLineArgumentProvider = { task -> HiltCommandLineArgumentProvider( forKsp = task.isKspTask(), projectType = projectType, - enableAggregatingTask = - hiltExtension.enableAggregatingTask, + enableAggregatingTask = hiltExtension.enableAggregatingTask, disableCrossCompilationRootValidation = - hiltExtension.disableCrossCompilationRootValidation + hiltExtension.disableCrossCompilationRootValidation, ) } - addJavaTaskProcessorOptions(project, component, argsProducer) - addKaptTaskProcessorOptions(project, component, argsProducer) - addKspTaskProcessorOptions(project, component, argsProducer) + addJavaTaskProcessorOptions(project, variantComponent, argsProducer) + addKaptTaskProcessorOptions(project, variantComponent, argsProducer) + addKspTaskProcessorOptions(project, variantComponent, argsProducer) } } @@ -457,15 +414,16 @@ if (project.state.failure != null) { return } - val dependencies = project.configurations - .filterNot { - // Exclude plugin created config since plugin adds the deps to them. - it.name.startsWith("hiltAnnotationProcessor") || - it.name.startsWith("hiltCompileOnly") - } - .flatMap { configuration -> - configuration.dependencies.map { dependency -> dependency.group to dependency.name } - }.toSet() + val dependencies = + project.configurations + .filterNot { + // Exclude plugin created config since plugin adds the deps to them. + it.name.startsWith("hiltAnnotationProcessor") || it.name.startsWith("hiltCompileOnly") + } + .flatMap { configuration -> + configuration.dependencies.map { dependency -> dependency.group to dependency.name } + } + .toSet() fun getMissingDepMsg(depCoordinate: String): String = "The Hilt Android Gradle plugin is applied but no $depCoordinate dependency was found." if (!dependencies.contains(LIBRARY_GROUP to "hilt-android")) { @@ -473,20 +431,30 @@ } if ( !dependencies.contains(LIBRARY_GROUP to "hilt-android-compiler") && - !dependencies.contains(LIBRARY_GROUP to "hilt-compiler") + !dependencies.contains(LIBRARY_GROUP to "hilt-compiler") ) { error(getMissingDepMsg("$LIBRARY_GROUP:hilt-compiler")) } } - private fun Project.baseExtension(): BaseExtension? - = extensions.findByType(BaseExtension::class.java) - companion object { private val ARTIFACT_TYPE_ATTRIBUTE = Attribute.of("artifactType", String::class.java) const val DAGGER_ARTIFACT_TYPE_VALUE = "jar-for-dagger" const val AGGREGATED_HILT_ARTIFACT_TYPE_VALUE = "aggregated-jar-for-hilt" const val LIBRARY_GROUP = "com.google.dagger" + + private fun Project.isGradleSyncRunning() = + gradleSyncProps.any { property -> + providers.gradleProperty(property).map { it.toBoolean() }.orElse(false).get() + } + + private val gradleSyncProps by lazy { + listOf( + "android.injected.build.model.v2", + "android.injected.build.model.only", + "android.injected.build.model.only.advanced", + ) + } } }
diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/AggregatedPackagesTransform.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/transform/AggregatedPackagesTransform.kt similarity index 93% rename from java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/AggregatedPackagesTransform.kt rename to java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/transform/AggregatedPackagesTransform.kt index cc9c2bb..ac964bb 100644 --- a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/AggregatedPackagesTransform.kt +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/transform/AggregatedPackagesTransform.kt
@@ -14,9 +14,13 @@ * limitations under the License. */ -package dagger.hilt.android.plugin.util +package dagger.hilt.android.plugin.transform import dagger.hilt.android.plugin.root.AggregatedAnnotation +import dagger.hilt.android.plugin.util.forEachZipEntry +import dagger.hilt.android.plugin.util.isClassFile +import dagger.hilt.android.plugin.util.isJarFile +import dagger.hilt.android.plugin.util.walkInPlatformIndependentOrder import java.io.ByteArrayOutputStream import java.io.File import java.util.zip.ZipEntry
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/transform/AndroidEntryPointClassVisitor.kt similarity index 97% rename from java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/AndroidEntryPointClassVisitor.kt rename to java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/transform/AndroidEntryPointClassVisitor.kt index 16e4af9..d849894 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/transform/AndroidEntryPointClassVisitor.kt
@@ -14,18 +14,13 @@ * limitations under the License. */ -package dagger.hilt.android.plugin +package dagger.hilt.android.plugin.transform import com.android.build.api.instrumentation.AsmClassVisitorFactory import com.android.build.api.instrumentation.ClassContext import com.android.build.api.instrumentation.ClassData import com.android.build.api.instrumentation.InstrumentationParameters -import java.io.File -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Internal -import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.FieldVisitor import org.objectweb.asm.MethodVisitor import org.objectweb.asm.Opcodes
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/transform/CopyTransform.kt similarity index 97% rename from java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/CopyTransform.kt rename to java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/transform/CopyTransform.kt index f7c33dc..1f9eb89 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/transform/CopyTransform.kt
@@ -14,7 +14,7 @@ * limitations under the License. */ -package dagger.hilt.android.plugin.util +package dagger.hilt.android.plugin.transform import org.gradle.api.artifacts.transform.InputArtifact import org.gradle.api.artifacts.transform.TransformAction
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 a91ce35..0489de7 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
@@ -16,7 +16,10 @@ package dagger.hilt.android.plugin.util -import com.google.devtools.ksp.gradle.KspTaskJvm +import com.android.build.api.variant.ComponentIdentity +import com.google.devtools.ksp.gradle.KspAATask +import com.google.devtools.ksp.gradle.KspTask +import kotlin.reflect.KClass import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.tasks.compile.JavaCompile @@ -25,17 +28,17 @@ internal fun addJavaTaskProcessorOptions( project: Project, - component: ComponentCompat, + variantIdentity: ComponentIdentity, produceArgProvider: (Task) -> CommandLineArgumentProvider -) = project.tasks.withType(JavaCompile::class.java) { task -> - if (task.name == "compile${component.name.capitalize()}JavaWithJavac") { +) = project.tasks.withType(JavaCompile::class.java).configureEach { task -> + if (task.name == "compile${variantIdentity.name.capitalize()}JavaWithJavac") { task.options.compilerArgumentProviders.add(produceArgProvider.invoke(task)) } } internal fun addKaptTaskProcessorOptions( project: Project, - component: ComponentCompat, + variantIdentity: ComponentIdentity, produceArgProvider: (Task) -> CommandLineArgumentProvider ) = project.plugins.withId("kotlin-kapt") { checkClass("org.jetbrains.kotlin.gradle.internal.KaptTask") { @@ -48,10 +51,10 @@ sub-projects. """.trimIndent() } - project.tasks.withType(KaptTask::class.java) { task -> - if (task.name == "kapt${component.name.capitalize()}Kotlin" || + project.tasks.withType(KaptTask::class.java).configureEach { task -> + if (task.name == "kapt${variantIdentity.name.capitalize()}Kotlin" || // Task names in shared/src/AndroidMain in KMP projects has a platform suffix. - task.name == "kapt${component.name.capitalize()}KotlinAndroid") { + task.name == "kapt${variantIdentity.name.capitalize()}KotlinAndroid") { val argProvider = produceArgProvider.invoke(task) // TODO: Update once KT-58009 is fixed. try { @@ -69,10 +72,10 @@ internal fun addKspTaskProcessorOptions( project: Project, - component: ComponentCompat, + variantIdentity: ComponentIdentity, produceArgProvider: (Task) -> CommandLineArgumentProvider ) = project.plugins.withId("com.google.devtools.ksp") { - checkClass("com.google.devtools.ksp.gradle.KspTaskJvm") { + check(kspOneTaskClass != null || kspTwoTaskClass != null) { """ The KSP plugin was detected to be applied but its task class could not be found. @@ -84,13 +87,25 @@ 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" || + fun <T : Task> configureEach( + kclass: KClass<T>, + block: T.(CommandLineArgumentProvider) -> Unit + ) { + project.tasks.withType(kclass.java).configureEach { task -> + if (task.name == "ksp${variantIdentity.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)) + task.name == "ksp${variantIdentity.name.capitalize()}KotlinAndroid") { + val argProvider = produceArgProvider.invoke(task) + task.block(argProvider) + } } } + if (kspOneTaskClass != null) { + configureEach(KspTask::class) { commandLineArgumentProviders.add(it) } + } + if (kspTwoTaskClass != null) { + configureEach(KspAATask::class) { commandLineArgumentProviders.add(it) } + } } private inline fun checkClass(fqn: String, msg: () -> String) { @@ -101,10 +116,21 @@ } } -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 -} +private val kspOneTaskClass = + try { + Class.forName("com.google.devtools.ksp.gradle.KspTask") + } catch (ex: ClassNotFoundException) { + null + } + +private val kspTwoTaskClass = + try { + Class.forName("com.google.devtools.ksp.gradle.KspAATask") + } catch (ex: ClassNotFoundException) { + null + } + +internal fun Task.isKspTask() = + kspOneTaskClass?.isAssignableFrom(this::class.java) == true || + kspTwoTaskClass?.isAssignableFrom(this::class.java) == true
diff --git a/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt new file mode 100644 index 0000000..24a6254 --- /dev/null +++ b/java/dagger/hilt/android/plugin/main/src/main/kotlin/dagger/hilt/android/plugin/util/Variants.kt
@@ -0,0 +1,66 @@ +/* + * 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.plugin.util + +import com.android.build.api.variant.AndroidComponentsExtension +import com.android.build.api.variant.Component +import com.android.build.api.variant.HasAndroidTest +import com.android.build.api.variant.HasUnitTest +import com.android.build.gradle.AppExtension +import com.android.build.gradle.BaseExtension +import com.android.build.gradle.LibraryExtension +import com.android.build.gradle.TestExtension + +/** + * Invokes the [block] function for each Android variant, including android instrumentation tests + * and host unit tests. + */ +internal fun AndroidComponentsExtension<*, *, *>.onAllVariants(block: (Component) -> Unit) { + this.onVariants { variant -> + block(variant) + (variant as? HasUnitTest)?.unitTest?.let { block(it) } + (variant as? HasAndroidTest)?.androidTest?.let { block(it) } + } +} + +/** + * Invokes the [block] function for each Android variant that is considered a Hilt root, where + * dependencies are aggregated and components are generated. + */ +internal fun BaseExtension.forEachRootVariant( + @Suppress("DEPRECATION") block: (variant: com.android.build.gradle.api.BaseVariant) -> Unit +) { + when (this) { + is AppExtension -> { + // For an app project we configure the app variant and both androidTest and unitTest + // variants, Hilt components are generated in all of them. + applicationVariants.all { block(it) } + testVariants.all { block(it) } + unitTestVariants.all { block(it) } + } + is LibraryExtension -> { + // For a library project, only the androidTest and unitTest variant are configured since + // Hilt components are not generated in a library. + testVariants.all { block(it) } + unitTestVariants.all { block(it) } + } + is TestExtension -> { + applicationVariants.all { block(it) } + } + else -> error("Hilt plugin does not know how to configure '$this'") + } +}
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 9e8a097..38f62e5 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
@@ -5,7 +5,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 21 @@ -17,6 +17,7 @@ sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } + namespace = "liba" } dependencies {
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 450f128..549e008 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
@@ -5,7 +5,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 21 @@ -17,6 +17,7 @@ sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 } + namespace = "libc" } dependencies {
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 954e209..ced9532 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
@@ -21,7 +21,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" flavorDimensions 'api', 'version' productFlavors { @@ -49,6 +49,8 @@ targetSdkVersion 33 } + namespace = "simple.app" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 068d402..5cfb7ad 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
@@ -21,7 +21,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" flavorDimensions 'api', 'version' productFlavors { @@ -48,6 +48,8 @@ targetSdkVersion 33 } + namespace = "simple.library" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 506d40a..01ba5b4 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
@@ -29,6 +29,8 @@ targetSdkVersion 33 } + namespace = "simple.app" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 57f7a74..d9102bd 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
@@ -28,6 +28,8 @@ targetSdkVersion 33 } + namespace = "simple.library" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 f488fb3..e243c3b 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
@@ -88,10 +88,7 @@ fun parameters() = listOf( // 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"), + arrayOf("8.3.0", "8.4"), ) } }
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 c5a67af..85ac371 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
@@ -86,7 +86,6 @@ add(":compressDebugAssets") add(":desugarDebugFileDependencies") add(":extractDeepLinksDebug") - add(":generateDebugBuildConfig") add(":generateDebugResValues") // When aggregating task is enabled, the plugin adds two more tasks that should be // cacheable. @@ -97,10 +96,14 @@ add(":javaPreCompileDebug") add(":mergeDebugAssets") add(":mergeDebugJniLibFolders") + add(":mergeDebugResources") add(":mergeDebugShaders") add(":mergeExtDexDebug") add(":mergeLibDexDebug") add(":mergeProjectDexDebug") + add(":packageDebugResources") + add(":parseDebugLocalResources") + add(":processDebugMainManifest") add(":processDebugManifestForPackage") add(":transformDebugClassesWithAsm") }
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 221dfcf..f7d41f3 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
@@ -157,7 +157,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { ${ if (isAppProject) "applicationId \"plugin.test\"" else "" } @@ -165,6 +165,8 @@ targetSdkVersion 33 } + namespace = "minimal" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -254,7 +256,7 @@ // Finds a transformed file. The srcFilePath is relative to the app's package. fun getTransformedFile(srcFilePath: String): File { val parentDir = - File(projectRoot, "build/intermediates/asm_instrumented_project_classes/debug") + File(projectRoot, "build/intermediates/classes/debug/transformDebugClassesWithAsm/dirs") return File(parentDir, srcFilePath).also { if (!it.exists()) { error("Unable to find transformed class ${it.path}")
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 4fb25a0..048f237 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
@@ -148,7 +148,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { applicationId "hilt.simple" @@ -161,6 +161,8 @@ } } + namespace = "simple" + compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -183,7 +185,7 @@ testImplementation 'junit:junit:4.12' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'androidx.test:runner:1.4.0' - testImplementation 'org.robolectric:robolectric:4.4' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'com.google.dagger:hilt-android-testing:LOCAL-SNAPSHOT' testAnnotationProcessor 'com.google.dagger:hilt-compiler:LOCAL-SNAPSHOT' } @@ -244,17 +246,17 @@ genAppInjectorDeps = File( projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.java" + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.java", ) genActivityInjectorDeps1 = File( projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.java" + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.java", ) genActivityInjectorDeps2 = File( projectRoot, - "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.java" + "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.java", ) genModuleDeps1 = File(projectRoot, "$defaultGenSrcDir/hilt_aggregated_deps/_simple_Module1.java") @@ -269,35 +271,35 @@ File( projectRoot, testComponentTreeDepsGenSrcDir + - "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.java" + "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.java", ) genTest2ComponentTreeDeps = File( projectRoot, testComponentTreeDepsGenSrcDir + - "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.java" + "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.java", ) genTest1HiltComponents = File( projectRoot, - "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.java" + "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.java", ) genTest2HiltComponents = File( projectRoot, - "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.java" + "$testRootGenSrcDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.java", ) genTest1DaggerHiltApplicationComponent = File( projectRoot, testRootGenSrcDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.java" + "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.java", ) genTest2DaggerHiltApplicationComponent = File( projectRoot, testRootGenSrcDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.java" + "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.java", ) classSrcApp = File(projectRoot, "$defaultClassesDir/simple/SimpleApp.class") @@ -319,17 +321,17 @@ classGenAppInjectorDeps = File( projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.class" + "$defaultClassesDir/hilt_aggregated_deps/_simple_SimpleApp_GeneratedInjector.class", ) classGenActivityInjectorDeps1 = File( projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.class" + "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity1_GeneratedInjector.class", ) classGenActivityInjectorDeps2 = File( projectRoot, - "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.class" + "$defaultClassesDir/hilt_aggregated_deps/_simple_Activity2_GeneratedInjector.class", ) classGenModuleDeps1 = File(projectRoot, "$defaultClassesDir/hilt_aggregated_deps/_simple_Module1.class") @@ -345,35 +347,35 @@ File( projectRoot, testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.class" + "/dagger/hilt/android/internal/testing/root/Test1_ComponentTreeDeps.class", ) classGenTest2ComponentTreeDeps = File( projectRoot, testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.class" + "/dagger/hilt/android/internal/testing/root/Test2_ComponentTreeDeps.class", ) classGenTest1HiltComponents = File( projectRoot, - "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.class" + "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test1_HiltComponents.class", ) classGenTest2HiltComponents = File( projectRoot, - "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.class" + "$testRootClassesDir/dagger/hilt/android/internal/testing/root/Test2_HiltComponents.class", ) classGenTest1DaggerHiltApplicationComponent = File( projectRoot, testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.class" + "/dagger/hilt/android/internal/testing/root/DaggerTest1_HiltComponents_SingletonC.class", ) classGenTest2DaggerHiltApplicationComponent = File( projectRoot, testRootClassesDir + - "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.class" + "/dagger/hilt/android/internal/testing/root/DaggerTest2_HiltComponents_SingletonC.class", ) } @@ -400,7 +402,7 @@ genModuleDeps2, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) ) @@ -425,7 +427,7 @@ classGenModuleDeps2, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) ) } @@ -445,7 +447,7 @@ super.onResume(); } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalBuild() @@ -464,7 +466,7 @@ genActivityInjector1, genActivityInjectorDeps1, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } else { // * Root classes along with components are always re-generated (aggregated processor) @@ -477,7 +479,7 @@ genActivityInjectorDeps1, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -513,7 +515,7 @@ classGenActivityInjectorDeps1, classGenHiltComponents, classGenComponentTreeDeps, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -531,7 +533,7 @@ """ private void foo() { } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalBuild() @@ -550,11 +552,7 @@ 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, - ) + listOf(genHiltActivity1, genActivityInjector1, genActivityInjectorDeps1) } else { // * Root classes along with components are always re-generated (aggregated processor) listOf( @@ -566,7 +564,7 @@ genActivityInjectorDeps1, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -585,7 +583,7 @@ classSrcActivity1, classGenHiltActivity1, classGenActivityInjector1, - classGenActivityInjectorDeps1 + classGenActivityInjectorDeps1, ) } else { // * All aggregating processor gen sources are re-compiled @@ -599,7 +597,7 @@ classGenActivityInjectorDeps1, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -620,7 +618,7 @@ return 10.10; } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalBuild() @@ -637,7 +635,7 @@ genHiltApp, // Re-generated because components got re-generated genModuleDeps1, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } else { // * Root classes along with components are always re-generated (aggregated processor) @@ -648,7 +646,7 @@ genModuleDeps1, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -668,7 +666,7 @@ classGenHiltApp, classGenModuleDeps1, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } else { // * All aggregating processor gen sources are re-compiled @@ -680,7 +678,7 @@ classGenModuleDeps1, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -701,7 +699,7 @@ super.onCreate(); } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalBuild() @@ -719,7 +717,7 @@ genAppInjector, genAppInjectorDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } else { // * Root classes along with components are always re-generated (aggregated processor) @@ -729,7 +727,7 @@ genAppInjectorDeps, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -749,7 +747,7 @@ classGenAppInjector, classGenAppInjectorDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } else { // * All aggregating processor gen sources are re-compiled @@ -760,7 +758,7 @@ classGenAppInjectorDeps, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -789,7 +787,7 @@ genHiltApp, // Re-generated because components got re-generated genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } else { listOf( @@ -798,7 +796,7 @@ genAppInjectorDeps, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -811,7 +809,7 @@ classSrcActivity2, classGenHiltActivity2, classGenActivityInjector2, - classGenActivityInjectorDeps2 + classGenActivityInjectorDeps2, ) ) val recompiledClassFiles = @@ -820,7 +818,7 @@ classGenHiltApp, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } else { listOf( @@ -829,7 +827,7 @@ classGenAppInjectorDeps, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -858,7 +856,7 @@ genHiltApp, // Re-generated because components got re-generated genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } else { // * Root classes along with components are always re-generated (aggregated processor) @@ -868,7 +866,7 @@ genAppInjectorDeps, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -883,7 +881,7 @@ classGenHiltApp, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } else { listOf( @@ -892,7 +890,7 @@ classGenAppInjectorDeps, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -936,7 +934,7 @@ genAppInjectorDeps, genComponentTreeDeps, genHiltComponents, - genDaggerHiltApplicationComponent + genDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.JAVA, regeneratedSourceFiles) @@ -951,7 +949,7 @@ classGenAppInjectorDeps, classGenComponentTreeDeps, classGenHiltComponents, - classGenDaggerHiltApplicationComponent + classGenDaggerHiltApplicationComponent, ) } assertChangedFiles(FileType.CLASS, recompiledClassFiles) @@ -1001,7 +999,7 @@ @Test public void newTest() { } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalTestBuild() @@ -1012,10 +1010,7 @@ val regeneratedSourceFiles = if (incapMode == ISOLATING_MODE) { - listOf( - genTest1HiltComponents, - genTest1DaggerHiltApplicationComponent, - ) + listOf(genTest1HiltComponents, genTest1DaggerHiltApplicationComponent) } else { listOf( genTest1ComponentTreeDeps, @@ -1073,7 +1068,7 @@ """ private void newMethod() { } """ - .trimIndent() + .trimIndent(), ) val result = runIncrementalTestBuild()
diff --git a/java/dagger/hilt/android/plugin/settings.gradle b/java/dagger/hilt/android/plugin/settings.gradle index 778bf22..4060e34 100644 --- a/java/dagger/hilt/android/plugin/settings.gradle +++ b/java/dagger/hilt/android/plugin/settings.gradle
@@ -16,9 +16,3 @@ rootProject.name = 'hilt-gradle-plugin' include ':main' -include ':agp-wrapper' -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 bf5a6c3..4e4357e 100644 --- a/java/dagger/hilt/android/processor/BUILD +++ b/java/dagger/hilt/android/processor/BUILD
@@ -15,8 +15,9 @@ # Description: # Hilt android processors. +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -92,7 +93,7 @@ "net.ltgt.gradle.incap:incap", "org.jetbrains.kotlin:kotlin-stdlib", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_root_packages = [ # Java 11 javadocs requires non-empty root package so use ".internal" as the root package. "dagger.hilt.processor.internal",
diff --git a/java/dagger/hilt/android/processor/internal/BUILD b/java/dagger/hilt/android/processor/internal/BUILD index 45615e4..60698ad 100644 --- a/java/dagger/hilt/android/processor/internal/BUILD +++ b/java/dagger/hilt/android/processor/internal/BUILD
@@ -15,6 +15,8 @@ # Description: # Internal code for implementing Hilt android processors. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java index e1bf74f..dfee51a 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/ActivityGenerator.java
@@ -95,7 +95,8 @@ Generators.copyConstructors( metadata.baseElement(), CodeBlock.builder().addStatement("_initHiltInternal()").build(), - builder); + builder, + metadata.element()); builder.addMethod(init()); if (!metadata.overridesAndroidEntryPointClass()) { builder
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD index 327412b..aef29e5 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD
@@ -14,6 +14,8 @@ # Description: # Hilt android processors. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java index 78a7976..d2005ac 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/BroadcastReceiverGenerator.java
@@ -78,7 +78,7 @@ JavaPoetExtKt.addOriginatingElement(builder, metadata.element()); Generators.addGeneratedBaseClassJavadoc(builder, AndroidClassNames.ANDROID_ENTRY_POINT); Processors.addGeneratedAnnotation(builder, env, getClass()); - Generators.copyConstructors(metadata.baseElement(), builder); + Generators.copyConstructors(metadata.baseElement(), builder, metadata.element()); metadata.baseElement().getTypeParameters().stream() .map(XTypeParameterElement::getTypeVariableName)
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java index 45017e4..873e654 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/FragmentGenerator.java
@@ -86,7 +86,7 @@ Processors.addGeneratedAnnotation(builder, env, getClass()); Generators.copyLintAnnotations(metadata.element(), builder); Generators.copySuppressAnnotations(metadata.element(), builder); - Generators.copyConstructors(metadata.baseElement(), builder); + Generators.copyConstructors(metadata.baseElement(), builder, metadata.element()); metadata.baseElement().getTypeParameters().stream() .map(XTypeParameterElement::getTypeVariableName)
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java index dc2339b..6213a4a 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java
@@ -28,6 +28,7 @@ import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XVariableElement; import com.google.common.base.Preconditions; @@ -45,6 +46,7 @@ import dagger.hilt.android.processor.internal.AndroidClassNames; import dagger.hilt.android.processor.internal.androidentrypoint.AndroidEntryPointMetadata.AndroidType; import dagger.hilt.processor.internal.ClassNames; +import dagger.hilt.processor.internal.Processors; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -65,15 +67,20 @@ } /** Copies all constructors with arguments to the builder. */ - static void copyConstructors(XTypeElement baseClass, TypeSpec.Builder builder) { - copyConstructors(baseClass, CodeBlock.builder().build(), builder); + static void copyConstructors( + XTypeElement baseClass, TypeSpec.Builder builder, XTypeElement subclassReference) { + copyConstructors(baseClass, CodeBlock.builder().build(), builder, subclassReference); } /** Copies all constructors with arguments along with an appended body to the builder. */ - static void copyConstructors(XTypeElement baseClass, CodeBlock body, TypeSpec.Builder builder) { + static void copyConstructors( + XTypeElement baseClass, + CodeBlock body, + TypeSpec.Builder builder, + XTypeElement subclassReference) { ImmutableList<XConstructorElement> constructors = baseClass.getConstructors().stream() - .filter(constructor -> !constructor.isPrivate()) + .filter(constructor -> isConstructorVisibleToSubclass(constructor, subclassReference)) .collect(toImmutableList()); if (constructors.size() == 1 @@ -86,6 +93,30 @@ constructors.forEach(constructor -> builder.addMethod(copyConstructor(constructor, body))); } + /** + * Returns true if the constructor is visibile to a subclass in the same package as the reference. + * A reference is used because usually for generators the subclass is being generated and so + * doesn't actually exist. + */ + static boolean isConstructorVisibleToSubclass( + XConstructorElement constructor, XTypeElement subclassReference) { + // Check if the constructor has package private visibility and we're outside the package + if (Processors.hasJavaPackagePrivateVisibility(constructor) + && !constructor + .getEnclosingElement() + .getPackageName() + .contentEquals(subclassReference.getPackageName())) { + return false; + // Or if it is private, we know generated code can't be in the same file + } else if (constructor.isPrivate()) { + return false; + } + + // Assume this is for a subclass per the name, so both protected and public methods are always + // accessible. + return true; + } + /** Returns Optional with AnnotationSpec for Nullable if found on element, empty otherwise. */ private static Optional<AnnotationSpec> getNullableAnnotationSpec(XElement element) { for (XAnnotation annotation : element.getAllAnnotations()) { @@ -100,14 +131,30 @@ return Optional.empty(); } + /** Returns a TypeName for the given type, including any @Nullable annotations on it. */ + private static TypeName withAnyNullnessAnnotation(XType type) { + for (XAnnotation annotation : type.getAllAnnotations()) { + if (annotation.getClassName().simpleName().contentEquals("Nullable")) { + return type.getTypeName().annotated(toAnnotationSpec(annotation)); + } + } + return type.getTypeName(); + } + /** - * Returns a ParameterSpec of the input parameter, @Nullable annotated if existing in original - * (this does not handle Nullable type annotations). + * Returns a ParameterSpec of the input parameter, @Nullable annotated if existing in original. */ private static ParameterSpec getParameterSpecWithNullable(XVariableElement parameter) { - ParameterSpec.Builder builder = - ParameterSpec.builder(parameter.getType().getTypeName(), getSimpleName(parameter)); - getNullableAnnotationSpec(parameter).ifPresent(builder::addAnnotation); + TypeName type = withAnyNullnessAnnotation(parameter.getType()); + ParameterSpec.Builder builder = ParameterSpec.builder(type, getSimpleName(parameter)); + /* + * If we already have a type-use Nullable, don't consider also adding a declaration Nullable, + * which could be a duplicate in the case of "hybrid" annotations that support both type-use and + * declaration targets. + */ + if (!type.isAnnotated()) { + getNullableAnnotationSpec(parameter).ifPresent(builder::addAnnotation); + } return builder.build(); }
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/ServiceGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/ServiceGenerator.java index 8e1405e..7c63152 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/ServiceGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/ServiceGenerator.java
@@ -16,21 +16,14 @@ package dagger.hilt.android.processor.internal.androidentrypoint; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; -import static java.util.stream.Collectors.joining; import androidx.room.compiler.processing.JavaPoetExtKt; -import androidx.room.compiler.processing.XConstructorElement; -import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XFiler; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeParameterElement; -import com.google.common.collect.ImmutableList; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; import dagger.hilt.android.processor.internal.AndroidClassNames; import dagger.hilt.processor.internal.Processors; @@ -58,7 +51,6 @@ TypeSpec.classBuilder(generatedClassName.simpleName()) .superclass(metadata.baseClassName()) .addModifiers(metadata.generatedClassModifiers()) - .addMethods(baseClassConstructors()) .addMethod(onCreateMethod()); JavaPoetExtKt.addOriginatingElement(builder, metadata.element()); @@ -74,6 +66,7 @@ Generators.addInjectionMethods(metadata, builder); Generators.addComponentOverride(metadata, builder); + Generators.copyConstructors(metadata.baseElement(), builder, metadata.element()); env.getFiler() .write( @@ -81,29 +74,6 @@ XFiler.Mode.Isolating); } - private ImmutableList<MethodSpec> baseClassConstructors() { - return metadata.baseElement().getConstructors().stream() - .map(ServiceGenerator::toMethodSpec) - .collect(toImmutableList()); - } - - private static MethodSpec toMethodSpec(XConstructorElement constructor) { - ImmutableList<ParameterSpec> params = - constructor.getParameters().stream() - .map(ServiceGenerator::toParameterSpec) - .collect(toImmutableList()); - - return MethodSpec.constructorBuilder() - .addParameters(params) - .addStatement("super($L)", params.stream().map(p -> p.name).collect(joining(","))) - .build(); - } - - private static ParameterSpec toParameterSpec(XExecutableParameterElement parameter) { - return ParameterSpec.builder(parameter.getType().getTypeName(), getSimpleName(parameter)) - .build(); - } - // @CallSuper // @Override // protected void onCreate() {
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/ViewGenerator.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/ViewGenerator.java index 799ba1f..d9a09fd 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/ViewGenerator.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/ViewGenerator.java
@@ -78,7 +78,8 @@ Generators.addInjectionMethods(metadata, builder); metadata.baseElement().getConstructors().stream() - .filter(this::isConstructorVisibleToGeneratedClass) + .filter(constructor -> Generators.isConstructorVisibleToSubclass( + constructor, metadata.element())) .map(this::constructorMethod) .forEach(builder::addMethod); @@ -88,17 +89,6 @@ XFiler.Mode.Isolating); } - private boolean isConstructorVisibleToGeneratedClass(XConstructorElement constructor) { - if (Processors.hasJavaPackagePrivateVisibility(constructor) && !isInOurPackage(constructor)) { - return false; - } else if (constructor.isPrivate()) { - return false; - } - - // We extend the base class, so both protected and public methods are always accessible. - return true; - } - /** * Returns a pass-through constructor matching the base class's provided constructorElement. The * generated constructor simply calls super(), then inject(). @@ -108,7 +98,9 @@ * <pre> * Hilt_$CLASS(Context context, ...) { * super(context, ...); - * inject(); + * if (!isInEditMode()) { + * inject(); + * } * } * </pre> */ @@ -126,7 +118,9 @@ AnnotationSpec.builder(AndroidClassNames.TARGET_API).addMember("value", "21").build()); } - builder.addStatement("inject()"); + builder.beginControlFlow("if(!isInEditMode())") + .addStatement("inject()") + .endControlFlow(); return builder.build(); } @@ -185,11 +179,4 @@ return isDeclared(type) && Processors.isAssignableFrom(type.getTypeElement(), AndroidClassNames.CONTEXT); } - - private boolean isInOurPackage(XConstructorElement constructor) { - return constructor - .getEnclosingElement() - .getPackageName() - .contentEquals(metadata.element().getPackageName()); - } }
diff --git a/java/dagger/hilt/android/processor/internal/bindvalue/BUILD b/java/dagger/hilt/android/processor/internal/bindvalue/BUILD index 5fb1736..5918b22 100644 --- a/java/dagger/hilt/android/processor/internal/bindvalue/BUILD +++ b/java/dagger/hilt/android/processor/internal/bindvalue/BUILD
@@ -14,6 +14,8 @@ # Description: # Hilt android library for binding values in test processors. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/android/processor/internal/customtestapplication/BUILD b/java/dagger/hilt/android/processor/internal/customtestapplication/BUILD index a4fa94b..339a7a0 100644 --- a/java/dagger/hilt/android/processor/internal/customtestapplication/BUILD +++ b/java/dagger/hilt/android/processor/internal/customtestapplication/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.android.testing.CustomTestApplication. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/BUILD b/java/dagger/hilt/android/processor/internal/viewmodel/BUILD index 90760ea..6c01d3c 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/BUILD +++ b/java/dagger/hilt/android/processor/internal/viewmodel/BUILD
@@ -14,7 +14,8 @@ # Description: # ViewModelInject processor. -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_plugin") package(default_visibility = ["//:src"])
diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt index 920410a..a84c1a4 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelMetadata.kt
@@ -108,7 +108,8 @@ val assistedFactoryMethodType = assistedFactoryMethod!!.asMemberOf(assistedFactoryType) ProcessorErrors.checkState( - assistedFactoryMethodType.returnType.asTypeName() == viewModelElement.asClassName(), + assistedFactoryMethodType.returnType.asTypeName() + .equalsIgnoreNullability(viewModelElement.asClassName()), assistedFactoryMethod, "Class %s must have a factory method that returns a %s. Found %s.", XElements.toStableString(assistedFactory),
diff --git a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt index 69094c9..9983a98 100644 --- a/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt +++ b/java/dagger/hilt/android/processor/internal/viewmodel/ViewModelValidationPlugin.kt
@@ -48,9 +48,14 @@ class ViewModelValidationPlugin : BindingGraphPlugin { private lateinit var env: XProcessingEnv + private lateinit var daggerProcessingEnv: DaggerProcessingEnv override fun init(processingEnv: DaggerProcessingEnv, options: MutableMap<String, String>) { - env = processingEnv.toXProcessingEnv() + daggerProcessingEnv = processingEnv + } + + override fun onProcessingRoundBegin() { + env = daggerProcessingEnv.toXProcessingEnv() } override fun visitGraph(bindingGraph: BindingGraph, diagnosticReporter: DiagnosticReporter) { @@ -75,7 +80,7 @@ "\nInjection of an @HiltViewModel class is prohibited since it does not create a " + "ViewModel instance correctly.\nAccess the ViewModel via the Android APIs " + "(e.g. ViewModelProvider) instead." + - "\nInjected ViewModel: ${target.key().type()}\n" + "\nInjected ViewModel: ${target.key().type()}\n", ) } else if ( isViewModelAssistedFactory(target) && !isInternalViewModelAssistedFactoryUsage(source) @@ -86,7 +91,7 @@ "\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" + "\nInjected factory: ${target.key().type()}\n", ) } }
diff --git a/java/dagger/hilt/android/qualifiers/BUILD b/java/dagger/hilt/android/qualifiers/BUILD index 51bb842..1b45e9e 100644 --- a/java/dagger/hilt/android/qualifiers/BUILD +++ b/java/dagger/hilt/android/qualifiers/BUILD
@@ -15,6 +15,8 @@ # Description: # Hilt Android qualifiers +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) android_library(
diff --git a/java/dagger/hilt/android/scopes/BUILD b/java/dagger/hilt/android/scopes/BUILD index d89176f..bf41296 100644 --- a/java/dagger/hilt/android/scopes/BUILD +++ b/java/dagger/hilt/android/scopes/BUILD
@@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) # Description:
diff --git a/java/dagger/hilt/android/testing/BUILD b/java/dagger/hilt/android/testing/BUILD index ee3d78a..ac05b99 100644 --- a/java/dagger/hilt/android/testing/BUILD +++ b/java/dagger/hilt/android/testing/BUILD
@@ -14,8 +14,9 @@ # Description: # Testing libraries for Hilt Android. +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -248,7 +249,7 @@ "com.google.guava:guava", "javax.annotation:javax.annotation-api", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_exclude_packages = [ "dagger.hilt.internal", "dagger.hilt.android.internal",
diff --git a/java/dagger/hilt/android/testing/compile/BUILD b/java/dagger/hilt/android/testing/compile/BUILD index 7d41e0d..9959fac 100644 --- a/java/dagger/hilt/android/testing/compile/BUILD +++ b/java/dagger/hilt/android/testing/compile/BUILD
@@ -14,6 +14,8 @@ # Description: # Tests for internal code for implementing Hilt processors. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java b/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java index 89bf678..39e90a9 100644 --- a/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java +++ b/java/dagger/hilt/android/testing/compile/HiltCompilerTests.java
@@ -70,6 +70,14 @@ /** {@link Compiler} instances for testing Android Hilt. */ public final class HiltCompilerTests { + private static final ImmutableList<String> DEFAULT_JAVAC_OPTIONS = ImmutableList.of(); + + private static final ImmutableList<String> DEFAULT_KOTLINC_OPTIONS = + ImmutableList.of( + "-api-version=1.9", + "-language-version=1.9", + "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"); + /** Returns the {@link XProcessingEnv.Backend} for the given {@link CompilationResultSubject}. */ public static XProcessingEnv.Backend backend(CompilationResultSubject subject) { return CompilerTests.backend(subject); @@ -161,8 +169,8 @@ sources, /* classpath= */ ImmutableList.of(CompilerTests.compilerDepsJar()), /* inheritClasspath= */ false, - /* javacArguments= */ ImmutableList.of(), - /* kotlincArguments= */ ImmutableList.of(), + /* javacArguments= */ DEFAULT_JAVAC_OPTIONS, + /* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS, /* kaptProcessors= */ ImmutableList.<Processor>builder() .addAll(defaultProcessors()) .addAll(additionalProcessors) @@ -182,10 +190,10 @@ new CustomTestApplicationProcessor(), new DefineComponentProcessor(), new EarlyEntryPointProcessor(), + new UninstallModulesProcessor(), new GeneratesRootInputProcessor(), new OriginatingElementProcessor(), - new RootProcessor(), - new UninstallModulesProcessor()); + new RootProcessor()); } private static ImmutableList<SymbolProcessorProvider> kspDefaultProcessors() { @@ -199,10 +207,10 @@ new KspCustomTestApplicationProcessor.Provider(), new KspDefineComponentProcessor.Provider(), new KspEarlyEntryPointProcessor.Provider(), + new KspUninstallModulesProcessor.Provider(), new KspGeneratesRootInputProcessor.Provider(), new KspOriginatingElementProcessor.Provider(), - new KspRootProcessor.Provider(), - new KspUninstallModulesProcessor.Provider()); + new KspRootProcessor.Provider()); } /** Used to compile Hilt sources and inspect the compiled results. */ @@ -274,9 +282,12 @@ sources().asList(), /* classpath= */ ImmutableList.of(CompilerTests.compilerDepsJar()), /* options= */ processorOptions(), - /* javacArguments= */ javacArguments().asList(), - /* kotlincArguments= */ ImmutableList.of( - "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"), + /* javacArguments= */ + ImmutableList.<String>builder() + .addAll(DEFAULT_JAVAC_OPTIONS) + .addAll(javacArguments()) + .build(), + /* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS, /* config= */ HiltProcessingEnvConfigs.CONFIGS, /* javacProcessors= */ ImmutableList.<Processor>builder() .addAll(mergeProcessors(defaultProcessors(), additionalJavacProcessors()))
diff --git a/java/dagger/hilt/codegen/BUILD b/java/dagger/hilt/codegen/BUILD index c88182b..da19bc2 100644 --- a/java/dagger/hilt/codegen/BUILD +++ b/java/dagger/hilt/codegen/BUILD
@@ -15,6 +15,8 @@ # Description: # This package contains sources used within code generated sources. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/components/BUILD b/java/dagger/hilt/components/BUILD index 9baf476..e3fd3b7 100644 --- a/java/dagger/hilt/components/BUILD +++ b/java/dagger/hilt/components/BUILD
@@ -15,6 +15,8 @@ # Description: # Hilt components +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/BUILD b/java/dagger/hilt/internal/BUILD index ad4dbb5..d199bf2 100644 --- a/java/dagger/hilt/internal/BUILD +++ b/java/dagger/hilt/internal/BUILD
@@ -15,6 +15,8 @@ # Description: # Internal Hilt libraries +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library( @@ -41,8 +43,8 @@ "GeneratedComponentManagerHolder.java", ], exports = [ - ":preconditions", - ":unsafe_casts", + "//java/dagger/hilt/internal:preconditions", + "//java/dagger/hilt/internal:unsafe_casts", ], )
diff --git a/java/dagger/hilt/internal/aggregatedroot/BUILD b/java/dagger/hilt/internal/aggregatedroot/BUILD index 0a7263a..9a8afeb 100644 --- a/java/dagger/hilt/internal/aggregatedroot/BUILD +++ b/java/dagger/hilt/internal/aggregatedroot/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotation for aggregating information about Hilt roots. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/aliasof/BUILD b/java/dagger/hilt/internal/aliasof/BUILD index 13d4364..9bbad4d 100644 --- a/java/dagger/hilt/internal/aliasof/BUILD +++ b/java/dagger/hilt/internal/aliasof/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotation for classes generated by @AliasOf. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/componenttreedeps/BUILD b/java/dagger/hilt/internal/componenttreedeps/BUILD index 1a100d5..ccc6086 100644 --- a/java/dagger/hilt/internal/componenttreedeps/BUILD +++ b/java/dagger/hilt/internal/componenttreedeps/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotation for aggregating information about Hilt roots. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/definecomponent/BUILD b/java/dagger/hilt/internal/definecomponent/BUILD index 973b7cb..1ce3a21 100644 --- a/java/dagger/hilt/internal/definecomponent/BUILD +++ b/java/dagger/hilt/internal/definecomponent/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotations for classes generated by @DefineComponent and @DefineComponent.Factory. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/generatesrootinput/BUILD b/java/dagger/hilt/internal/generatesrootinput/BUILD index 8e54ac4..f524499 100644 --- a/java/dagger/hilt/internal/generatesrootinput/BUILD +++ b/java/dagger/hilt/internal/generatesrootinput/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotations for classes generated by @GeneratesRootInput. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/internal/processedrootsentinel/BUILD b/java/dagger/hilt/internal/processedrootsentinel/BUILD index 70b72a6..cbcc3e2 100644 --- a/java/dagger/hilt/internal/processedrootsentinel/BUILD +++ b/java/dagger/hilt/internal/processedrootsentinel/BUILD
@@ -15,6 +15,8 @@ # Description: # The annotation for aggregating information about processed Hilt roots. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/migration/BUILD b/java/dagger/hilt/migration/BUILD index 27f472a..7d8ed6c 100644 --- a/java/dagger/hilt/migration/BUILD +++ b/java/dagger/hilt/migration/BUILD
@@ -14,6 +14,8 @@ # Description: # Libraries for migration. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/hilt/processor/BUILD b/java/dagger/hilt/processor/BUILD index ecbc294..4e90e76 100644 --- a/java/dagger/hilt/processor/BUILD +++ b/java/dagger/hilt/processor/BUILD
@@ -15,8 +15,9 @@ # Description: # Hilt android processors. +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -114,7 +115,7 @@ "net.ltgt.gradle.incap:incap", "org.jetbrains.kotlin:kotlin-stdlib", ], - javadoc_android_api_level = 32, + javadoc_android_api_level = 34, javadoc_root_packages = [ # Java 11 javadocs requires non-empty root package so use ".internal" as the root package. "dagger.hilt.processor.internal",
diff --git a/java/dagger/hilt/processor/internal/BUILD b/java/dagger/hilt/processor/internal/BUILD index 8828227..cd83d83 100644 --- a/java/dagger/hilt/processor/internal/BUILD +++ b/java/dagger/hilt/processor/internal/BUILD
@@ -15,7 +15,8 @@ # Description: # Internal code for implementing Hilt processors. -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_library") package(default_visibility = ["//:src"])
diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsMetadata.java b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsMetadata.java index 840ba9c..0caaf7b 100644 --- a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsMetadata.java +++ b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsMetadata.java
@@ -107,8 +107,11 @@ } private static AggregatedDepsMetadata create(XTypeElement element, XProcessingEnv env) { + checkState( + element.hasAnnotation(ClassNames.AGGREGATED_DEPS), + "Missing @AggregatedDeps annotation on %s", + element.getClassName().canonicalName()); XAnnotation annotation = element.getAnnotation(ClassNames.AGGREGATED_DEPS); - return new AutoValue_AggregatedDepsMetadata( element, getTestElement(annotation.getAnnotationValue("test"), env),
diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/BUILD b/java/dagger/hilt/processor/internal/aggregateddeps/BUILD index 2d1bd92..f69d509 100644 --- a/java/dagger/hilt/processor/internal/aggregateddeps/BUILD +++ b/java/dagger/hilt/processor/internal/aggregateddeps/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor that aggregates metadata about Hilt @InstallIn annotations +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) # TODO(bcorso): Remove all AggregatedDeps usage from the processor class path.
diff --git a/java/dagger/hilt/processor/internal/aliasof/BUILD b/java/dagger/hilt/processor/internal/aliasof/BUILD index 3c72e71..47776ec 100644 --- a/java/dagger/hilt/processor/internal/aliasof/BUILD +++ b/java/dagger/hilt/processor/internal/aliasof/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.AliasOfProcessor. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/definecomponent/BUILD b/java/dagger/hilt/processor/internal/definecomponent/BUILD index a259b72..4cf5f46 100644 --- a/java/dagger/hilt/processor/internal/definecomponent/BUILD +++ b/java/dagger/hilt/processor/internal/definecomponent/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.DefineComponent. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/disableinstallincheck/BUILD b/java/dagger/hilt/processor/internal/disableinstallincheck/BUILD index b9caf58..766752a 100644 --- a/java/dagger/hilt/processor/internal/disableinstallincheck/BUILD +++ b/java/dagger/hilt/processor/internal/disableinstallincheck/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.AliasOfProcessor. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/earlyentrypoint/BUILD b/java/dagger/hilt/processor/internal/earlyentrypoint/BUILD index 81607e9..c371e8d 100644 --- a/java/dagger/hilt/processor/internal/earlyentrypoint/BUILD +++ b/java/dagger/hilt/processor/internal/earlyentrypoint/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.android.EarlyEntryPoint. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/generatesrootinput/BUILD b/java/dagger/hilt/processor/internal/generatesrootinput/BUILD index afd611f..39c05b6 100644 --- a/java/dagger/hilt/processor/internal/generatesrootinput/BUILD +++ b/java/dagger/hilt/processor/internal/generatesrootinput/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.GeneratesRootInput. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/kotlin/BUILD b/java/dagger/hilt/processor/internal/kotlin/BUILD index 437ea0f..32343ab 100644 --- a/java/dagger/hilt/processor/internal/kotlin/BUILD +++ b/java/dagger/hilt/processor/internal/kotlin/BUILD
@@ -15,13 +15,16 @@ # Description: # Sources related to Kotlin metadata. -load("@rules_java//java:defs.bzl", "java_library") +load("//tools:bazel_compat.bzl", "compat_kt_jvm_library") package(default_visibility = ["//:src"]) -java_library( +compat_kt_jvm_library( name = "kotlin", - srcs = glob(["*.java"]), + srcs = glob([ + "*.java", + "*.kt", + ]), deps = [ "//:dagger_with_compiler", "//java/dagger/hilt/processor/internal:classnames", @@ -33,7 +36,7 @@ "//third_party/java/javapoet", "//third_party/java/jsr305_annotations", "//third_party/java/jsr330_inject", + "//third_party/kotlin/kotlin_metadata_jvm", "@maven//:org_jetbrains_kotlin_kotlin_stdlib", - "@maven//:org_jetbrains_kotlinx_kotlinx_metadata_jvm", ], )
diff --git a/java/dagger/hilt/processor/internal/kotlin/ClassMetadata.kt b/java/dagger/hilt/processor/internal/kotlin/ClassMetadata.kt new file mode 100644 index 0000000..d8ec6bd --- /dev/null +++ b/java/dagger/hilt/processor/internal/kotlin/ClassMetadata.kt
@@ -0,0 +1,100 @@ +/* + * 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.kotlin + +import androidx.room.compiler.processing.XAnnotation +import androidx.room.compiler.processing.XFieldElement +import androidx.room.compiler.processing.XMethodElement +import androidx.room.compiler.processing.XTypeElement +import kotlin.Metadata +import kotlin.metadata.declaresDefaultValue +import kotlin.metadata.KmClass +import kotlin.metadata.KmConstructor +import kotlin.metadata.KmFunction +import kotlin.metadata.KmProperty +import kotlin.metadata.KmValueParameter +import kotlin.metadata.jvm.KotlinClassMetadata +import kotlin.metadata.jvm.fieldSignature +import kotlin.metadata.jvm.getterSignature +import kotlin.metadata.jvm.signature +import kotlin.metadata.jvm.syntheticMethodForAnnotations + +/** Container classes for kotlin metadata types. */ +class ClassMetadata private constructor(private val kmClass: KmClass) { + val functionsBySignature = buildList<FunctionMetadata> { + addAll(kmClass.constructors.map { ConstructorMetadata(it) }) + addAll(kmClass.functions.map { MethodMetadata(it) }) + }.associateBy { it.signature } + + val propertiesBySignature = + kmClass.properties + .filter { it.fieldSignature != null } + .map { PropertyMetadata(it) } + .associateBy { it.fieldSignature } + + fun constructors(): List<FunctionMetadata> = + functionsBySignature.values.filterIsInstance<ConstructorMetadata>() + + companion object { + /** Parse Kotlin class metadata from a given type element. */ + @JvmStatic + fun of(typeElement: XTypeElement): ClassMetadata { + val metadataAnnotation = checkNotNull(typeElement.getAnnotation(Metadata::class)).value + return when (val classMetadata = KotlinClassMetadata.readStrict(metadataAnnotation)) { + is KotlinClassMetadata.Class -> ClassMetadata(classMetadata.kmClass) + else -> error("Unsupported metadata type: ${classMetadata}") + } + } + } +} + +class ConstructorMetadata(private val kmConstructor: KmConstructor) : FunctionMetadata { + override val name = "<init>" + override val signature = kmConstructor.signature!!.toString() + override val parameters = kmConstructor.valueParameters.map { ParameterMetadata(it) } +} + +class MethodMetadata(private val kmFunction: KmFunction) : FunctionMetadata { + override val name = kmFunction.name + override val signature = kmFunction.signature!!.toString() + override val parameters = kmFunction.valueParameters.map { ParameterMetadata(it) } +} + +interface FunctionMetadata { + val name: String + val signature: String + val parameters: List<ParameterMetadata> +} + +class PropertyMetadata(private val kmProperty: KmProperty) { + val name = kmProperty.name + + /** Returns the JVM field descriptor of the backing field of this property. */ + val fieldSignature = kmProperty.fieldSignature?.toString() + + val getterSignature = kmProperty.getterSignature?.toString() + + /** Returns JVM method descriptor of the synthetic method for property annotations. */ + val methodForAnnotationsSignature = kmProperty.syntheticMethodForAnnotations?.toString() +} + +class ParameterMetadata(private val kmValueParameter: KmValueParameter) { + val name = kmValueParameter.name + + fun declaresDefaultValue() = kmValueParameter.declaresDefaultValue +} +
diff --git a/java/dagger/hilt/processor/internal/kotlin/KotlinMetadata.java b/java/dagger/hilt/processor/internal/kotlin/KotlinMetadata.java index e98b2b3..47edf6e 100644 --- a/java/dagger/hilt/processor/internal/kotlin/KotlinMetadata.java +++ b/java/dagger/hilt/processor/internal/kotlin/KotlinMetadata.java
@@ -17,37 +17,20 @@ package dagger.hilt.processor.internal.kotlin; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; -import static kotlinx.metadata.Flag.ValueParameter.DECLARES_DEFAULT_VALUE; -import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XFieldElement; import androidx.room.compiler.processing.XMethodElement; 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.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import dagger.hilt.processor.internal.ClassNames; import dagger.internal.codegen.extension.DaggerCollectors; import dagger.internal.codegen.xprocessing.XElements; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.function.Function; import javax.annotation.Nullable; -import kotlin.Metadata; -import kotlinx.metadata.Flag; -import kotlinx.metadata.KmClass; -import kotlinx.metadata.KmConstructor; -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.KmProperty; -import kotlinx.metadata.jvm.JvmExtensionsKt; -import kotlinx.metadata.jvm.JvmFieldSignature; -import kotlinx.metadata.jvm.JvmMetadataUtil; -import kotlinx.metadata.jvm.JvmMethodSignature; -import kotlinx.metadata.jvm.KotlinClassMetadata; /** Data class of a TypeElement and its Kotlin metadata. */ @AutoValue @@ -79,8 +62,8 @@ @Memoized boolean containsConstructorWithDefaultParam() { return classMetadata().constructors().stream() - .flatMap(constructor -> constructor.parameters().stream()) - .anyMatch(parameter -> parameter.flags(DECLARES_DEFAULT_VALUE)); + .flatMap(constructor -> constructor.getParameters().stream()) + .anyMatch(parameter -> parameter.declaresDefaultValue()); } /** Gets the synthetic method for annotations of a given field element. */ @@ -102,8 +85,7 @@ } private Optional<MethodForAnnotations> getAnnotationMethodUncached(XFieldElement fieldElement) { - return findProperty(fieldElement) - .methodForAnnotationsSignature() + return Optional.ofNullable(findProperty(fieldElement).getMethodForAnnotationsSignature()) .map( signature -> Optional.ofNullable(methodDescriptors().get(signature)) @@ -120,20 +102,19 @@ } private Optional<XMethodElement> getPropertyGetterUncached(XFieldElement fieldElement) { - return findProperty(fieldElement) - .getterSignature() + return Optional.ofNullable(findProperty(fieldElement).getGetterSignature()) .flatMap(signature -> Optional.ofNullable(methodDescriptors().get(signature))); } private PropertyMetadata findProperty(XFieldElement field) { String fieldDescriptor = field.getJvmDescriptor(); - if (classMetadata().propertiesByFieldSignature().containsKey(fieldDescriptor)) { - return classMetadata().propertiesByFieldSignature().get(fieldDescriptor); + if (classMetadata().getPropertiesBySignature().containsKey(fieldDescriptor)) { + return classMetadata().getPropertiesBySignature().get(fieldDescriptor); } else { // Fallback to finding property by name, see: https://youtrack.jetbrains.com/issue/KT-35124 final String propertyName = getPropertyNameFromField(field); - return classMetadata().propertiesByFieldSignature().values().stream() - .filter(property -> propertyName.contentEquals(property.name())) + return classMetadata().getPropertiesBySignature().values().stream() + .filter(property -> propertyName.contentEquals(property.getName())) // SUPPRESS_GET_NAME_CHECK .collect(DaggerCollectors.onlyElement()); } } @@ -149,204 +130,7 @@ /** Parse Kotlin class metadata from a given type element. */ static KotlinMetadata from(XTypeElement typeElement) { - return new AutoValue_KotlinMetadata(typeElement, ClassMetadata.create(metadataOf(typeElement))); - } - - private static KotlinClassMetadata.Class metadataOf(XTypeElement typeElement) { - XAnnotation annotation = typeElement.getAnnotation(ClassNames.KOTLIN_METADATA); - Metadata metadataAnnotation = - JvmMetadataUtil.Metadata( - annotation.getAsInt("k"), - annotation.getAsIntList("mv").stream().mapToInt(Integer::intValue).toArray(), - annotation.getAsStringList("d1").toArray(new String[0]), - annotation.getAsStringList("d2").toArray(new String[0]), - annotation.getAsString("xs"), - getOptionalStringValue(annotation, "pn").orElse(null), - getOptionalIntValue(annotation, "xi").orElse(null)); - KotlinClassMetadata metadata = KotlinClassMetadata.read(metadataAnnotation); - if (metadata == null) { - // Can happen if Kotlin < 1.0 or if metadata version is not supported, i.e. - // kotlinx-metadata-jvm is outdated. - throw new IllegalStateException( - "Unable to read Kotlin metadata due to unsupported metadata version."); - } - if (metadata instanceof KotlinClassMetadata.Class) { - // TODO(danysantiago): If when we need other types of metadata then move to right method. - return (KotlinClassMetadata.Class) metadata; - } else { - throw new IllegalStateException("Unsupported metadata type: " + metadata); - } - } - - @AutoValue - abstract static class ClassMetadata extends BaseMetadata { - abstract Optional<String> companionObjectName(); - - abstract ImmutableSet<FunctionMetadata> constructors(); - - abstract ImmutableMap<String, FunctionMetadata> functionsBySignature(); - - abstract ImmutableMap<String, PropertyMetadata> propertiesByFieldSignature(); - - static ClassMetadata create(KotlinClassMetadata.Class metadata) { - KmClass kmClass = metadata.toKmClass(); - ClassMetadata.Builder builder = ClassMetadata.builder(kmClass.getFlags(), kmClass.getName()); - builder.companionObjectName(Optional.ofNullable(kmClass.getCompanionObject())); - kmClass.getConstructors().forEach(it -> builder.addConstructor(FunctionMetadata.create(it))); - kmClass.getFunctions().forEach(it -> builder.addFunction(FunctionMetadata.create(it))); - kmClass.getProperties().forEach(it -> builder.addProperty(PropertyMetadata.create(it))); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_ClassMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - abstract static class Builder implements BaseMetadata.Builder<Builder> { - abstract Builder companionObjectName(Optional<String> companionObjectName); - - abstract ImmutableSet.Builder<FunctionMetadata> constructorsBuilder(); - - abstract ImmutableMap.Builder<String, FunctionMetadata> functionsBySignatureBuilder(); - - abstract ImmutableMap.Builder<String, PropertyMetadata> propertiesByFieldSignatureBuilder(); - - Builder addConstructor(FunctionMetadata constructor) { - constructorsBuilder().add(constructor); - functionsBySignatureBuilder().put(constructor.signature(), constructor); - return this; - } - - Builder addFunction(FunctionMetadata function) { - functionsBySignatureBuilder().put(function.signature(), function); - return this; - } - - Builder addProperty(PropertyMetadata property) { - if (property.fieldSignature().isPresent()) { - propertiesByFieldSignatureBuilder().put(property.fieldSignature().get(), property); - } - return this; - } - - abstract ClassMetadata build(); - } - } - - @AutoValue - abstract static class FunctionMetadata extends BaseMetadata { - abstract String signature(); - - abstract ImmutableList<ValueParameterMetadata> parameters(); - - static FunctionMetadata create(KmConstructor metadata) { - FunctionMetadata.Builder builder = FunctionMetadata.builder(metadata.getFlags(), "<init>"); - metadata - .getValueParameters() - .forEach( - it -> - builder.addParameter(ValueParameterMetadata.create(it.getFlags(), it.getName()))); - builder.signature(Objects.requireNonNull(JvmExtensionsKt.getSignature(metadata)).asString()); - return builder.build(); - } - - static FunctionMetadata create(KmFunction metadata) { - FunctionMetadata.Builder builder = - FunctionMetadata.builder(metadata.getFlags(), metadata.getName()); - metadata - .getValueParameters() - .forEach( - it -> - builder.addParameter(ValueParameterMetadata.create(it.getFlags(), it.getName()))); - builder.signature(Objects.requireNonNull(JvmExtensionsKt.getSignature(metadata)).asString()); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_FunctionMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - abstract static class Builder implements BaseMetadata.Builder<Builder> { - abstract Builder signature(String signature); - - abstract ImmutableList.Builder<ValueParameterMetadata> parametersBuilder(); - - Builder addParameter(ValueParameterMetadata parameter) { - parametersBuilder().add(parameter); - return this; - } - - abstract FunctionMetadata build(); - } - } - - @AutoValue - abstract static class PropertyMetadata extends BaseMetadata { - /** Returns the JVM field descriptor of the backing field of this property. */ - abstract Optional<String> fieldSignature(); - - abstract Optional<String> getterSignature(); - - /** Returns JVM method descriptor of the synthetic method for property annotations. */ - abstract Optional<String> methodForAnnotationsSignature(); - - static PropertyMetadata create(KmProperty metadata) { - PropertyMetadata.Builder builder = - PropertyMetadata.builder(metadata.getFlags(), metadata.getName()); - builder.fieldSignature( - Optional.ofNullable(JvmExtensionsKt.getFieldSignature(metadata)) - .map(JvmFieldSignature::asString)); - builder.getterSignature( - Optional.ofNullable(JvmExtensionsKt.getGetterSignature(metadata)) - .map(JvmMethodSignature::asString)); - builder.methodForAnnotationsSignature( - Optional.ofNullable(JvmExtensionsKt.getSyntheticMethodForAnnotations(metadata)) - .map(JvmMethodSignature::asString)); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_PropertyMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - interface Builder extends BaseMetadata.Builder<Builder> { - Builder fieldSignature(Optional<String> signature); - - Builder getterSignature(Optional<String> signature); - - Builder methodForAnnotationsSignature(Optional<String> signature); - - PropertyMetadata build(); - } - } - - @AutoValue - abstract static class ValueParameterMetadata extends BaseMetadata { - private static ValueParameterMetadata create(int flags, String name) { - return new AutoValue_KotlinMetadata_ValueParameterMetadata(flags, name); - } - } - - abstract static class BaseMetadata { - /** Returns the Kotlin metadata flags for this property. */ - abstract int flags(); - - /** returns {@code true} if the given flag (e.g. {@link Flag.IS_PRIVATE}) applies. */ - boolean flags(Flag flag) { - return flag.invoke(flags()); - } - - /** Returns the simple name of this property. */ - abstract String name(); - - interface Builder<BuilderT> { - BuilderT flags(int flags); - - BuilderT name(String name); - } + return new AutoValue_KotlinMetadata(typeElement, ClassMetadata.of(typeElement)); } @AutoValue @@ -360,21 +144,4 @@ @Nullable abstract XMethodElement method(); } - - private static Optional<Integer> getOptionalIntValue(XAnnotation annotation, String valueName) { - return isValuePresent(annotation, valueName) - ? Optional.of(annotation.getAsInt(valueName)) - : Optional.empty(); - } - - private static Optional<String> getOptionalStringValue(XAnnotation annotation, String valueName) { - return isValuePresent(annotation, valueName) - ? Optional.of(annotation.getAsString(valueName)) - : Optional.empty(); - } - - private static boolean isValuePresent(XAnnotation annotation, String valueName) { - return annotation.getAnnotationValues().stream() - .anyMatch(member -> member.getName().equals(valueName)); - } }
diff --git a/java/dagger/hilt/processor/internal/originatingelement/BUILD b/java/dagger/hilt/processor/internal/originatingelement/BUILD index f4a279a..de0be5f 100644 --- a/java/dagger/hilt/processor/internal/originatingelement/BUILD +++ b/java/dagger/hilt/processor/internal/originatingelement/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.codegen.OriginatingElement. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/root/BUILD b/java/dagger/hilt/processor/internal/root/BUILD index a132b1c..8c235fb 100644 --- a/java/dagger/hilt/processor/internal/root/BUILD +++ b/java/dagger/hilt/processor/internal/root/BUILD
@@ -15,6 +15,8 @@ # Description: # Annotation processor for Hilt. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/processor/internal/root/ir/BUILD b/java/dagger/hilt/processor/internal/root/ir/BUILD index 4bc1a29..33f5803 100644 --- a/java/dagger/hilt/processor/internal/root/ir/BUILD +++ b/java/dagger/hilt/processor/internal/root/ir/BUILD
@@ -16,7 +16,7 @@ # A library containing intermediate representations of the various Hilt # aggregating annotations along with logic to process them. -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package(default_visibility = ["//:src"])
diff --git a/java/dagger/hilt/processor/internal/uninstallmodules/BUILD b/java/dagger/hilt/processor/internal/uninstallmodules/BUILD index 818abbc..cd6baed 100644 --- a/java/dagger/hilt/processor/internal/uninstallmodules/BUILD +++ b/java/dagger/hilt/processor/internal/uninstallmodules/BUILD
@@ -15,6 +15,8 @@ # Description: # A processor for @dagger.hilt.android.testing.UninstallModules. +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") + package(default_visibility = ["//:src"]) java_plugin(
diff --git a/java/dagger/hilt/testing/BUILD b/java/dagger/hilt/testing/BUILD index 59a1e94..54080e6 100644 --- a/java/dagger/hilt/testing/BUILD +++ b/java/dagger/hilt/testing/BUILD
@@ -15,6 +15,8 @@ # Description: # Testing libraries for Hilt. +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/internal/DaggerCollections.java b/java/dagger/internal/DaggerCollections.java index cebca42..e4e70f0 100644 --- a/java/dagger/internal/DaggerCollections.java +++ b/java/dagger/internal/DaggerCollections.java
@@ -22,6 +22,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Set; +import org.jspecify.annotations.Nullable; /** * Collection utility methods in service of Dagger internal classes. <em>Do not use</em> in client @@ -47,14 +48,12 @@ return new ArrayList<T>(size); } - /** - * Returns true if at least one pair of items in {@code list} are equals. - */ - public static boolean hasDuplicates(List<?> list) { + /** Returns true if at least one pair of items in {@code list} are equals. */ + public static <T extends @Nullable Object> boolean hasDuplicates(List<T> list) { if (list.size() < 2) { return false; } - Set<Object> asSet = new HashSet<Object>(list); + Set<T> asSet = new HashSet<T>(list); return list.size() != asSet.size(); }
diff --git a/java/dagger/internal/DelegateFactory.java b/java/dagger/internal/DelegateFactory.java index bc5cd9a..93dccf5 100644 --- a/java/dagger/internal/DelegateFactory.java +++ b/java/dagger/internal/DelegateFactory.java
@@ -19,13 +19,16 @@ import static dagger.internal.Preconditions.checkNotNull; import static dagger.internal.Providers.asDaggerProvider; +import org.jspecify.annotations.Nullable; + /** * 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> { - private Provider<T> delegate; + + private @Nullable Provider<T> delegate; @Override public T get() {
diff --git a/java/dagger/internal/DoubleCheck.java b/java/dagger/internal/DoubleCheck.java index 6af8661..af82b7a 100644 --- a/java/dagger/internal/DoubleCheck.java +++ b/java/dagger/internal/DoubleCheck.java
@@ -20,16 +20,17 @@ import static dagger.internal.Providers.asDaggerProvider; import dagger.Lazy; +import org.jspecify.annotations.Nullable; /** * A {@link Lazy} and {@link Provider} implementation that memoizes the value returned from a * delegate using the double-check idiom described in Item 71 of <i>Effective Java 2</i>. */ -public final class DoubleCheck<T> implements Provider<T>, Lazy<T> { +public final class DoubleCheck<T extends @Nullable Object> implements Provider<T>, Lazy<T> { private static final Object UNINITIALIZED = new Object(); - private volatile Provider<T> provider; - private volatile Object instance = UNINITIALIZED; + private volatile @Nullable Provider<T> provider; + private volatile @Nullable Object instance = UNINITIALIZED; private DoubleCheck(Provider<T> provider) { assert provider != null; @@ -39,28 +40,33 @@ @SuppressWarnings("unchecked") // cast only happens when result comes from the provider @Override public T get() { - Object result = instance; + @Nullable Object result = instance; if (result == UNINITIALIZED) { - synchronized (this) { - result = instance; - if (result == UNINITIALIZED) { - result = provider.get(); - instance = reentrantCheck(instance, result); - /* Null out the reference to the provider. We are never going to need it again, so we - * can make it eligible for GC. */ - provider = null; - } - } + result = getSynchronized(); } return (T) result; } + @SuppressWarnings("nullness:dereference.of.nullable") // provider is non-null + private synchronized @Nullable Object getSynchronized() { + @Nullable Object result = instance; + if (result == UNINITIALIZED) { + result = provider.get(); + instance = reentrantCheck(instance, result); + /* Null out the reference to the provider. We are never going to need it again, so we + * can make it eligible for GC. */ + provider = null; + } + return result; + } + /** * Checks to see if creating the new instance has resulted in a recursive call. If it has, and the * new instance is the same as the current instance, return the instance. However, if the new * instance differs from the current instance, an {@link IllegalStateException} is thrown. */ - private static Object reentrantCheck(Object currentInstance, Object newInstance) { + private static @Nullable Object reentrantCheck( + @Nullable Object currentInstance, @Nullable Object newInstance) { boolean isReentrant = currentInstance != UNINITIALIZED; if (isReentrant && currentInstance != newInstance) { throw new IllegalStateException("Scoped provider was invoked recursively returning " @@ -71,10 +77,7 @@ } /** 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 dagger.internal.Provider<T>, T> dagger.internal.Provider<T> provider( - P delegate) { + public static <T> dagger.internal.Provider<T> provider(dagger.internal.Provider<T> 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 @@ -95,9 +98,7 @@ } /** 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. - public static <P extends Provider<T>, T> Lazy<T> lazy(P provider) { + public static <T> Lazy<T> lazy(Provider<T> provider) { if (provider instanceof Lazy) { @SuppressWarnings("unchecked") final Lazy<T> lazy = (Lazy<T>) provider;
diff --git a/java/dagger/internal/Factory.java b/java/dagger/internal/Factory.java index 73bcfbc..41c4353 100644 --- a/java/dagger/internal/Factory.java +++ b/java/dagger/internal/Factory.java
@@ -19,6 +19,7 @@ import dagger.Provides; import javax.inject.Inject; import javax.inject.Scope; +import org.jspecify.annotations.Nullable; /** * An {@linkplain Scope unscoped} {@link Provider}. While a {@link Provider} <i>may</i> apply @@ -31,5 +32,4 @@ * bindings. For example, {@link Provides} methods may be implemented in ways that return the same * instance for each call. */ -public interface Factory<T> extends Provider<T> { -} +public interface Factory<T extends @Nullable Object> extends Provider<T> {}
diff --git a/java/dagger/internal/InstanceFactory.java b/java/dagger/internal/InstanceFactory.java index 3156fe8..96490f0 100644 --- a/java/dagger/internal/InstanceFactory.java +++ b/java/dagger/internal/InstanceFactory.java
@@ -19,6 +19,7 @@ import static dagger.internal.Preconditions.checkNotNull; import dagger.Lazy; +import org.jspecify.annotations.Nullable; /** * A {@link Factory} implementation that returns a single instance for all invocations of {@link @@ -29,24 +30,24 @@ * is redundant and unnecessary. However, using this with {@link DoubleCheck#provider} is valid and * may be desired for testing or contractual guarantees. */ -public final class InstanceFactory<T> implements Factory<T>, Lazy<T> { +public final class InstanceFactory<T extends @Nullable Object> implements Factory<T>, Lazy<T> { public static <T> Factory<T> create(T instance) { return new InstanceFactory<T>(checkNotNull(instance, "instance cannot be null")); } - public static <T> Factory<T> createNullable(T instance) { + public static <T extends @Nullable Object> Factory<T> createNullable(T instance) { return instance == null ? InstanceFactory.<T>nullInstanceFactory() : new InstanceFactory<T>(instance); } @SuppressWarnings("unchecked") // bivariant implementation - private static <T> InstanceFactory<T> nullInstanceFactory() { + private static <T extends @Nullable Object> InstanceFactory<T> nullInstanceFactory() { return (InstanceFactory<T>) NULL_INSTANCE_FACTORY; } - private static final InstanceFactory<Object> NULL_INSTANCE_FACTORY = - new InstanceFactory<Object>(null); + private static final InstanceFactory<@Nullable Object> NULL_INSTANCE_FACTORY = + new InstanceFactory<@Nullable Object>(null); private final T instance;
diff --git a/java/dagger/internal/LazyClassKeyMap.java b/java/dagger/internal/LazyClassKeyMap.java index dabf86f..eec7909 100644 --- a/java/dagger/internal/LazyClassKeyMap.java +++ b/java/dagger/internal/LazyClassKeyMap.java
@@ -19,6 +19,8 @@ import java.util.Collection; import java.util.Map; import java.util.Set; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; /** * A class keyed map that delegates to a string keyed map under the hood. @@ -37,11 +39,11 @@ } @Override - public V get(Object key) { + public V get(@Nullable Object key) { if (!(key instanceof Class)) { throw new IllegalArgumentException("Key must be a class"); } - return delegate.get(((Class<?>) key).getName()); + return (@NonNull V) delegate.get(((Class<?>) key).getName()); } @Override @@ -64,7 +66,7 @@ } @Override - public boolean containsKey(Object key) { + public boolean containsKey(@Nullable Object key) { if (!(key instanceof Class)) { throw new IllegalArgumentException("Key must be a class"); } @@ -72,7 +74,7 @@ } @Override - public boolean containsValue(Object value) { + public boolean containsValue(@Nullable Object value) { return delegate.containsValue(value); } @@ -92,7 +94,7 @@ // The dagger map binding should be a immutable map. @Override - public V remove(Object key) { + public V remove(@Nullable Object key) { throw new UnsupportedOperationException("Dagger map bindings are immutable"); } @@ -111,15 +113,15 @@ 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; + /** Wrapper around {@link MapFactory}. */ + public static class MapFactory<V> implements Factory<Map<Class<?>, V>> { + Factory<Map<String, V>> delegate; - public static <V> Factory<V> of(MapFactory<String, V> delegate) { - return new Factory<>(delegate); + public static <V> MapFactory<V> of(Factory<Map<String, V>> delegate) { + return new MapFactory<V>(delegate); } - private Factory(MapFactory<String, V> delegate) { + private MapFactory(Factory<Map<String, V>> delegate) { this.delegate = delegate; } @@ -128,4 +130,22 @@ return LazyClassKeyMap.of(delegate.get()); } } + + /** Wrapper around for {@link MapProviderFactory}. */ + public static class MapProviderFactory<V> implements Factory<Map<Class<?>, Provider<V>>> { + Factory<Map<String, Provider<V>>> delegate; + + public static <V> MapProviderFactory<V> of(Factory<Map<String, Provider<V>>> delegate) { + return new MapProviderFactory<V>(delegate); + } + + private MapProviderFactory(Factory<Map<String, Provider<V>>> delegate) { + this.delegate = delegate; + } + + @Override + public Map<Class<?>, Provider<V>> get() { + return LazyClassKeyMap.of(delegate.get()); + } + } }
diff --git a/java/dagger/internal/Preconditions.java b/java/dagger/internal/Preconditions.java index d21e594..2a1ef05 100644 --- a/java/dagger/internal/Preconditions.java +++ b/java/dagger/internal/Preconditions.java
@@ -16,6 +16,7 @@ package dagger.internal; +import org.jspecify.annotations.Nullable; /** * An adaptation of Guava's {@code com.google.common.base.Preconditions} that is specially tailored @@ -29,7 +30,7 @@ * @return the non-null reference that was validated * @throws NullPointerException if {@code reference} is null */ - public static <T> T checkNotNull(T reference) { + public static <T> T checkNotNull(@Nullable T reference) { if (reference == null) { throw new NullPointerException(); } @@ -106,9 +107,10 @@ "errorMessageTemplate has more than one format specifier"); } String argString = - errorMessageArg instanceof Class - ? ((Class) errorMessageArg).getCanonicalName() - : String.valueOf(errorMessageArg); + String.valueOf( + errorMessageArg instanceof Class + ? ((Class) errorMessageArg).getCanonicalName() + : errorMessageArg); throw new NullPointerException(errorMessageTemplate.replace("%s", argString)); } return reference;
diff --git a/java/dagger/internal/Provider.java b/java/dagger/internal/Provider.java index e388601..5732045 100644 --- a/java/dagger/internal/Provider.java +++ b/java/dagger/internal/Provider.java
@@ -16,10 +16,11 @@ package dagger.internal; +import org.jspecify.annotations.Nullable; + /** - * 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. + * 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> { -} +public interface Provider<T extends @Nullable Object> + extends javax.inject.Provider<T>, jakarta.inject.Provider<T> {}
diff --git a/java/dagger/internal/Providers.java b/java/dagger/internal/Providers.java index 60ec83f..bf164eb 100644 --- a/java/dagger/internal/Providers.java +++ b/java/dagger/internal/Providers.java
@@ -18,12 +18,19 @@ import static dagger.internal.Preconditions.checkNotNull; +import org.jspecify.annotations.Nullable; + /** 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) { + @SuppressWarnings("unchecked") + public static <T extends @Nullable Object> Provider<T> asDaggerProvider( + final javax.inject.Provider<T> provider) { checkNotNull(provider); + if (provider instanceof Provider) { + return (Provider) provider; + } return new Provider<T>() { @Override public T get() { return provider.get();
diff --git a/java/dagger/internal/SingleCheck.java b/java/dagger/internal/SingleCheck.java index 32ba83a..0b0273f 100644 --- a/java/dagger/internal/SingleCheck.java +++ b/java/dagger/internal/SingleCheck.java
@@ -19,15 +19,17 @@ import static dagger.internal.Preconditions.checkNotNull; import static dagger.internal.Providers.asDaggerProvider; +import org.jspecify.annotations.Nullable; + /** * A {@link Provider} implementation that memoizes the result of another {@link Provider} using * simple lazy initialization, not the double-checked lock pattern. */ -public final class SingleCheck<T> implements Provider<T> { +public final class SingleCheck<T extends @Nullable Object> implements Provider<T> { private static final Object UNINITIALIZED = new Object(); - private volatile Provider<T> provider; - private volatile Object instance = UNINITIALIZED; + private volatile @Nullable Provider<T> provider; + private volatile @Nullable Object instance = UNINITIALIZED; private SingleCheck(Provider<T> provider) { assert provider != null; @@ -37,10 +39,10 @@ @SuppressWarnings("unchecked") // cast only happens when result comes from the delegate provider @Override public T get() { - Object local = instance; + @Nullable Object local = instance; if (local == UNINITIALIZED) { // provider is volatile and might become null after the check, so retrieve the provider first - Provider<T> providerReference = provider; + @Nullable Provider<T> providerReference = provider; if (providerReference == null) { // The provider was null, so the instance must already be set local = instance; @@ -57,9 +59,7 @@ } /** 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)" - // 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) { + public static <T> Provider<T> provider(Provider<T> provider) { // If a scoped @Binds delegates to a scoped binding, don't cache the value again. if (provider instanceof SingleCheck || provider instanceof DoubleCheck) { return provider;
diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD index 80ca8d7..2de6ffc 100644 --- a/java/dagger/internal/codegen/BUILD +++ b/java/dagger/internal/codegen/BUILD
@@ -20,7 +20,7 @@ "//:build_defs.bzl", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"])
diff --git a/java/dagger/internal/codegen/ComponentProcessor.java b/java/dagger/internal/codegen/ComponentProcessor.java index 2a68a4b..e97493c 100644 --- a/java/dagger/internal/codegen/ComponentProcessor.java +++ b/java/dagger/internal/codegen/ComponentProcessor.java
@@ -120,6 +120,11 @@ } @Override + public void preRound(XProcessingEnv env, XRoundEnv roundEnv) { + delegate.onProcessingRoundBegin(); + } + + @Override public void postRound(XProcessingEnv env, XRoundEnv roundEnv) { delegate.postRound(env, roundEnv); }
diff --git a/java/dagger/internal/codegen/DelegateComponentProcessor.java b/java/dagger/internal/codegen/DelegateComponentProcessor.java index 432daa6..754b4d9 100644 --- a/java/dagger/internal/codegen/DelegateComponentProcessor.java +++ b/java/dagger/internal/codegen/DelegateComponentProcessor.java
@@ -33,14 +33,13 @@ 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.ContributionBinding; 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; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.componentgenerator.ComponentGeneratorModule; @@ -74,7 +73,7 @@ new XProcessingEnvConfig.Builder().disableAnnotatedElementValidation(true).build(); @Inject InjectBindingRegistry injectBindingRegistry; - @Inject SourceFileGenerator<ProvisionBinding> factoryGenerator; + @Inject SourceFileGenerator<ContributionBinding> factoryGenerator; @Inject SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator; @Inject ImmutableList<XProcessingStep> processingSteps; @Inject ValidationBindingGraphPlugins validationBindingGraphPlugins; @@ -108,15 +107,19 @@ DaggerDelegateComponentProcessor_Injector.factory() .create(env, plugins, legacyPlugins) .inject(this); + validationBindingGraphPlugins.initializePlugins(); + externalBindingGraphPlugins.initializePlugins(); } public Iterable<XProcessingStep> processingSteps() { - validationBindingGraphPlugins.initializePlugins(); - externalBindingGraphPlugins.initializePlugins(); return processingSteps; } + public void onProcessingRoundBegin() { + externalBindingGraphPlugins.onProcessingRoundBegin(); + } + public void postRound(XProcessingEnv env, XRoundEnv roundEnv) { if (!roundEnv.isProcessingOver()) { try { @@ -182,10 +185,6 @@ @Binds @IntoSet - ClearableCache bindingGraphFactory(BindingGraphFactory cache); - - @Binds - @IntoSet ClearableCache componentValidator(ComponentValidator cache); @Binds @@ -200,7 +199,7 @@ @Module interface SourceFileGeneratorsModule { @Provides - static SourceFileGenerator<ProvisionBinding> factoryGenerator( + static SourceFileGenerator<ContributionBinding> factoryGenerator( FactoryGenerator generator, CompilerOptions compilerOptions, XProcessingEnv processingEnv) {
diff --git a/java/dagger/internal/codegen/KspComponentProcessor.java b/java/dagger/internal/codegen/KspComponentProcessor.java index 8b07f93..5fc6363 100644 --- a/java/dagger/internal/codegen/KspComponentProcessor.java +++ b/java/dagger/internal/codegen/KspComponentProcessor.java
@@ -59,6 +59,11 @@ } @Override + public void preRound(XProcessingEnv env, XRoundEnv roundEnv) { + delegate.onProcessingRoundBegin(); + } + + @Override public void postRound(XProcessingEnv env, XRoundEnv roundEnv) { delegate.postRound(env, roundEnv); }
diff --git a/java/dagger/internal/codegen/ServiceLoaders.java b/java/dagger/internal/codegen/ServiceLoaders.java index 95773fa..974f36e 100644 --- a/java/dagger/internal/codegen/ServiceLoaders.java +++ b/java/dagger/internal/codegen/ServiceLoaders.java
@@ -30,8 +30,6 @@ /** * Returns the loaded services for the given class. - * - * <p>Note: This should only be called in Javac. This method will throw if called in KSP. */ static <T> ImmutableSet<T> loadServices(XProcessingEnv processingEnv, Class<T> clazz) { return ImmutableSet.copyOf(ServiceLoader.load(clazz, classLoaderFor(processingEnv, clazz)));
diff --git a/java/dagger/internal/codegen/base/FrameworkTypes.java b/java/dagger/internal/codegen/base/FrameworkTypes.java index e39aeab..04eaf2e 100644 --- a/java/dagger/internal/codegen/base/FrameworkTypes.java +++ b/java/dagger/internal/codegen/base/FrameworkTypes.java
@@ -31,7 +31,11 @@ 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); + ImmutableSet.of( + TypeNames.PROVIDER, + TypeNames.JAKARTA_PROVIDER, + TypeNames.LAZY, + TypeNames.MEMBERS_INJECTOR); // NOTE(beder): ListenableFuture is not considered a producer framework type because it is not // defined by the framework, so we can't treat it specially in ordinary Dagger. @@ -41,6 +45,22 @@ private static final ImmutableSet<ClassName> ALL_FRAMEWORK_TYPES = ImmutableSet.<ClassName>builder().addAll(PROVISION_TYPES).addAll(PRODUCTION_TYPES).build(); + public static final ImmutableSet<ClassName> SET_VALUE_FRAMEWORK_TYPES = + ImmutableSet.of(TypeNames.PRODUCED); + + public static final ImmutableSet<ClassName> MAP_VALUE_FRAMEWORK_TYPES = + ImmutableSet.of( + TypeNames.PRODUCED, + TypeNames.PRODUCER, + TypeNames.PROVIDER, + TypeNames.JAKARTA_PROVIDER); + + // This is a set of types that are disallowed from use, but also aren't framework types in the + // sense that they aren't supported. Like we shouldn't try to unwrap these if we see them, though + // we shouldn't see them at all if they are correctly caught in validation. + private static final ImmutableSet<ClassName> DISALLOWED_TYPES = + ImmutableSet.of(TypeNames.DAGGER_PROVIDER); + /** Returns true if the type represents a producer-related framework type. */ public static boolean isProducerType(XType type) { return typeIsOneOf(PRODUCTION_TYPES, type); @@ -51,6 +71,18 @@ return typeIsOneOf(ALL_FRAMEWORK_TYPES, type); } + public static boolean isSetValueFrameworkType(XType type) { + return typeIsOneOf(SET_VALUE_FRAMEWORK_TYPES, type); + } + + public static boolean isMapValueFrameworkType(XType type) { + return typeIsOneOf(MAP_VALUE_FRAMEWORK_TYPES, type); + } + + public static boolean isDisallowedType(XType type) { + return typeIsOneOf(DISALLOWED_TYPES, type); + } + private static boolean typeIsOneOf(Set<ClassName> classNames, XType type) { return classNames.stream().anyMatch(className -> isTypeOf(type, className)); }
diff --git a/java/dagger/internal/codegen/base/MapType.java b/java/dagger/internal/codegen/base/MapType.java index c4ba838..ba4b1e7 100644 --- a/java/dagger/internal/codegen/base/MapType.java +++ b/java/dagger/internal/codegen/base/MapType.java
@@ -23,15 +23,24 @@ import androidx.room.compiler.processing.XType; import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.TypeName; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.xprocessing.XTypes; /** Information about a {@link java.util.Map} type. */ @AutoValue public abstract class MapType { + // TODO(b/28555349): support PROVIDER_OF_LAZY here too + // TODO(b/376124787): We could consolidate this with a similar list in FrameworkTypes + // if we had a better way to go from RequestKind to framework ClassName or vice versa + /** The valid framework request kinds allowed on a multibinding map value. */ + private static final ImmutableSet<RequestKind> VALID_FRAMEWORK_REQUEST_KINDS = + ImmutableSet.of(RequestKind.PROVIDER, RequestKind.PRODUCER, RequestKind.PRODUCED); + private XType type; /** The map type itself. */ @@ -74,35 +83,45 @@ /** Returns {@code true} if the raw type of {@link #valueType()} is a framework type. */ public boolean valuesAreFrameworkType() { - return FrameworkTypes.isFrameworkType(valueType()); + return valueRequestKind() != RequestKind.INSTANCE; } /** - * {@code V} if {@link #valueType()} is a framework type like {@code Provider<V>} or {@code - * Producer<V>}. + * Returns the map's {@link #valueType()} without any wrapping framework type, if one exists. * - * @throws IllegalStateException if {@link #isRawType()} is true or {@link #valueType()} is not a - * framework type + * <p>In particular, this method returns {@code V} for all of the following map types: + * {@code Map<K,V>}, {@code Map<K,Provider<V>>}, {@code Map<K,Producer<V>>}, and + * {@code Map<K,Produced<V>>}. + * + * <p>Note that we don't consider {@code Lazy} a framework type for this particular case, so this + * method will return {@code Lazy<V>} for {@code Map<K,Lazy<V>>}. + * + * @throws IllegalStateException if {@link #isRawType()} is true. */ public XType unwrappedFrameworkValueType() { - checkState(valuesAreFrameworkType(), "called unwrappedFrameworkValueType() on %s", type()); - return uncheckedUnwrappedValueType(); + return valuesAreFrameworkType() ? unwrapType(valueType()) : valueType(); } /** - * {@code V} if {@link #valueType()} is a {@code WrappingClass<V>}. + * Returns the {@link RequestKind} of the {@link #valueType()}. * - * @throws IllegalStateException if {@link #isRawType()} is true or {@link #valueType()} is not a - * {@code WrappingClass<V>} + * @throws IllegalArgumentException if {@link #isRawType()} is true. */ - // TODO(b/202033221): Consider using stricter input type, e.g. FrameworkType. - public XType unwrappedValueType(ClassName wrappingClass) { - checkState(valuesAreTypeOf(wrappingClass), "expected values to be %s: %s", wrappingClass, this); - return uncheckedUnwrappedValueType(); - } - - private XType uncheckedUnwrappedValueType() { - return unwrapType(valueType()); + public RequestKind valueRequestKind() { + checkArgument(!isRawType()); + RequestKind requestKind = RequestKinds.getRequestKind(valueType()); + if (VALID_FRAMEWORK_REQUEST_KINDS.contains(requestKind)) { + return requestKind; + } else if (requestKind == RequestKind.PROVIDER_OF_LAZY) { + // This is kind of a weird case. We don't support Map<K, Lazy<V>>, so we also don't support + // Map<K, Provider<Lazy<V>>> directly. However, if the user bound that themselves, we don't + // want that to get confused as a normal instance request, so return PROVIDER here. + return RequestKind.PROVIDER; + } else { + // Not all RequestKinds are supported, so if there's a map value that matches an unsupported + // RequestKind, just treat it like it is a normal instance request. + return RequestKind.INSTANCE; + } } /** {@code true} if {@code type} is a {@link java.util.Map} type. */
diff --git a/java/dagger/internal/codegen/base/RequestKinds.java b/java/dagger/internal/codegen/base/RequestKinds.java index a9c7e83..fdf1c20 100644 --- a/java/dagger/internal/codegen/base/RequestKinds.java +++ b/java/dagger/internal/codegen/base/RequestKinds.java
@@ -39,6 +39,11 @@ import com.squareup.javapoet.ClassName; import com.squareup.javapoet.TypeName; import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.model.Binding; +import dagger.internal.codegen.model.BindingGraph; +import dagger.internal.codegen.model.BindingGraph.ComponentNode; +import dagger.internal.codegen.model.BindingGraph.DependencyEdge; +import dagger.internal.codegen.model.BindingGraph.Node; import dagger.internal.codegen.model.RequestKind; /** Utility methods for {@link RequestKind}s. */ @@ -92,6 +97,8 @@ private static final ImmutableMap<RequestKind, ClassName> FRAMEWORK_CLASSES = ImmutableMap.of( + // Default to the javax Provider since that is what is used for the binding graph + // representation. PROVIDER, TypeNames.PROVIDER, LAZY, TypeNames.LAZY, PRODUCER, TypeNames.PRODUCER, @@ -106,10 +113,15 @@ return RequestKind.INSTANCE; } - if (isTypeOf(type, TypeNames.PROVIDER) && isTypeOf(unwrapType(type), TypeNames.LAZY)) { + if ((isTypeOf(type, TypeNames.PROVIDER) || isTypeOf(type, TypeNames.JAKARTA_PROVIDER)) + && isTypeOf(unwrapType(type), TypeNames.LAZY)) { return RequestKind.PROVIDER_OF_LAZY; } + if (isTypeOf(type, TypeNames.JAKARTA_PROVIDER)) { + return RequestKind.PROVIDER; + } + return FRAMEWORK_CLASSES.keySet().stream() .filter(kind -> isTypeOf(type, FRAMEWORK_CLASSES.get(kind))) .collect(toOptional()) @@ -162,21 +174,38 @@ * Returns {@code true} if requests for {@code requestKind} can be satisfied by a production * binding. */ - public static boolean canBeSatisfiedByProductionBinding(RequestKind requestKind) { + public static boolean canBeSatisfiedByProductionBinding( + RequestKind requestKind, boolean isEntryPoint) { switch (requestKind) { - case INSTANCE: case PROVIDER: case LAZY: case PROVIDER_OF_LAZY: case MEMBERS_INJECTION: return false; + case PRODUCED: // TODO(b/337087142) Requires implementation for entry point. + case INSTANCE: + return !isEntryPoint; case PRODUCER: - case PRODUCED: case FUTURE: return true; } throw new AssertionError(); } + public static boolean dependencyCanBeProduction(DependencyEdge edge, BindingGraph graph) { + Node source = graph.network().incidentNodes(edge).source(); + boolean isEntryPoint = source instanceof ComponentNode; + boolean isValidRequest = + canBeSatisfiedByProductionBinding(edge.dependencyRequest().kind(), isEntryPoint); + if (isEntryPoint) { + return isValidRequest; + } + if (source instanceof Binding) { + return isValidRequest && ((Binding) source).isProduction(); + } + throw new IllegalArgumentException( + "expected a dagger.internal.codegen.model.Binding or ComponentNode: " + source); + } + private RequestKinds() {} }
diff --git a/java/dagger/internal/codegen/base/SourceFileGenerator.java b/java/dagger/internal/codegen/base/SourceFileGenerator.java index dfe14b1..e4fd5b6 100644 --- a/java/dagger/internal/codegen/base/SourceFileGenerator.java +++ b/java/dagger/internal/codegen/base/SourceFileGenerator.java
@@ -19,16 +19,17 @@ 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.DEPRECATION; 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; +import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNINITIALIZED; import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XFiler; import androidx.room.compiler.processing.XMessager; import androidx.room.compiler.processing.XProcessingEnv; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.AnnotationSpec; @@ -61,29 +62,15 @@ this(delegate.filer, delegate.processingEnv); } - /** - * Generates a source file to be compiled for {@code T}. Writes any generation exception to {@code - * messager} and does not throw. - */ + /** Generates a source file to be compiled for {@code T}. */ public void generate(T input, XMessager messager) { - try { - generate(input); - } catch (SourceFileGenerationException e) { - e.printMessageTo(messager); - } + generate(input); } /** Generates a source file to be compiled for {@code T}. */ - public void generate(T input) throws SourceFileGenerationException { + public void generate(T input) { for (TypeSpec.Builder type : topLevelTypes(input)) { - try { - filer.write(buildJavaFile(input, type), XFiler.Mode.Isolating); - } catch (RuntimeException e) { - // if the code above threw a SFGE, use that - Throwables.propagateIfPossible(e, SourceFileGenerationException.class); - // otherwise, throw a new one - throw new SourceFileGenerationException(Optional.empty(), e, originatingElement(input)); - } + filer.write(buildJavaFile(input, type), XFiler.Mode.Isolating); } } @@ -106,7 +93,7 @@ AnnotationSpecs.suppressWarnings( ImmutableSet.<Suppression>builder() .addAll(warningSuppressions()) - .add(UNCHECKED, RAWTYPES, KOTLIN_INTERNAL, CAST) + .add(UNCHECKED, RAWTYPES, KOTLIN_INTERNAL, CAST, DEPRECATION, UNINITIALIZED) .build())); String packageName = closestEnclosingTypeElement(originatingElement).getPackageName();
diff --git a/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java b/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java index 6857c36..8e93a61 100644 --- a/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java +++ b/java/dagger/internal/codegen/base/SourceFileHjarGenerator.java
@@ -201,11 +201,16 @@ } private FieldSpec skeletonField(FieldSpec completeField) { - return FieldSpec.builder( - completeField.type, - completeField.name, - completeField.modifiers.toArray(new Modifier[0])) - .addAnnotations(completeField.annotations) - .build(); + FieldSpec.Builder skeleton = + FieldSpec.builder( + completeField.type, + completeField.name, + completeField.modifiers.toArray(new Modifier[0])) + .addAnnotations(completeField.annotations); + if (completeField.modifiers.contains(Modifier.FINAL)) { + // Final fields must be initialized so use the default value. + skeleton.initializer(getDefaultValueCodeBlock(completeField.type)); + } + return skeleton.build(); } }
diff --git a/java/dagger/internal/codegen/binding/AnnotationExpression.java b/java/dagger/internal/codegen/binding/AnnotationExpression.java index 535a7ef..db0bf55 100644 --- a/java/dagger/internal/codegen/binding/AnnotationExpression.java +++ b/java/dagger/internal/codegen/binding/AnnotationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.binding; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static androidx.room.compiler.processing.XTypeKt.isArray; import static dagger.internal.codegen.binding.SourceFiles.classFileName; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; @@ -26,11 +27,11 @@ import static dagger.internal.codegen.xprocessing.XTypes.asArray; import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf; +import androidx.room.compiler.codegen.XClassName; import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XAnnotationValue; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; -import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import dagger.internal.codegen.javapoet.TypeNames; @@ -47,7 +48,7 @@ */ public final class AnnotationExpression { private final XAnnotation annotation; - private final ClassName creatorClass; + private final XClassName creatorClass; AnnotationExpression(XAnnotation annotation) { this.annotation = annotation; @@ -65,7 +66,7 @@ private CodeBlock getAnnotationInstanceExpression(XAnnotation annotation) { return CodeBlock.of( "$T.$L($L)", - creatorClass, + toJavaPoet(creatorClass), createMethodName(annotation.getType().getTypeElement()), makeParametersCodeBlock( annotation.getAnnotationValues().stream() @@ -77,11 +78,11 @@ * Returns the name of the generated class that contains the static {@code create} methods for an * annotation type. */ - public static ClassName getAnnotationCreatorClassName(XTypeElement annotationType) { - ClassName annotationTypeName = annotationType.getClassName(); - return annotationTypeName - .topLevelClassName() - .peerClass(classFileName(annotationTypeName) + "Creator"); + public static XClassName getAnnotationCreatorClassName(XTypeElement annotationType) { + XClassName annotationTypeName = annotationType.asClassName(); + return XClassName.Companion.get( + annotationTypeName.getPackageName(), + classFileName(annotationTypeName) + "Creator"); } public static String createMethodName(XTypeElement annotationType) {
diff --git a/java/dagger/internal/codegen/binding/AssistedFactoryBinding.java b/java/dagger/internal/codegen/binding/AssistedFactoryBinding.java new file mode 100644 index 0000000..21220e6 --- /dev/null +++ b/java/dagger/internal/codegen/binding/AssistedFactoryBinding.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.internal.codegen.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#ASSISTED_FACTORY}. */ +@CheckReturnValue +@AutoValue +public abstract class AssistedFactoryBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.ASSISTED_FACTORY; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of( + DependencyRequest.builder() + .key(assistedInjectKey()) + .kind(RequestKind.PROVIDER) + .build()); + } + + /** Returns the key for the associated {@code @AssistedInject} binding. */ + public abstract Key assistedInjectKey(); + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_AssistedFactoryBinding.Builder(); + } + + /** A {@link AssistedFactoryBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<AssistedFactoryBinding, Builder> { + abstract Builder assistedInjectKey(Key assistedInjectKey); + } +}
diff --git a/java/dagger/internal/codegen/binding/AssistedInjectionBinding.java b/java/dagger/internal/codegen/binding/AssistedInjectionBinding.java new file mode 100644 index 0000000..b5fef76 --- /dev/null +++ b/java/dagger/internal/codegen/binding/AssistedInjectionBinding.java
@@ -0,0 +1,98 @@ +/* + * 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.binding; + +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#ASSISTED_INJECTION}. */ +@CheckReturnValue +@AutoValue +public abstract class AssistedInjectionBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.ASSISTED_INJECTION; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + /** Dependencies necessary to invoke the {@code @Inject} annotated constructor. */ + public abstract ImmutableSet<DependencyRequest> constructorDependencies(); + + /** {@link InjectionSite}s for all {@code @Inject} members. */ + public abstract ImmutableSortedSet<InjectionSite> injectionSites(); + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.<DependencyRequest>builder() + .addAll(constructorDependencies()) + .addAll( + injectionSites().stream() + .flatMap(i -> i.dependencies().stream()) + .collect(toImmutableSet())) + .build(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_AssistedInjectionBinding.Builder(); + } + + /** A {@link AssistedInjectionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<AssistedInjectionBinding, Builder> { + abstract Builder constructorDependencies(Iterable<DependencyRequest> constructorDependencies); + + abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites); + } +}
diff --git a/java/dagger/internal/codegen/binding/Binding.java b/java/dagger/internal/codegen/binding/Binding.java index 250e608..d706485 100644 --- a/java/dagger/internal/codegen/binding/Binding.java +++ b/java/dagger/internal/codegen/binding/Binding.java
@@ -16,16 +16,7 @@ package dagger.internal.codegen.binding; -import static com.google.common.base.Suppliers.memoize; -import static dagger.internal.codegen.xprocessing.XElements.isAbstract; -import static dagger.internal.codegen.xprocessing.XElements.isStatic; - -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.DependencyRequest; -import dagger.internal.codegen.model.Scope; import java.util.Optional; /** @@ -35,77 +26,19 @@ * subtypes. */ public abstract class Binding extends BindingDeclaration { - - /** - * Returns {@code true} if using this binding requires an instance of the {@link - * #contributingModule()}. - */ - public boolean requiresModuleInstance() { - return contributingModule().isPresent() - && bindingElement().isPresent() - && !isAbstract(bindingElement().get()) - && !isStatic(bindingElement().get()); - } - - /** - * Returns {@code true} if this binding may provide {@code null} instead of an instance of {@link - * #key()}. Nullable bindings cannot be requested from {@linkplain DependencyRequest#isNullable() - * non-nullable dependency requests}. - */ - public abstract boolean isNullable(); - - /** The kind of binding this instance represents. */ - public abstract BindingKind kind(); + /** Returns the optional {@link BindingType}. */ + abstract Optional<BindingType> optionalBindingType(); /** The {@link BindingType} of this binding. */ - public abstract BindingType bindingType(); + public final BindingType bindingType() { + if (optionalBindingType().isPresent()) { + return optionalBindingType().get(); + } + throw new AssertionError("bindingType() is not set: " + this); + } /** The {@link FrameworkType} of this binding. */ public final FrameworkType frameworkType() { return FrameworkType.forBindingType(bindingType()); } - - /** - * The explicit set of {@link DependencyRequest dependencies} required to satisfy this binding as - * defined by the user-defined injection sites. - */ - public abstract ImmutableSet<DependencyRequest> explicitDependencies(); - - /** - * The set of {@link DependencyRequest dependencies} that are added by the framework rather than a - * user-defined injection site. This returns an unmodifiable set. - */ - public ImmutableSet<DependencyRequest> implicitDependencies() { - return ImmutableSet.of(); - } - - private final Supplier<ImmutableSet<DependencyRequest>> dependencies = - memoize( - () -> { - ImmutableSet<DependencyRequest> implicitDependencies = implicitDependencies(); - return ImmutableSet.copyOf( - implicitDependencies.isEmpty() - ? explicitDependencies() - : Sets.union(implicitDependencies, explicitDependencies())); - }); - - /** - * The set of {@link DependencyRequest dependencies} required to satisfy this binding. This is the - * union of {@link #explicitDependencies()} and {@link #implicitDependencies()}. This returns an - * unmodifiable set. - */ - public final ImmutableSet<DependencyRequest> dependencies() { - return dependencies.get(); - } - - /** - * If this binding's key's type parameters are different from those of the {@link - * #bindingTypeElement()}, this is the binding for the {@link #bindingTypeElement()}'s unresolved - * type. - */ - public abstract Optional<? extends Binding> unresolved(); - - public Optional<Scope> scope() { - return Optional.empty(); - } }
diff --git a/java/dagger/internal/codegen/binding/BindingDeclaration.java b/java/dagger/internal/codegen/binding/BindingDeclaration.java index dd24c98..54c8c49 100644 --- a/java/dagger/internal/codegen/binding/BindingDeclaration.java +++ b/java/dagger/internal/codegen/binding/BindingDeclaration.java
@@ -16,74 +16,41 @@ package dagger.internal.codegen.binding; -import static androidx.room.compiler.processing.compat.XConverters.toJavac; -import static dagger.internal.codegen.extension.Optionals.emptiesLast; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; -import static java.util.Comparator.comparing; - -import androidx.room.compiler.processing.XElement; -import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableSet; import dagger.internal.codegen.model.BindingKind; -import dagger.internal.codegen.model.Key; -import dagger.internal.codegen.xprocessing.XElements; -import java.util.Comparator; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.model.Scope; import java.util.Optional; /** An object that declares or specifies a binding. */ -public abstract class BindingDeclaration { - /** - * A comparator that compares binding declarations with elements. - * - * <p>Compares, in order: - * - * <ol> - * <li>Contributing module or enclosing type name - * <li>Binding element's simple name - * <li>Binding element's type - * </ol> - * - * Any binding declarations without elements are last. - */ - public static final Comparator<BindingDeclaration> COMPARATOR = - comparing( - (BindingDeclaration declaration) -> - declaration.contributingModule().isPresent() - ? declaration.contributingModule() - : declaration.bindingTypeElement(), - emptiesLast(comparing(XTypeElement::getQualifiedName))) - .thenComparing( - (BindingDeclaration declaration) -> declaration.bindingElement(), - emptiesLast( - comparing((XElement element) -> getSimpleName(element)) - .thenComparing((XElement element) -> toJavac(element).asType().toString()))); - - /** The {@link Key} of this declaration. */ - public abstract Key key(); +public abstract class BindingDeclaration extends Declaration { /** - * The {@link XElement} that declares this binding. Absent for {@linkplain BindingKind binding - * kinds} that are not always declared by exactly one element. - * - * <p>For example, consider {@link BindingKind#MULTIBOUND_SET}. A component with many - * {@code @IntoSet} bindings for the same key will have a synthetic binding that depends on all - * contributions, but with no identifiying binding element. A {@code @Multibinds} method will also - * contribute a synthetic binding, but since multiple {@code @Multibinds} methods can coexist in - * the same component (and contribute to one single binding), it has no binding element. + * Returns {@code true} if using this binding requires an instance of the {@link + * #contributingModule()}. */ - public abstract Optional<XElement> bindingElement(); + public abstract boolean requiresModuleInstance(); /** - * The type enclosing the {@link #bindingElement()}, or {@link Optional#empty()} if {@link - * #bindingElement()} is empty. + * Returns {@code true} if this binding may provide {@code null} instead of an instance of {@link + * #key()}. Nullable bindings cannot be requested from {@linkplain DependencyRequest#isNullable() + * non-nullable dependency requests}. */ - public final Optional<XTypeElement> bindingTypeElement() { - return bindingElement().map(XElements::closestEnclosingTypeElement); - } + public abstract boolean isNullable(); + + /** The kind of binding this instance represents. */ + public abstract BindingKind kind(); + + /** The set of {@link DependencyRequest dependencies} required to satisfy this binding. */ + public abstract ImmutableSet<DependencyRequest> dependencies(); /** - * The installed module class that contributed the {@link #bindingElement()}. May be a subclass of - * the class that contains {@link #bindingElement()}. Absent if {@link #bindingElement()} is - * empty. + * If this binding's key's type parameters are different from those of the {@link + * #bindingTypeElement()}, this is the binding for the {@link #bindingTypeElement()}'s unresolved + * type. */ - public abstract Optional<XTypeElement> contributingModule(); + public abstract Optional<? extends Binding> unresolved(); + + /** Returns the optional scope used on the binding. */ + public abstract Optional<Scope> scope(); }
diff --git a/java/dagger/internal/codegen/binding/BindingFactory.java b/java/dagger/internal/codegen/binding/BindingFactory.java index 11fa591..8a57abf 100644 --- a/java/dagger/internal/codegen/binding/BindingFactory.java +++ b/java/dagger/internal/codegen/binding/BindingFactory.java
@@ -17,29 +17,12 @@ package dagger.internal.codegen.binding; import static androidx.room.compiler.processing.XElementKt.isMethod; -import static androidx.room.compiler.processing.XElementKt.isTypeElement; import static androidx.room.compiler.processing.XElementKt.isVariableElement; 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.binding.ComponentDescriptor.isComponentProductionMethod; -import static dagger.internal.codegen.binding.MapKeys.getMapKey; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.model.BindingKind.ASSISTED_FACTORY; -import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION; -import static dagger.internal.codegen.model.BindingKind.BOUND_INSTANCE; -import static dagger.internal.codegen.model.BindingKind.COMPONENT; -import static dagger.internal.codegen.model.BindingKind.COMPONENT_DEPENDENCY; -import static dagger.internal.codegen.model.BindingKind.COMPONENT_PRODUCTION; -import static dagger.internal.codegen.model.BindingKind.COMPONENT_PROVISION; -import static dagger.internal.codegen.model.BindingKind.DELEGATE; -import static dagger.internal.codegen.model.BindingKind.INJECTION; -import static dagger.internal.codegen.model.BindingKind.MEMBERS_INJECTOR; -import static dagger.internal.codegen.model.BindingKind.OPTIONAL; -import static dagger.internal.codegen.model.BindingKind.PRODUCTION; -import static dagger.internal.codegen.model.BindingKind.PROVISION; -import static dagger.internal.codegen.model.BindingKind.SUBCOMPONENT_CREATOR; +import static dagger.internal.codegen.base.RequestKinds.getRequestKind; import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import static dagger.internal.codegen.xprocessing.XElements.asVariable; @@ -57,23 +40,18 @@ import androidx.room.compiler.processing.XVariableElement; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; -import com.squareup.javapoet.ClassName; import dagger.Module; -import dagger.internal.codegen.base.ContributionType; import dagger.internal.codegen.base.MapType; +import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.base.SetType; -import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; -import dagger.internal.codegen.binding.ProductionBinding.ProductionKind; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingKind; -import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.Nullability; import java.util.Optional; -import java.util.function.BiFunction; import javax.inject.Inject; /** A factory for {@link Binding} objects. */ @@ -96,16 +74,16 @@ } /** - * Returns an {@link dagger.internal.codegen.model.BindingKind#INJECTION} binding. + * Returns an {@link BindingKind#INJECTION} binding. * * @param constructorElement the {@code @Inject}-annotated constructor - * @param resolvedType the parameterized type if the constructor is for a generic class and the - * binding should be for the parameterized type + * @param resolvedEnclosingType the parameterized type if the constructor is for a generic class + * and the binding should be for the parameterized type */ // TODO(dpb): See if we can just pass the parameterized type and not also the constructor. - public ProvisionBinding injectionBinding( + public InjectionBinding injectionBinding( XConstructorElement constructorElement, Optional<XType> resolvedEnclosingType) { - checkArgument(InjectionAnnotations.hasInjectOrAssistedInjectAnnotation(constructorElement)); + checkArgument(InjectionAnnotations.hasInjectAnnotation(constructorElement)); XConstructorType constructorType = constructorElement.getExecutableType(); XType enclosingType = constructorElement.getEnclosingElement().getType(); @@ -117,37 +95,74 @@ } // Collect all dependency requests within the provision method. - // Note: we filter out @Assisted parameters since these aren't considered dependency requests. - ImmutableSet.Builder<DependencyRequest> provisionDependencies = ImmutableSet.builder(); + ImmutableSet.Builder<DependencyRequest> constructorDependencies = ImmutableSet.builder(); for (int i = 0; i < constructorElement.getParameters().size(); i++) { XExecutableParameterElement parameter = constructorElement.getParameters().get(i); XType parameterType = constructorType.getParameterTypes().get(i); + constructorDependencies.add( + dependencyRequestFactory.forRequiredResolvedVariable(parameter, parameterType)); + } + + return InjectionBinding.builder() + .bindingElement(constructorElement) + .key(keyFactory.forInjectConstructorWithResolvedType(enclosingType)) + .constructorDependencies(constructorDependencies.build()) + .injectionSites(injectionSiteFactory.getInjectionSites(enclosingType)) + .scope(injectionAnnotations.getScope(constructorElement.getEnclosingElement())) + .unresolved( + hasNonDefaultTypeParameters(enclosingType) + ? Optional.of(injectionBinding(constructorElement, Optional.empty())) + : Optional.empty()) + .build(); + } + + /** + * Returns an {@link BindingKind#ASSISTED_INJECTION} binding. + * + * @param constructorElement the {@code @Inject}-annotated constructor + * @param resolvedEnclosingType the parameterized type if the constructor is for a generic class + * and the binding should be for the parameterized type + */ + // TODO(dpb): See if we can just pass the parameterized type and not also the constructor. + public AssistedInjectionBinding assistedInjectionBinding( + XConstructorElement constructorElement, Optional<XType> resolvedEnclosingType) { + checkArgument(constructorElement.hasAnnotation(TypeNames.ASSISTED_INJECT)); + + XConstructorType constructorType = constructorElement.getExecutableType(); + XType enclosingType = constructorElement.getEnclosingElement().getType(); + // If the class this is constructing has some type arguments, resolve everything. + if (!enclosingType.getTypeArguments().isEmpty() && resolvedEnclosingType.isPresent()) { + checkIsSameErasedType(resolvedEnclosingType.get(), enclosingType); + enclosingType = resolvedEnclosingType.get(); + constructorType = constructorElement.asMemberOf(enclosingType); + } + + // Collect all dependency requests within the provision method. + ImmutableSet.Builder<DependencyRequest> constructorDependencies = ImmutableSet.builder(); + for (int i = 0; i < constructorElement.getParameters().size(); i++) { + XExecutableParameterElement parameter = constructorElement.getParameters().get(i); + XType parameterType = constructorType.getParameterTypes().get(i); + // Note: we filter out @Assisted parameters since these aren't considered dependency requests. if (!AssistedInjectionAnnotations.isAssistedParameter(parameter)) { - provisionDependencies.add( + constructorDependencies.add( dependencyRequestFactory.forRequiredResolvedVariable(parameter, parameterType)); } } - ProvisionBinding.Builder builder = - ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) - .bindingElement(constructorElement) - .key(keyFactory.forInjectConstructorWithResolvedType(enclosingType)) - .provisionDependencies(provisionDependencies.build()) - .injectionSites(injectionSiteFactory.getInjectionSites(enclosingType)) - .kind( - constructorElement.hasAnnotation(TypeNames.ASSISTED_INJECT) - ? ASSISTED_INJECTION - : INJECTION) - .scope(injectionAnnotations.getScope(constructorElement.getEnclosingElement())); - - if (hasNonDefaultTypeParameters(enclosingType)) { - builder.unresolved(injectionBinding(constructorElement, Optional.empty())); - } - return builder.build(); + return AssistedInjectionBinding.builder() + .bindingElement(constructorElement) + .key(keyFactory.forInjectConstructorWithResolvedType(enclosingType)) + .constructorDependencies(constructorDependencies.build()) + .injectionSites(injectionSiteFactory.getInjectionSites(enclosingType)) + .scope(injectionAnnotations.getScope(constructorElement.getEnclosingElement())) + .unresolved( + hasNonDefaultTypeParameters(enclosingType) + ? Optional.of(assistedInjectionBinding(constructorElement, Optional.empty())) + : Optional.empty()) + .build(); } - public ProvisionBinding assistedFactoryBinding( + public AssistedFactoryBinding assistedFactoryBinding( XTypeElement factory, Optional<XType> resolvedFactoryType) { // If the class this is constructing has some type arguments, resolve everything. @@ -159,351 +174,325 @@ XMethodElement factoryMethod = AssistedInjectionAnnotations.assistedFactoryMethod(factory); XMethodType factoryMethodType = factoryMethod.asMemberOf(factoryType); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) + return AssistedFactoryBinding.builder() .key(keyFactory.forType(factoryType)) .bindingElement(factory) - .provisionDependencies( - ImmutableSet.of( - DependencyRequest.builder() - .key(keyFactory.forType(factoryMethodType.getReturnType())) - .kind(RequestKind.PROVIDER) - .build())) - .kind(ASSISTED_FACTORY) + .assistedInjectKey(keyFactory.forType(factoryMethodType.getReturnType())) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#PROVISION} binding for a - * {@code @Provides}-annotated method. + * Returns a {@link BindingKind#PROVISION} binding for a {@code @Provides}-annotated method. * - * @param contributedBy the installed module that declares or inherits the method + * @param module the installed module that declares or inherits the method */ - public ProvisionBinding providesMethodBinding( - XMethodElement providesMethod, XTypeElement contributedBy) { - return setMethodBindingProperties( - ProvisionBinding.builder(), - providesMethod, - contributedBy, - keyFactory.forProvidesMethod(providesMethod, contributedBy), - this::providesMethodBinding) - .kind(PROVISION) - .scope(injectionAnnotations.getScope(providesMethod)) - .nullability(Nullability.of(providesMethod)) - .build(); - } - - /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#PRODUCTION} binding for a - * {@code @Produces}-annotated method. - * - * @param contributedBy the installed module that declares or inherits the method - */ - public ProductionBinding producesMethodBinding( - XMethodElement producesMethod, XTypeElement contributedBy) { - // TODO(beder): Add nullability checking with Java 8. - ProductionBinding.Builder builder = - setMethodBindingProperties( - ProductionBinding.builder(), - producesMethod, - contributedBy, - keyFactory.forProducesMethod(producesMethod, contributedBy), - this::producesMethodBinding) - .kind(PRODUCTION) - .productionKind(ProductionKind.fromProducesMethod(producesMethod)) - .thrownTypes(producesMethod.getThrownTypes()) - .executorRequest(dependencyRequestFactory.forProductionImplementationExecutor()) - .monitorRequest(dependencyRequestFactory.forProductionComponentMonitor()); - return builder.build(); - } - - private <C extends ContributionBinding, B extends ContributionBinding.Builder<C, B>> - B setMethodBindingProperties( - B builder, - XMethodElement method, - XTypeElement contributedBy, - Key key, - BiFunction<XMethodElement, XTypeElement, C> create) { - XMethodType methodType = method.asMemberOf(contributedBy.getType()); - if (!methodType.isSameType(method.getExecutableType())) { - checkState(isTypeElement(method.getEnclosingElement())); - builder.unresolved(create.apply(method, asTypeElement(method.getEnclosingElement()))); - } - return builder - .contributionType(ContributionType.fromBindingElement(method)) + public ProvisionBinding providesMethodBinding(XMethodElement method, XTypeElement module) { + XMethodType methodType = method.asMemberOf(module.getType()); + return ProvisionBinding.builder() + .scope(injectionAnnotations.getScope(method)) + .nullability(Nullability.of(method)) .bindingElement(method) - .contributingModule(contributedBy) - .key(key) + .contributingModule(module) + .key(keyFactory.forProvidesMethod(method, module)) .dependencies( dependencyRequestFactory.forRequiredResolvedVariables( method.getParameters(), methodType.getParameterTypes())) - .mapKey(getMapKey(method).map(DaggerAnnotation::from)); - } - - /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#MULTIBOUND_MAP} or {@link - * dagger.internal.codegen.model.BindingKind#MULTIBOUND_SET} binding given a set of multibinding - * contribution bindings. - * - * @param key a key that may be satisfied by a multibinding - */ - public ContributionBinding syntheticMultibinding( - Key key, Iterable<ContributionBinding> multibindingContributions) { - ContributionBinding.Builder<?, ?> builder = - multibindingRequiresProduction(key, multibindingContributions) - ? ProductionBinding.builder() - : ProvisionBinding.builder(); - return builder - .contributionType(ContributionType.UNIQUE) - .key(key) - .dependencies( - dependencyRequestFactory.forMultibindingContributions(key, multibindingContributions)) - .kind(bindingKindForMultibindingKey(key)) + .unresolved( + methodType.isSameType(method.getExecutableType()) + ? Optional.empty() + : Optional.of( + providesMethodBinding(method, asTypeElement(method.getEnclosingElement())))) .build(); } - private static BindingKind bindingKindForMultibindingKey(Key key) { - if (SetType.isSet(key)) { - return BindingKind.MULTIBOUND_SET; - } else if (MapType.isMap(key)) { - return BindingKind.MULTIBOUND_MAP; - } else { - throw new IllegalArgumentException(String.format("key is not for a set or map: %s", key)); - } + /** + * Returns a {@link BindingKind#PRODUCTION} binding for a {@code @Produces}-annotated method. + * + * @param module the installed module that declares or inherits the method + */ + public ProductionBinding producesMethodBinding(XMethodElement method, XTypeElement module) { + // TODO(beder): Add nullability checking with Java 8. + XMethodType methodType = method.asMemberOf(module.getType()); + return ProductionBinding.builder() + .bindingElement(method) + .contributingModule(module) + .key(keyFactory.forProducesMethod(method, module)) + .executorRequest(dependencyRequestFactory.forProductionImplementationExecutor()) + .monitorRequest(dependencyRequestFactory.forProductionComponentMonitor()) + .explicitDependencies( + dependencyRequestFactory.forRequiredResolvedVariables( + method.getParameters(), methodType.getParameterTypes())) + .scope(injectionAnnotations.getScope(method)) + .unresolved( + methodType.isSameType(method.getExecutableType()) + ? Optional.empty() + : Optional.of( + producesMethodBinding(method, asTypeElement(method.getEnclosingElement())))) + .build(); } - private boolean multibindingRequiresProduction( + /** + * Returns a {@link BindingKind#MULTIBOUND_MAP} binding given a set of multibinding contributions. + * + * @param key a key that may be satisfied by a multibinding + */ + public MultiboundMapBinding multiboundMap( + Key key, Iterable<ContributionBinding> multibindingContributions) { + return MultiboundMapBinding.builder() + .optionalBindingType(multibindingBindingType(key, multibindingContributions)) + .key(key) + .dependencies( + dependencyRequestFactory.forMultibindingContributions(key, multibindingContributions)) + .build(); + } + + /** + * Returns a {@link BindingKind#MULTIBOUND_SET} binding given a set of multibinding contributions. + * + * @param key a key that may be satisfied by a multibinding + */ + public MultiboundSetBinding multiboundSet( + Key key, Iterable<ContributionBinding> multibindingContributions) { + return MultiboundSetBinding.builder() + .optionalBindingType(multibindingBindingType(key, multibindingContributions)) + .key(key) + .dependencies( + dependencyRequestFactory.forMultibindingContributions(key, multibindingContributions)) + .build(); + } + + private Optional<BindingType> multibindingBindingType( Key key, Iterable<ContributionBinding> multibindingContributions) { if (MapType.isMap(key)) { MapType mapType = MapType.from(key); if (mapType.valuesAreTypeOf(TypeNames.PRODUCER) || mapType.valuesAreTypeOf(TypeNames.PRODUCED)) { - return true; + return Optional.of(BindingType.PRODUCTION); } } else if (SetType.isSet(key) && SetType.from(key).elementsAreTypeOf(TypeNames.PRODUCED)) { - return true; + return Optional.of(BindingType.PRODUCTION); + } + if (Iterables.any( + multibindingContributions, + binding -> binding.optionalBindingType().equals(Optional.of(BindingType.PRODUCTION)))) { + return Optional.of(BindingType.PRODUCTION); } return Iterables.any( - multibindingContributions, binding -> binding.bindingType().equals(BindingType.PRODUCTION)); + multibindingContributions, + binding -> binding.optionalBindingType().isEmpty()) + // If a dependency is missing a BindingType then we can't determine the BindingType of this + // binding yet since it may end up depending on a production type. + ? Optional.empty() + : Optional.of(BindingType.PROVISION); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#COMPONENT} binding for the + * Returns a {@link BindingKind#COMPONENT} binding for the * component. */ - public ProvisionBinding componentBinding(XTypeElement componentDefinitionType) { + public ComponentBinding componentBinding(XTypeElement componentDefinitionType) { checkNotNull(componentDefinitionType); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) + return ComponentBinding.builder() .bindingElement(componentDefinitionType) .key(keyFactory.forType(componentDefinitionType.getType())) - .kind(COMPONENT) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#COMPONENT_DEPENDENCY} binding for a + * Returns a {@link BindingKind#COMPONENT_DEPENDENCY} binding for a * component's dependency. */ - public ProvisionBinding componentDependencyBinding(ComponentRequirement dependency) { + public ComponentDependencyBinding componentDependencyBinding(ComponentRequirement dependency) { checkNotNull(dependency); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) + return ComponentDependencyBinding.builder() .bindingElement(dependency.typeElement()) .key(keyFactory.forType(dependency.type())) - .kind(COMPONENT_DEPENDENCY) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#COMPONENT_PROVISION} or {@link - * dagger.internal.codegen.model.BindingKind#COMPONENT_PRODUCTION} binding for a method on a - * component's dependency. - * - * @param componentDescriptor the component with the dependency, not the dependency that has the - * method + * Returns a {@link BindingKind#COMPONENT_PROVISION} binding for a + * method on a component's dependency. */ - public ContributionBinding componentDependencyMethodBinding( - ComponentDescriptor componentDescriptor, XMethodElement dependencyMethod) { + public ComponentDependencyProvisionBinding componentDependencyProvisionMethodBinding( + XMethodElement dependencyMethod) { checkArgument(dependencyMethod.getParameters().isEmpty()); - ContributionBinding.Builder<?, ?> builder; - if (componentDescriptor.isProduction() && isComponentProductionMethod(dependencyMethod)) { - builder = - ProductionBinding.builder() - .key(keyFactory.forProductionComponentMethod(dependencyMethod)) - .kind(COMPONENT_PRODUCTION) - .thrownTypes(dependencyMethod.getThrownTypes()); - } else { - builder = - ProvisionBinding.builder() - .key(keyFactory.forComponentMethod(dependencyMethod)) - .nullability(Nullability.of(dependencyMethod)) - .kind(COMPONENT_PROVISION) - .scope(injectionAnnotations.getScope(dependencyMethod)); - } - return builder - .contributionType(ContributionType.UNIQUE) + return ComponentDependencyProvisionBinding.builder() + .key(keyFactory.forComponentMethod(dependencyMethod)) + .nullability(Nullability.of(dependencyMethod)) + .scope(injectionAnnotations.getScope(dependencyMethod)) .bindingElement(dependencyMethod) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#BOUND_INSTANCE} binding for a + * Returns a {@link BindingKind#COMPONENT_PRODUCTION} binding for a + * method on a component's dependency. + */ + public ComponentDependencyProductionBinding componentDependencyProductionMethodBinding( + XMethodElement dependencyMethod) { + checkArgument(dependencyMethod.getParameters().isEmpty()); + return ComponentDependencyProductionBinding.builder() + .key(keyFactory.forProductionComponentMethod(dependencyMethod)) + .bindingElement(dependencyMethod) + .build(); + } + + /** + * Returns a {@link BindingKind#BOUND_INSTANCE} binding for a * {@code @BindsInstance}-annotated builder setter method or factory method parameter. */ - ProvisionBinding boundInstanceBinding(ComponentRequirement requirement, XElement element) { + BoundInstanceBinding boundInstanceBinding(ComponentRequirement requirement, XElement element) { checkArgument(isVariableElement(element) || isMethod(element)); XVariableElement parameterElement = isVariableElement(element) ? asVariable(element) : getOnlyElement(asMethod(element).getParameters()); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) + return BoundInstanceBinding.builder() .bindingElement(element) .key(requirement.key().get()) .nullability(Nullability.of(parameterElement)) - .kind(BOUND_INSTANCE) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#SUBCOMPONENT_CREATOR} binding + * Returns a {@link BindingKind#SUBCOMPONENT_CREATOR} binding * declared by a component method that returns a subcomponent builder. Use {{@link * #subcomponentCreatorBinding(ImmutableSet)}} for bindings declared using {@link * Module#subcomponents()}. * * @param component the component that declares or inherits the method */ - ProvisionBinding subcomponentCreatorBinding( + SubcomponentCreatorBinding subcomponentCreatorBinding( XMethodElement subcomponentCreatorMethod, XTypeElement component) { checkArgument(subcomponentCreatorMethod.getParameters().isEmpty()); Key key = keyFactory.forSubcomponentCreatorMethod(subcomponentCreatorMethod, component.getType()); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) + return SubcomponentCreatorBinding.builder() .bindingElement(subcomponentCreatorMethod) .key(key) - .kind(SUBCOMPONENT_CREATOR) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#SUBCOMPONENT_CREATOR} binding + * Returns a {@link BindingKind#SUBCOMPONENT_CREATOR} binding * declared using {@link Module#subcomponents()}. */ - ProvisionBinding subcomponentCreatorBinding( + SubcomponentCreatorBinding subcomponentCreatorBinding( ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) { SubcomponentDeclaration subcomponentDeclaration = subcomponentDeclarations.iterator().next(); - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) - .key(subcomponentDeclaration.key()) - .kind(SUBCOMPONENT_CREATOR) - .build(); + return SubcomponentCreatorBinding.builder().key(subcomponentDeclaration.key()).build(); + } + + /** Returns a {@link BindingKind#DELEGATE} binding. */ + DelegateBinding delegateBinding(DelegateDeclaration delegateDeclaration) { + return delegateBinding(delegateDeclaration, Optional.empty()); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#DELEGATE} binding. + * Returns a {@link BindingKind#DELEGATE} binding. * * @param delegateDeclaration the {@code @Binds}-annotated declaration * @param actualBinding the binding that satisfies the {@code @Binds} declaration */ - ContributionBinding delegateBinding( + DelegateBinding delegateBinding( DelegateDeclaration delegateDeclaration, ContributionBinding actualBinding) { - switch (actualBinding.bindingType()) { - case PRODUCTION: - return buildDelegateBinding( - ProductionBinding.builder().nullability(actualBinding.nullability()), - delegateDeclaration, - TypeNames.PRODUCER); - - case PROVISION: - return buildDelegateBinding( - ProvisionBinding.builder() - .scope(injectionAnnotations.getScope(delegateDeclaration.bindingElement().get())) - .nullability(actualBinding.nullability()), - delegateDeclaration, - TypeNames.PROVIDER); - - case MEMBERS_INJECTION: // fall-through to throw - } - throw new AssertionError("bindingType: " + actualBinding); + return delegateBinding(delegateDeclaration, delegateBindingType(Optional.of(actualBinding))); } - /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#DELEGATE} binding used when there is - * no binding that satisfies the {@code @Binds} declaration. - */ - public ContributionBinding unresolvedDelegateBinding(DelegateDeclaration delegateDeclaration) { - return buildDelegateBinding( - ProvisionBinding.builder() - .scope(injectionAnnotations.getScope(delegateDeclaration.bindingElement().get())), - delegateDeclaration, - TypeNames.PROVIDER); - } - - private ContributionBinding buildDelegateBinding( - ContributionBinding.Builder<?, ?> builder, - DelegateDeclaration delegateDeclaration, - ClassName frameworkType) { - return builder + private DelegateBinding delegateBinding( + DelegateDeclaration delegateDeclaration, Optional<BindingType> optionalBindingType) { + return DelegateBinding.builder() .contributionType(delegateDeclaration.contributionType()) .bindingElement(delegateDeclaration.bindingElement().get()) .contributingModule(delegateDeclaration.contributingModule().get()) - .key(keyFactory.forDelegateBinding(delegateDeclaration, frameworkType)) - .dependencies(delegateDeclaration.delegateRequest()) - .mapKey(delegateDeclaration.mapKey()) - .kind(DELEGATE) + .delegateRequest(delegateDeclaration.delegateRequest()) + .nullability(Nullability.of(delegateDeclaration.bindingElement().get())) + .optionalBindingType(optionalBindingType) + .key( + optionalBindingType.isEmpty() + // This is used by BindingGraphFactory which passes in an empty optionalBindingType. + // In this case, multibound map contributions will always return the key type + // without framework types, i.e. Map<K,V>. + ? delegateDeclaration.key() + // This is used by LegacyBindingGraphFactory, which passes in a non-empty + // optionalBindingType. Then, KeyFactory decides whether or not multibound map + // contributions should include the factory type based on the compiler flag, + // -Adagger.useFrameworkTypeInMapMultibindingContributionKey. + : optionalBindingType.get() == BindingType.PRODUCTION + ? keyFactory.forDelegateBinding(delegateDeclaration, TypeNames.PRODUCER) + : keyFactory.forDelegateBinding(delegateDeclaration, TypeNames.PROVIDER)) + .scope(injectionAnnotations.getScope(delegateDeclaration.bindingElement().get())) .build(); } /** - * Returns an {@link dagger.internal.codegen.model.BindingKind#OPTIONAL} binding for {@code key}. - * - * @param requestKind the kind of request for the optional binding - * @param underlyingKeyBindings the possibly empty set of bindings that exist in the component for - * the underlying (non-optional) key + * Returns a {@link BindingKind#DELEGATE} binding used when there is + * no binding that satisfies the {@code @Binds} declaration. */ - ContributionBinding syntheticOptionalBinding( - Key key, - RequestKind requestKind, - ImmutableCollection<? extends Binding> underlyingKeyBindings) { - if (underlyingKeyBindings.isEmpty()) { - return ProvisionBinding.builder() - .contributionType(ContributionType.UNIQUE) - .key(key) - .kind(OPTIONAL) - .build(); + public DelegateBinding unresolvedDelegateBinding(DelegateDeclaration delegateDeclaration) { + return delegateBinding(delegateDeclaration, Optional.of(BindingType.PROVISION)); + } + + private Optional<BindingType> delegateBindingType(Optional<ContributionBinding> actualBinding) { + if (actualBinding.isEmpty()) { + return Optional.empty(); } + checkArgument(actualBinding.get().bindingType() != BindingType.MEMBERS_INJECTION); + return Optional.of(actualBinding.get().bindingType()); + } - boolean requiresProduction = - underlyingKeyBindings.stream() - .anyMatch(binding -> binding.bindingType() == BindingType.PRODUCTION) - || requestKind.equals(RequestKind.PRODUCER) // handles producerFromProvider cases - || requestKind.equals(RequestKind.PRODUCED); // handles producerFromProvider cases - - return (requiresProduction ? ProductionBinding.builder() : ProvisionBinding.builder()) - .contributionType(ContributionType.UNIQUE) + /** Returns an {@link BindingKind#OPTIONAL} present binding for {@code key}. */ + OptionalBinding syntheticPresentOptionalDeclaration( + Key key, ImmutableCollection<Binding> optionalContributions) { + checkArgument(!optionalContributions.isEmpty()); + return OptionalBinding.builder() + .optionalBindingType(presentOptionalBindingType(key, optionalContributions)) .key(key) - .kind(OPTIONAL) - .dependencies(dependencyRequestFactory.forSyntheticPresentOptionalBinding(key, requestKind)) + .delegateRequest(dependencyRequestFactory.forSyntheticPresentOptionalBinding(key)) .build(); } - /** Returns a {@link dagger.internal.codegen.model.BindingKind#MEMBERS_INJECTOR} binding. */ - public ProvisionBinding membersInjectorBinding( - Key key, MembersInjectionBinding membersInjectionBinding) { - return ProvisionBinding.builder() + private Optional<BindingType> presentOptionalBindingType( + Key key, ImmutableCollection<Binding> optionalContributions) { + RequestKind requestKind = getRequestKind(OptionalType.from(key).valueType()); + if (requestKind.equals(RequestKind.PRODUCER) // handles producerFromProvider cases + || requestKind.equals(RequestKind.PRODUCED)) { // handles producerFromProvider cases + return Optional.of(BindingType.PRODUCTION); + } + if (optionalContributions.stream() + .filter(binding -> binding.optionalBindingType().isPresent()) + .anyMatch(binding -> binding.bindingType() == BindingType.PRODUCTION)) { + return Optional.of(BindingType.PRODUCTION); + } + return optionalContributions.stream() + .anyMatch(binding -> binding.optionalBindingType().isEmpty()) + // If a dependency is missing a BindingType then we can't determine the BindingType of this + // binding yet since it may end up depending on a production type. + ? Optional.empty() + : Optional.of(BindingType.PROVISION); + } + + /** Returns an {@link BindingKind#OPTIONAL} absent binding for {@code key}. */ + OptionalBinding syntheticAbsentOptionalDeclaration(Key key) { + return OptionalBinding.builder() .key(key) - .contributionType(ContributionType.UNIQUE) - .kind(MEMBERS_INJECTOR) + .optionalBindingType(Optional.of(BindingType.PROVISION)) + .build(); + } + + /** Returns a {@link BindingKind#MEMBERS_INJECTOR} binding. */ + public MembersInjectorBinding membersInjectorBinding( + Key key, MembersInjectionBinding membersInjectionBinding) { + return MembersInjectorBinding.builder() + .key(key) .bindingElement(membersInjectionBinding.key().type().xprocessing().getTypeElement()) - .provisionDependencies(membersInjectionBinding.dependencies()) .injectionSites(membersInjectionBinding.injectionSites()) .build(); } /** - * Returns a {@link dagger.internal.codegen.model.BindingKind#MEMBERS_INJECTION} binding. + * Returns a {@link BindingKind#MEMBERS_INJECTION} binding. * * @param resolvedType if {@code declaredType} is a generic class and {@code resolvedType} is a * parameterization of that type, the returned binding will be for the resolved type @@ -515,20 +504,15 @@ checkIsSameErasedType(resolvedType.get(), type); type = resolvedType.get(); } - ImmutableSortedSet<InjectionSite> injectionSites = injectionSiteFactory.getInjectionSites(type); - ImmutableSet<DependencyRequest> dependencies = - injectionSites.stream() - .flatMap(injectionSite -> injectionSite.dependencies().stream()) - .collect(toImmutableSet()); - - return MembersInjectionBinding.create( - keyFactory.forMembersInjectedType(type), - dependencies, - hasNonDefaultTypeParameters(type) - ? Optional.of( - membersInjectionBinding(type.getTypeElement().getType(), Optional.empty())) - : Optional.empty(), - injectionSites); + return MembersInjectionBinding.builder() + .key(keyFactory.forMembersInjectedType(type)) + .injectionSites(injectionSiteFactory.getInjectionSites(type)) + .unresolved( + hasNonDefaultTypeParameters(type) + ? Optional.of( + membersInjectionBinding(type.getTypeElement().getType(), Optional.empty())) + : Optional.empty()) + .build(); } private void checkIsSameErasedType(XType type1, XType type2) {
diff --git a/java/dagger/internal/codegen/binding/BindingGraph.java b/java/dagger/internal/codegen/binding/BindingGraph.java index 0090b3d..9dffac0 100644 --- a/java/dagger/internal/codegen/binding/BindingGraph.java +++ b/java/dagger/internal/codegen/binding/BindingGraph.java
@@ -17,6 +17,7 @@ package dagger.internal.codegen.binding; import static com.google.common.collect.Iterables.transform; +import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; import static dagger.internal.codegen.extension.DaggerStreams.presentValues; @@ -42,6 +43,7 @@ import com.google.common.graph.ImmutableNetwork; import com.google.common.graph.Traverser; import dagger.internal.codegen.base.TarjanSCCs; +import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.model.BindingGraph.ChildFactoryMethodEdge; import dagger.internal.codegen.model.BindingGraph.ComponentNode; import dagger.internal.codegen.model.BindingGraph.DependencyEdge; @@ -52,6 +54,7 @@ import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; @@ -73,8 +76,9 @@ @AutoValue public abstract static class TopLevelBindingGraph extends dagger.internal.codegen.model.BindingGraph { - static TopLevelBindingGraph create( - ImmutableNetwork<Node, Edge> network, boolean isFullBindingGraph) { + private static TopLevelBindingGraph create( + ImmutableNetwork<Node, Edge> network, + boolean isFullBindingGraph) { TopLevelBindingGraph topLevelBindingGraph = new AutoValue_BindingGraph_TopLevelBindingGraph(network, isFullBindingGraph); @@ -194,8 +198,13 @@ } static BindingGraph create( - ComponentNode componentNode, TopLevelBindingGraph topLevelBindingGraph) { - return create(Optional.empty(), componentNode, topLevelBindingGraph); + ImmutableNetwork<Node, Edge> network, + boolean isFullBindingGraph) { + TopLevelBindingGraph topLevelBindingGraph = + TopLevelBindingGraph.create( + network, + isFullBindingGraph); + return create(Optional.empty(), topLevelBindingGraph.rootComponentNode(), topLevelBindingGraph); } private static BindingGraph create( @@ -278,6 +287,29 @@ return ((ComponentNodeImpl) componentNode()).componentDescriptor(); } + /** Returns all entry point methods for this component. */ + @Memoized + public ImmutableSet<ComponentMethodDescriptor> entryPointMethods() { + return componentDescriptor().entryPointMethods().stream() + .collect(toImmutableSet()); + } + + public Optional<ComponentMethodDescriptor> findFirstMatchingComponentMethod( + BindingRequest request) { + return Optional.ofNullable(firstMatchingComponentMethods().get(request)); + } + + @Memoized + ImmutableMap<BindingRequest, ComponentMethodDescriptor> firstMatchingComponentMethods() { + Map<BindingRequest, ComponentMethodDescriptor> componentMethodDescriptorsByRequest = + new HashMap<>(); + for (ComponentMethodDescriptor method : entryPointMethods()) { + componentMethodDescriptorsByRequest.putIfAbsent( + bindingRequest(method.dependencyRequest().get()), method); + } + return ImmutableMap.copyOf(componentMethodDescriptorsByRequest); + } + /** * Returns the {@link ContributionBinding} for the given {@link Key} in this component or {@link * Optional#empty()} if one doesn't exist.
diff --git a/java/dagger/internal/codegen/binding/BindingGraphFactory.java b/java/dagger/internal/codegen/binding/BindingGraphFactory.java index 5034359..a85721e 100644 --- a/java/dagger/internal/codegen/binding/BindingGraphFactory.java +++ b/java/dagger/internal/codegen/binding/BindingGraphFactory.java
@@ -18,49 +18,47 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static dagger.internal.codegen.base.RequestKinds.getRequestKind; -import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.base.Predicates.not; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedFactoryType; -import static dagger.internal.codegen.binding.SourceFiles.generatedMonitoringModuleName; +import static dagger.internal.codegen.binding.LegacyBindingGraphFactory.useLegacyBindingGraphFactory; +import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; +import static dagger.internal.codegen.extension.DaggerGraphs.unreachableNodes; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION; import static dagger.internal.codegen.model.BindingKind.DELEGATE; import static dagger.internal.codegen.model.BindingKind.INJECTION; import static dagger.internal.codegen.model.BindingKind.OPTIONAL; import static dagger.internal.codegen.model.BindingKind.SUBCOMPONENT_CREATOR; import static dagger.internal.codegen.model.RequestKind.MEMBERS_INJECTION; -import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf; -import static java.util.function.Predicate.isEqual; -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.ImmutableSet; -import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Iterables; -import com.google.common.collect.Multimaps; -import dagger.Reusable; -import dagger.internal.codegen.base.ClearableCache; -import dagger.internal.codegen.base.ContributionType; -import dagger.internal.codegen.base.DaggerSuperficialValidation; +import com.google.common.graph.ImmutableNetwork; +import com.google.common.graph.MutableNetwork; +import com.google.common.graph.NetworkBuilder; +import com.google.errorprone.annotations.CanIgnoreReturnValue; import dagger.internal.codegen.base.Keys; import dagger.internal.codegen.base.MapType; -import dagger.internal.codegen.base.OptionalType; +import dagger.internal.codegen.base.SetType; +import dagger.internal.codegen.base.TarjanSCCs; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingGraph.ComponentNode; +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.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 java.util.ArrayDeque; -import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -69,37 +67,35 @@ import java.util.Optional; import java.util.Queue; import java.util.Set; +import java.util.stream.Stream; import javax.inject.Inject; -import javax.inject.Singleton; +import javax.tools.Diagnostic; /** A factory for {@link BindingGraph} objects. */ -@Singleton -public final class BindingGraphFactory implements ClearableCache { - - private final XProcessingEnv processingEnv; +public final class BindingGraphFactory { + private final LegacyBindingGraphFactory legacyBindingGraphFactory; private final InjectBindingRegistry injectBindingRegistry; private final KeyFactory keyFactory; private final BindingFactory bindingFactory; - private final ModuleDescriptor.Factory moduleDescriptorFactory; - private final BindingGraphConverter bindingGraphConverter; - private final Map<Key, ImmutableSet<Key>> keysMatchingRequestCache = new HashMap<>(); + private final BindingNode.Factory bindingNodeFactory; + private final ComponentDeclarations.Factory componentDeclarationsFactory; private final CompilerOptions compilerOptions; @Inject BindingGraphFactory( - XProcessingEnv processingEnv, + LegacyBindingGraphFactory legacyBindingGraphFactory, InjectBindingRegistry injectBindingRegistry, KeyFactory keyFactory, BindingFactory bindingFactory, - ModuleDescriptor.Factory moduleDescriptorFactory, - BindingGraphConverter bindingGraphConverter, + BindingNode.Factory bindingNodeFactory, + ComponentDeclarations.Factory componentDeclarationsFactory, CompilerOptions compilerOptions) { - this.processingEnv = processingEnv; + this.legacyBindingGraphFactory = legacyBindingGraphFactory; this.injectBindingRegistry = injectBindingRegistry; this.keyFactory = keyFactory; this.bindingFactory = bindingFactory; - this.moduleDescriptorFactory = moduleDescriptorFactory; - this.bindingGraphConverter = bindingGraphConverter; + this.bindingNodeFactory = bindingNodeFactory; + this.componentDeclarationsFactory = componentDeclarationsFactory; this.compilerOptions = compilerOptions; } @@ -111,293 +107,117 @@ */ public BindingGraph create( ComponentDescriptor componentDescriptor, boolean createFullBindingGraph) { - return bindingGraphConverter.convert( - createLegacyBindingGraph(Optional.empty(), componentDescriptor, createFullBindingGraph), + return useLegacyBindingGraphFactory(compilerOptions, componentDescriptor) + ? legacyBindingGraphFactory.create(componentDescriptor, createFullBindingGraph) + : createBindingGraph(componentDescriptor, createFullBindingGraph); + } + + private BindingGraph createBindingGraph( + ComponentDescriptor componentDescriptor, boolean createFullBindingGraph) { + Resolver resolver = new Resolver(componentDescriptor); + resolver.resolve(createFullBindingGraph); + + MutableNetwork<Node, Edge> network = resolver.network; + if (!createFullBindingGraph) { + unreachableNodes(network.asGraph(), resolver.componentNode).forEach(network::removeNode); + } + + network = BindingGraphTransformations.withFixedBindingTypes(network); + return BindingGraph.create( + ImmutableNetwork.copyOf(network), createFullBindingGraph); } - private LegacyBindingGraph createLegacyBindingGraph( - Optional<Resolver> parentResolver, - ComponentDescriptor componentDescriptor, - boolean createFullBindingGraph) { - ImmutableSet.Builder<ContributionBinding> explicitBindingsBuilder = ImmutableSet.builder(); - ImmutableSet.Builder<DelegateDeclaration> delegatesBuilder = ImmutableSet.builder(); - ImmutableSet.Builder<OptionalBindingDeclaration> optionalsBuilder = ImmutableSet.builder(); - - if (componentDescriptor.isRealComponent()) { - // binding for the component itself - explicitBindingsBuilder.add( - bindingFactory.componentBinding(componentDescriptor.typeElement())); - } - - // Collect Component dependencies. - for (ComponentRequirement dependency : componentDescriptor.dependencies()) { - explicitBindingsBuilder.add(bindingFactory.componentDependencyBinding(dependency)); - - // Within a component dependency, we want to allow the same method to appear multiple - // times assuming it is the exact same method. We do this by tracking a set of bindings - // we've already added with the binding element removed since that is the only thing - // allowed to differ. - HashMultimap<String, ContributionBinding> dedupeBindings = HashMultimap.create(); - XTypeElements.getAllMethods(dependency.typeElement()).stream() - // MembersInjection methods aren't "provided" explicitly, so ignore them. - .filter(ComponentDescriptor::isComponentContributionMethod) - .forEach( - method -> { - ContributionBinding binding = - bindingFactory.componentDependencyMethodBinding(componentDescriptor, method); - if (dedupeBindings.put( - getSimpleName(method), - // Remove the binding element since we know that will be different, but - // everything else we want to be the same to consider it a duplicate. - binding.toBuilder().clearBindingElement().build())) { - explicitBindingsBuilder.add(binding); - } - }); - } - - // Collect bindings on the creator. - componentDescriptor - .creatorDescriptor() - .ifPresent( - creatorDescriptor -> - creatorDescriptor.boundInstanceRequirements().stream() - .map( - requirement -> - bindingFactory.boundInstanceBinding( - requirement, creatorDescriptor.elementForRequirement(requirement))) - .forEach(explicitBindingsBuilder::add)); - - componentDescriptor - .childComponentsDeclaredByBuilderEntryPoints() - .forEach( - (builderEntryPoint, childComponent) -> { - if (!componentDescriptor - .childComponentsDeclaredByModules() - .contains(childComponent)) { - explicitBindingsBuilder.add( - bindingFactory.subcomponentCreatorBinding( - builderEntryPoint.methodElement(), componentDescriptor.typeElement())); - } - }); - - ImmutableSet.Builder<MultibindingDeclaration> multibindingDeclarations = ImmutableSet.builder(); - ImmutableSet.Builder<SubcomponentDeclaration> subcomponentDeclarations = ImmutableSet.builder(); - - // Collect transitive module bindings and multibinding declarations. - ImmutableSet<ModuleDescriptor> modules = modules(componentDescriptor, parentResolver); - for (ModuleDescriptor moduleDescriptor : modules) { - explicitBindingsBuilder.addAll(moduleDescriptor.bindings()); - multibindingDeclarations.addAll(moduleDescriptor.multibindingDeclarations()); - subcomponentDeclarations.addAll(moduleDescriptor.subcomponentDeclarations()); - delegatesBuilder.addAll(moduleDescriptor.delegateDeclarations()); - 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()), - indexBindingDeclarationsByKey(multibindingDeclarations.build()), - indexBindingDeclarationsByKey(subcomponentDeclarations.build()), - indexBindingDeclarationsByKey(delegatesBuilder.build()), - indexBindingDeclarationsByKey(optionalsBuilder.build())); - - componentDescriptor.entryPointMethods().stream() - .map(method -> method.dependencyRequest().get()) - .forEach( - entryPoint -> { - if (entryPoint.kind().equals(MEMBERS_INJECTION)) { - requestResolver.resolveMembersInjection(entryPoint.key()); - } else { - requestResolver.resolve(entryPoint.key()); - } - }); - - if (createFullBindingGraph) { - // Resolve the keys for all bindings in all modules, stripping any multibinding contribution - // identifier so that the multibinding itself is resolved. - modules.stream() - .flatMap(module -> module.allBindingKeys().stream()) - .map(Key::withoutMultibindingContributionIdentifier) - .forEach(requestResolver::resolve); - } - - // Resolve all bindings for subcomponents, creating subgraphs for all subcomponents that have - // been detected during binding resolution. If a binding for a subcomponent is never resolved, - // no BindingGraph will be created for it and no implementation will be generated. This is - // done in a queue since resolving one subcomponent might resolve a key for a subcomponent - // from a parent graph. This is done until no more new subcomponents are resolved. - Set<ComponentDescriptor> resolvedSubcomponents = new HashSet<>(); - ImmutableList.Builder<LegacyBindingGraph> subgraphs = ImmutableList.builder(); - for (ComponentDescriptor subcomponent : - Iterables.consumingIterable(requestResolver.subcomponentsToResolve)) { - if (resolvedSubcomponents.add(subcomponent)) { - subgraphs.add( - createLegacyBindingGraph( - Optional.of(requestResolver), subcomponent, createFullBindingGraph)); - } - } - - return new LegacyBindingGraph(requestResolver, subgraphs.build()); - } - - /** - * Returns all the modules that should be installed in the component. For production components - * and production subcomponents that have a parent that is not a production component or - * subcomponent, also includes the production monitoring module for the component and the - * production executor module. - */ - private ImmutableSet<ModuleDescriptor> modules( - ComponentDescriptor componentDescriptor, Optional<Resolver> parentResolver) { - return shouldIncludeImplicitProductionModules(componentDescriptor, parentResolver) - ? new ImmutableSet.Builder<ModuleDescriptor>() - .addAll(componentDescriptor.modules()) - .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 componentDescriptor, Optional<Resolver> parentResolver) { - return componentDescriptor.isProduction() - && componentDescriptor.isRealComponent() - && (parentResolver.isEmpty() || !parentResolver.get().componentDescriptor.isProduction()); - } - - /** Indexes {@code bindingDeclarations} by {@link BindingDeclaration#key()}. */ - private static <T extends BindingDeclaration> - ImmutableSetMultimap<Key, T> indexBindingDeclarationsByKey(Iterable<T> declarations) { - return ImmutableSetMultimap.copyOf(Multimaps.index(declarations, BindingDeclaration::key)); - } - - @Override - public void clearCache() { - 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 ComponentNode componentNode; final ComponentDescriptor componentDescriptor; - final ImmutableSetMultimap<Key, ContributionBinding> explicitBindings; - final ImmutableSet<ContributionBinding> explicitBindingsSet; - final ImmutableSetMultimap<Key, ContributionBinding> explicitMultibindings; - final ImmutableSetMultimap<Key, MultibindingDeclaration> multibindingDeclarations; - final ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations; - final ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations; - final ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations; - final ImmutableSetMultimap<Key, DelegateDeclaration> delegateMultibindingDeclarations; + final ComponentDeclarations declarations; + final MutableNetwork<Node, Edge> network; final Map<Key, ResolvedBindings> resolvedContributionBindings = new LinkedHashMap<>(); final Map<Key, ResolvedBindings> resolvedMembersInjectionBindings = new LinkedHashMap<>(); - final Deque<Key> cycleStack = new ArrayDeque<>(); - final Map<Key, Boolean> keyDependsOnLocalBindingsCache = new HashMap<>(); - final Map<Binding, Boolean> bindingDependsOnLocalBindingsCache = new HashMap<>(); + final RequiresResolutionChecker requiresResolutionChecker = new RequiresResolutionChecker(); final Queue<ComponentDescriptor> subcomponentsToResolve = new ArrayDeque<>(); - Resolver( - ComponentPath componentPath, - Optional<Resolver> parentResolver, - ComponentDescriptor componentDescriptor, - ImmutableSetMultimap<Key, ContributionBinding> explicitBindings, - ImmutableSetMultimap<Key, MultibindingDeclaration> multibindingDeclarations, - ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponentDeclarations, - ImmutableSetMultimap<Key, DelegateDeclaration> delegateDeclarations, - ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindingDeclarations) { - this.componentPath = componentPath; + Resolver(ComponentDescriptor componentDescriptor) { + this(Optional.empty(), componentDescriptor); + } + + Resolver(Resolver parentResolver, ComponentDescriptor componentDescriptor) { + this(Optional.of(parentResolver), componentDescriptor); + } + + private Resolver(Optional<Resolver> parentResolver, ComponentDescriptor componentDescriptor) { this.parentResolver = parentResolver; this.componentDescriptor = checkNotNull(componentDescriptor); - this.explicitBindings = checkNotNull(explicitBindings); - this.explicitBindingsSet = ImmutableSet.copyOf(explicitBindings.values()); - this.multibindingDeclarations = checkNotNull(multibindingDeclarations); - this.subcomponentDeclarations = checkNotNull(subcomponentDeclarations); - this.delegateDeclarations = checkNotNull(delegateDeclarations); - this.optionalBindingDeclarations = checkNotNull(optionalBindingDeclarations); - this.explicitMultibindings = multibindingContributionsByMultibindingKey(explicitBindingsSet); - this.delegateMultibindingDeclarations = - multibindingContributionsByMultibindingKey(delegateDeclarations.values()); + DaggerTypeElement componentType = DaggerTypeElement.from(componentDescriptor.typeElement()); + componentPath = + parentResolver.isPresent() + ? parentResolver.get().componentPath.childPath(componentType) + : ComponentPath.create(ImmutableList.of(componentType)); + this.componentNode = ComponentNodeImpl.create(componentPath, componentDescriptor); + this.network = + parentResolver.isPresent() + ? parentResolver.get().network + : NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); + declarations = + componentDeclarationsFactory.create( + parentResolver.map(parent -> parent.componentDescriptor), + componentDescriptor); subcomponentsToResolve.addAll( componentDescriptor.childComponentsDeclaredByFactoryMethods().values()); subcomponentsToResolve.addAll( componentDescriptor.childComponentsDeclaredByBuilderEntryPoints().values()); } + void resolve(boolean createFullBindingGraph) { + addNode(componentNode); + + componentDescriptor.entryPointMethods().stream() + .map(method -> method.dependencyRequest().get()) + .forEach( + entryPoint -> { + ResolvedBindings resolvedBindings = + entryPoint.kind().equals(MEMBERS_INJECTION) + ? resolveMembersInjectionKey(entryPoint.key()) + : resolveContributionKey(entryPoint.key()); + addDependencyEdges(componentNode, resolvedBindings, entryPoint); + }); + + if (createFullBindingGraph) { + // Resolve the keys for all bindings in all modules, stripping any multibinding contribution + // identifier so that the multibinding itself is resolved. + declarations.allDeclarations().stream() + // TODO(b/349155899): Consider resolving all declarations in full binding graph mode, + // not just those from modules. + .filter(declaration -> declaration.contributingModule().isPresent()) + // @BindsOptionalOf bindings are keyed by the unwrapped type so wrap it in Optional to + // resolve the optional type instead. + .map( + declaration -> + declaration instanceof OptionalBindingDeclaration + ? keyFactory.optionalOf(declaration.key()) + : declaration.key()) + .map(Key::withoutMultibindingContributionIdentifier) + .forEach(this::resolveContributionKey); + } + + // Resolve all bindings for subcomponents, creating subgraphs for all subcomponents that have + // been detected during binding resolution. If a binding for a subcomponent is never resolved, + // no BindingGraph will be created for it and no implementation will be generated. This is + // done in a queue since resolving one subcomponent might resolve a key for a subcomponent + // from a parent graph. This is done until no more new subcomponents are resolved. + Set<ComponentDescriptor> resolvedSubcomponents = new HashSet<>(); + for (ComponentDescriptor subcomponent : Iterables.consumingIterable(subcomponentsToResolve)) { + if (resolvedSubcomponents.add(subcomponent)) { + Resolver subcomponentResolver = new Resolver(this, subcomponent); + addChildFactoryMethodEdge(subcomponentResolver); + subcomponentResolver.resolve(createFullBindingGraph); + } + } + } + /** * Returns the resolved contribution bindings for the given {@link Key}: * @@ -421,38 +241,42 @@ Set<SubcomponentDeclaration> subcomponentDeclarations = new LinkedHashSet<>(); // Gather all bindings, multibindings, optional, and subcomponent declarations/contributions. - ImmutableSet<Key> keysMatchingRequest = keysMatchingRequest(requestKey); for (Resolver resolver : getResolverLineage()) { bindings.addAll(resolver.getLocalExplicitBindings(requestKey)); - - for (Key key : keysMatchingRequest) { - multibindingContributions.addAll(resolver.getLocalExplicitMultibindings(key)); - multibindingDeclarations.addAll(resolver.multibindingDeclarations.get(key)); - subcomponentDeclarations.addAll(resolver.subcomponentDeclarations.get(key)); - // The optional binding declarations are keyed by the unwrapped type. - keyFactory.unwrapOptional(key) - .map(resolver.optionalBindingDeclarations::get) - .ifPresent(optionalBindingDeclarations::addAll); - } + multibindingContributions.addAll(resolver.getLocalMultibindingContributions(requestKey)); + multibindingDeclarations.addAll(resolver.declarations.multibindings(requestKey)); + subcomponentDeclarations.addAll(resolver.declarations.subcomponents(requestKey)); + // The optional binding declarations are keyed by the unwrapped type. + keyFactory.unwrapOptional(requestKey) + .map(resolver.declarations::optionalBindings) + .ifPresent(optionalBindingDeclarations::addAll); } // Add synthetic multibinding if (!multibindingContributions.isEmpty() || !multibindingDeclarations.isEmpty()) { - bindings.add(bindingFactory.syntheticMultibinding(requestKey, multibindingContributions)); + if (MapType.isMap(requestKey)) { + bindings.add(bindingFactory.multiboundMap(requestKey, multibindingContributions)); + } else if (SetType.isSet(requestKey)) { + bindings.add(bindingFactory.multiboundSet(requestKey, multibindingContributions)); + } else { + throw new AssertionError("Unexpected type in multibinding key: " + requestKey); + } } // Add synthetic optional binding if (!optionalBindingDeclarations.isEmpty()) { + ImmutableSet<Binding> optionalContributions = + lookUpBindings(keyFactory.unwrapOptional(requestKey).get()).bindings(); bindings.add( - bindingFactory.syntheticOptionalBinding( - requestKey, - getRequestKind(OptionalType.from(requestKey).valueType()), - lookUpBindings(keyFactory.unwrapOptional(requestKey).get()).bindings())); + optionalContributions.isEmpty() + ? bindingFactory.syntheticAbsentOptionalDeclaration(requestKey) + : bindingFactory.syntheticPresentOptionalDeclaration( + requestKey, optionalContributions)); } // Add subcomponent creator binding if (!subcomponentDeclarations.isEmpty()) { - ProvisionBinding binding = + ContributionBinding binding = bindingFactory.subcomponentCreatorBinding( ImmutableSet.copyOf(subcomponentDeclarations)); bindings.add(binding); @@ -461,9 +285,7 @@ // Add members injector binding if (isTypeOf(requestKey.type().xprocessing(), TypeNames.MEMBERS_INJECTOR)) { - injectBindingRegistry - .getOrFindMembersInjectorProvisionBinding(requestKey) - .ifPresent(bindings::add); + injectBindingRegistry.getOrFindMembersInjectorBinding(requestKey).ifPresent(bindings::add); } // Add Assisted Factory binding @@ -478,18 +300,32 @@ // If there are no bindings, add the implicit @Inject-constructed binding if there is one. if (bindings.isEmpty()) { injectBindingRegistry - .getOrFindProvisionBinding(requestKey) + .getOrFindInjectionBinding(requestKey) .filter(this::isCorrectlyScopedInSubcomponent) .ifPresent(bindings::add); } - return ResolvedBindings.forContributionBindings( - componentPath, + return ResolvedBindings.create( requestKey, - Multimaps.index(bindings, binding -> getOwningComponent(requestKey, binding)), - multibindingDeclarations, - subcomponentDeclarations, - optionalBindingDeclarations); + bindings.stream() + .map( + binding -> { + Optional<BindingNode> bindingNodeOwnedByAncestor = + getBindingNodeOwnedByAncestor(requestKey, binding); + // If a binding is owned by an ancestor we use the corresponding BindingNode + // instance directly rather than creating a new instance to avoid accidentally + // including additional multi/optional/subcomponent declarations that don't + // exist in the ancestor's BindingNode instance. + return bindingNodeOwnedByAncestor.isPresent() + ? bindingNodeOwnedByAncestor.get() + : bindingNodeFactory.forContributionBindings( + componentPath, + binding, + multibindingDeclarations, + optionalBindingDeclarations, + subcomponentDeclarations); + }) + .collect(toImmutableSet())); } /** @@ -499,7 +335,7 @@ * be owned by a future ancestor (or, if never owned, will result in an incompatibly scoped * binding error at the root component). */ - private boolean isCorrectlyScopedInSubcomponent(ProvisionBinding binding) { + private boolean isCorrectlyScopedInSubcomponent(ContributionBinding binding) { checkArgument(binding.kind() == INJECTION || binding.kind() == ASSISTED_INJECTION); if (!rootComponent().isSubcomponent() || !binding.scope().isPresent() @@ -522,9 +358,10 @@ Optional<MembersInjectionBinding> binding = injectBindingRegistry.getOrFindMembersInjectionBinding(requestKey); return binding.isPresent() - ? ResolvedBindings.forMembersInjectionBinding( - componentPath, requestKey, componentDescriptor, binding.get()) - : ResolvedBindings.noBindings(componentPath, requestKey); + ? ResolvedBindings.create( + requestKey, + bindingNodeFactory.forMembersInjectionBinding(componentPath, binding.get())) + : ResolvedBindings.create(requestKey); } /** @@ -532,7 +369,7 @@ * ComponentDescriptor subcomponent} to a queue in the owning component's resolver. The queue * will be used to detect which subcomponents need to be resolved. */ - private void addSubcomponentToOwningResolver(ProvisionBinding subcomponentCreatorBinding) { + private void addSubcomponentToOwningResolver(ContributionBinding subcomponentCreatorBinding) { checkArgument(subcomponentCreatorBinding.kind().equals(SUBCOMPONENT_CREATOR)); Resolver owningResolver = getOwningResolver(subcomponentCreatorBinding).get(); @@ -542,126 +379,51 @@ owningResolver.componentDescriptor.getChildComponentWithBuilderType(builderType)); } - /** - * Profiling has determined that computing the keys matching {@code requestKey} has measurable - * performance impact. It is called repeatedly (at least 3 times per key resolved per {@link - * BindingGraph}. {@code javac}'s name-checking performance seems suboptimal (converting byte - * strings to Strings repeatedly), and the matching keys creations relies on that. This also - * ensures that the resulting keys have their hash codes cached on successive calls to this - * method. - * - * <p>This caching may become obsolete if: - * - * <ul> - * <li>We decide to intern all {@link Key} instances - * <li>We fix javac's name-checking peformance (though we may want to keep this for older - * javac users) - * </ul> - */ - private ImmutableSet<Key> keysMatchingRequest(Key requestKey) { - return keysMatchingRequestCache.computeIfAbsent( - requestKey, this::keysMatchingRequestUncached); - } - - private ImmutableSet<Key> keysMatchingRequestUncached(Key requestKey) { - ImmutableSet.Builder<Key> keys = ImmutableSet.builder(); - keys.add(requestKey); - keyFactory.unwrapSetKey(requestKey, TypeNames.PRODUCED).ifPresent(keys::add); - keyFactory - .rewrapMapKey(requestKey, TypeNames.PRODUCER, TypeNames.PROVIDER) - .ifPresent(keys::add); - keyFactory - .rewrapMapKey(requestKey, TypeNames.PROVIDER, TypeNames.PRODUCER) - .ifPresent(keys::add); - keys.addAll(keyFactory.implicitFrameworkMapKeys(requestKey)); - return keys.build(); - } - private ImmutableSet<ContributionBinding> createDelegateBindings( ImmutableSet<DelegateDeclaration> delegateDeclarations) { ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder(); for (DelegateDeclaration delegateDeclaration : delegateDeclarations) { - builder.add(createDelegateBinding(delegateDeclaration)); + builder.add(bindingFactory.delegateBinding(delegateDeclaration)); } return builder.build(); } - /** - * Creates one (and only one) delegate binding for a delegate declaration, based on the resolved - * bindings of the right-hand-side of a {@link dagger.Binds} method. If there are duplicate - * bindings for the dependency key, there should still be only one binding for the delegate key. + * Returns a {@link BindingNode} for the given binding that is owned by an ancestor component, + * if one exists. Otherwise returns {@link Optional#empty()}. */ - private ContributionBinding createDelegateBinding(DelegateDeclaration delegateDeclaration) { - Key delegateKey = delegateDeclaration.delegateRequest().key(); - if (cycleStack.contains(delegateKey)) { - return bindingFactory.unresolvedDelegateBinding(delegateDeclaration); + private Optional<BindingNode> getBindingNodeOwnedByAncestor( + Key requestKey, ContributionBinding binding) { + if (canBeResolvedInParent(requestKey, binding)) { + // Resolve in the parent to make sure we have the most recent multi/optional contributions. + parentResolver.get().resolveContributionKey(requestKey); + BindingNode previouslyResolvedBinding = + getPreviouslyResolvedBindings(requestKey).get().forBinding(binding); + if (!requiresResolutionChecker.requiresResolution(previouslyResolvedBinding)) { + return Optional.of(previouslyResolvedBinding); + } } - - ResolvedBindings resolvedDelegate; - try { - cycleStack.push(delegateKey); - resolvedDelegate = lookUpBindings(delegateKey); - } finally { - cycleStack.pop(); - } - if (resolvedDelegate.contributionBindings().isEmpty()) { - // This is guaranteed to result in a missing binding error, so it doesn't matter if the - // binding is a Provision or Production, except if it is a @IntoMap method, in which - // case the key will be of type Map<K, Provider<V>>, which will be "upgraded" into a - // Map<K, Producer<V>> if it's requested in a ProductionComponent. This may result in a - // strange error, that the RHS needs to be provided with an @Inject or @Provides - // annotated method, but a user should be able to figure out if a @Produces annotation - // is needed. - // TODO(gak): revisit how we model missing delegates if/when we clean up how we model - // binding declarations - return bindingFactory.unresolvedDelegateBinding(delegateDeclaration); - } - // It doesn't matter which of these is selected, since they will later on produce a - // duplicate binding error. - ContributionBinding explicitDelegate = - resolvedDelegate.contributionBindings().iterator().next(); - return bindingFactory.delegateBinding(delegateDeclaration, explicitDelegate); + return Optional.empty(); } - /** - * Returns the component that should contain the framework field for {@code binding}. - * - * <p>If {@code binding} is either not bound in an ancestor component or depends transitively on - * bindings in this component, returns this component. - * - * <p>Otherwise, resolves {@code request} in this component's parent in order to resolve any - * multibinding contributions in the parent, and returns the parent-resolved {@link - * ResolvedBindings#owningComponent(ContributionBinding)}. - */ - private XTypeElement getOwningComponent(Key requestKey, ContributionBinding binding) { - if (isResolvedInParent(requestKey, binding) && !requiresResolution(binding)) { - ResolvedBindings parentResolvedBindings = - parentResolver.get().resolvedContributionBindings.get(requestKey); - return parentResolvedBindings.owningComponent(binding); - } else { - return componentDescriptor.typeElement(); - } - } - - /** - * Returns {@code true} if {@code binding} is owned by an ancestor. If so, {@linkplain #resolve - * resolves} the {@link Key} in this component's parent. Don't resolve directly in the owning - * component in case it depends on multibindings in any of its descendants. - */ - private boolean isResolvedInParent(Key requestKey, ContributionBinding binding) { - Optional<Resolver> owningResolver = getOwningResolver(binding); - if (owningResolver.isPresent() && !owningResolver.get().equals(this)) { - parentResolver.get().resolve(requestKey); - return true; - } else { + private boolean canBeResolvedInParent(Key requestKey, ContributionBinding binding) { + if (parentResolver.isEmpty()) { return false; } + Optional<Resolver> owningResolver = getOwningResolver(binding); + if (owningResolver.isPresent()) { + return !owningResolver.get().equals(this); + } + return !Keys.isComponentOrCreator(requestKey) + // TODO(b/305748522): Allow caching for assisted injection bindings. + && binding.kind() != BindingKind.ASSISTED_INJECTION + && getPreviouslyResolvedBindings(requestKey).isPresent() + && getPreviouslyResolvedBindings(requestKey).get().bindings().contains(binding); } private Optional<Resolver> getOwningResolver(ContributionBinding binding) { // TODO(ronshapiro): extract the different pieces of this method into their own methods if ((binding.scope().isPresent() && binding.scope().get().isProductionScope()) - || binding.bindingType().equals(BindingType.PRODUCTION)) { + || binding.kind().equals(BindingKind.PRODUCTION)) { for (Resolver requestResolver : getResolverLineage()) { // Resolve @Inject @ProductionScope bindings at the highest production component. if (binding.kind().equals(INJECTION) @@ -682,8 +444,7 @@ // If a @Reusable binding was resolved in an ancestor, use that component. ResolvedBindings resolvedBindings = requestResolver.resolvedContributionBindings.get(binding.key()); - if (resolvedBindings != null - && resolvedBindings.contributionBindings().contains(binding)) { + if (resolvedBindings != null && resolvedBindings.bindings().contains(binding)) { return Optional.of(requestResolver); } } @@ -691,6 +452,9 @@ return Optional.empty(); } + // TODO(b/359893922): we currently iterate from child to parent to find an owning resolver, + // but we probably want to iterate from parent to child to catch missing bindings in + // misconfigured repeated modules. for (Resolver requestResolver : getResolverLineage().reverse()) { if (requestResolver.containsExplicitBinding(binding)) { return Optional.of(requestResolver); @@ -711,9 +475,9 @@ } private boolean containsExplicitBinding(ContributionBinding binding) { - return explicitBindingsSet.contains(binding) + return declarations.bindings(binding.key()).contains(binding) || resolverContainsDelegateDeclarationForBinding(binding) - || subcomponentDeclarations.containsKey(binding.key()); + || !declarations.subcomponents(binding.key()).isEmpty(); } /** Returns true if {@code binding} was installed in a module in this resolver's component. */ @@ -721,18 +485,10 @@ if (!binding.kind().equals(DELEGATE)) { return false; } - - // Map multibinding key values are wrapped with a framework type. This needs to be undone - // to look it up in the delegate declarations map. - // TODO(erichang): See if we can standardize the way map keys are used in these data - // structures, either always wrapped or unwrapped to be consistent and less errorprone. - Key bindingKey = binding.key(); - if (compilerOptions.strictMultibindingValidation() - && binding.contributionType().equals(ContributionType.MAP)) { - bindingKey = keyFactory.unwrapMapValueType(bindingKey); + if (LegacyBindingGraphFactory.hasStrictMultibindingsExemption(compilerOptions, binding)) { + return false; } - - return delegateDeclarations.get(bindingKey).stream() + return declarations.delegates(binding.key()).stream() .anyMatch( declaration -> declaration.contributingModule().equals(binding.contributingModule()) @@ -755,15 +511,9 @@ * resolver. */ private ImmutableSet<ContributionBinding> getLocalExplicitBindings(Key key) { - return new ImmutableSet.Builder<ContributionBinding>() - .addAll(explicitBindings.get(key)) - // @Binds @IntoMap declarations have key Map<K, V>, unlike @Provides @IntoMap or @Produces - // @IntoMap, which have Map<K, Provider/Producer<V>> keys. So unwrap the key's type's - // value type if it's a Map<K, Provider/Producer<V>> before looking in - // delegateDeclarations. createDelegateBindings() will create bindings with the properly - // wrapped key type. - .addAll( - createDelegateBindings(delegateDeclarations.get(keyFactory.unwrapMapValueType(key)))) + return ImmutableSet.<ContributionBinding>builder() + .addAll(declarations.bindings(key)) + .addAll(createDelegateBindings(declarations.delegates(key))) .build(); } @@ -771,22 +521,11 @@ * Returns the explicit multibinding contributions that contribute to the map or set requested * by {@code key} from this resolver. */ - private ImmutableSet<ContributionBinding> getLocalExplicitMultibindings(Key key) { - ImmutableSet.Builder<ContributionBinding> multibindings = ImmutableSet.builder(); - multibindings.addAll(explicitMultibindings.get(key)); - if (!MapType.isMap(key) - || MapType.from(key).isRawType() - || MapType.from(key).valuesAreFrameworkType()) { - // @Binds @IntoMap declarations have key Map<K, V>, unlike @Provides @IntoMap or @Produces - // @IntoMap, which have Map<K, Provider/Producer<V>> keys. So unwrap the key's type's - // value type if it's a Map<K, Provider/Producer<V>> before looking in - // delegateMultibindingDeclarations. createDelegateBindings() will create bindings with the - // properly wrapped key type. - multibindings.addAll( - createDelegateBindings( - delegateMultibindingDeclarations.get(keyFactory.unwrapMapValueType(key)))); - } - return multibindings.build(); + private ImmutableSet<ContributionBinding> getLocalMultibindingContributions(Key key) { + return ImmutableSet.<ContributionBinding>builder() + .addAll(declarations.multibindingContributions(key)) + .addAll(createDelegateBindings(declarations.delegateMultibindingContributions(key))) + .build(); } /** @@ -795,12 +534,12 @@ */ private ImmutableSet<OptionalBindingDeclaration> getOptionalBindingDeclarations(Key key) { Optional<Key> unwrapped = keyFactory.unwrapOptional(key); - if (!unwrapped.isPresent()) { + if (unwrapped.isEmpty()) { return ImmutableSet.of(); } ImmutableSet.Builder<OptionalBindingDeclaration> declarations = ImmutableSet.builder(); for (Resolver resolver : getResolverLineage()) { - declarations.addAll(resolver.optionalBindingDeclarations.get(unwrapped.get())); + declarations.addAll(resolver.declarations.optionalBindings(unwrapped.get())); } return declarations.build(); } @@ -811,242 +550,330 @@ * MembersInjectionBinding}s are not inherited. */ private Optional<ResolvedBindings> getPreviouslyResolvedBindings(Key key) { - Optional<ResolvedBindings> result = - Optional.ofNullable(resolvedContributionBindings.get(key)); - if (result.isPresent()) { - return result; - } else if (parentResolver.isPresent()) { - return parentResolver.get().getPreviouslyResolvedBindings(key); - } else { + if (parentResolver.isEmpty()) { return Optional.empty(); } + // Check the parent's resolvedContributionBindings directly before calling + // parentResolver.getPreviouslyResolvedBindings() otherwise the parent will skip itself. + return parentResolver.get().resolvedContributionBindings.containsKey(key) + ? Optional.of(parentResolver.get().resolvedContributionBindings.get(key)) + : parentResolver.get().getPreviouslyResolvedBindings(key); } - private void resolveMembersInjection(Key key) { + private ResolvedBindings resolveMembersInjectionKey(Key key) { + if (resolvedMembersInjectionBindings.containsKey(key)) { + return resolvedMembersInjectionBindings.get(key); + } ResolvedBindings bindings = lookUpMembersInjectionBinding(key); + addNodes(bindings); resolveDependencies(bindings); resolvedMembersInjectionBindings.put(key, bindings); + return bindings; } - void resolve(Key key) { - // If we find a cycle, stop resolving. The original request will add it with all of the - // other resolved deps. - if (cycleStack.contains(key)) { - return; - } - - // If the binding was previously resolved in this (sub)component, don't resolve it again. - if (resolvedContributionBindings.containsKey(key)) { - return; - } - - /* - * If the binding was previously resolved in an ancestor component, then we may be able to - * avoid resolving it here and just depend on the ancestor component resolution. - * - * 1. If it depends transitively on multibinding contributions or optional bindings with - * bindings from this subcomponent, then we have to resolve it in this subcomponent so - * that it sees the local bindings. - * - * 2. If there are any explicit bindings in this component, they may conflict with those in - * the ancestor component, so resolve them here so that conflicts can be caught. - */ - if (getPreviouslyResolvedBindings(key).isPresent() && !Keys.isComponentOrCreator(key)) { - /* 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); - 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, previouslyResolvedBindings); - return; - } - } - - cycleStack.push(key); - try { - ResolvedBindings bindings = lookUpBindings(key); - resolvedContributionBindings.put(key, bindings); - resolveDependencies(bindings); - } finally { - cycleStack.pop(); - } - } - - /** - * {@link #resolve(Key) Resolves} each of the dependencies of the bindings owned by this - * component. - */ - private void resolveDependencies(ResolvedBindings resolvedBindings) { - for (Binding binding : resolvedBindings.bindingsOwnedBy(componentDescriptor)) { - for (DependencyRequest dependency : binding.dependencies()) { - resolve(dependency.key()); - } - } - } - - private ResolvedBindings getResolvedContributionBindings(Key key) { + @CanIgnoreReturnValue + private ResolvedBindings resolveContributionKey(Key key) { if (resolvedContributionBindings.containsKey(key)) { return resolvedContributionBindings.get(key); } - if (parentResolver.isPresent()) { - return parentResolver.get().getResolvedContributionBindings(key); + ResolvedBindings bindings = lookUpBindings(key); + resolvedContributionBindings.put(key, bindings); + addNodes(bindings); + resolveDependencies(bindings); + return bindings; + } + + /** Resolves each of the dependencies of the bindings owned by this component. */ + private void resolveDependencies(ResolvedBindings resolvedBindings) { + for (BindingNode binding : resolvedBindings.bindingNodesOwnedBy(componentPath)) { + for (DependencyRequest request : binding.dependencies()) { + ResolvedBindings dependencies = resolveContributionKey(request.key()); + addDependencyEdges(binding, dependencies, request); + } } - throw new AssertionError("No resolved bindings for key: " + key); } - private ResolvedBindings getResolvedMembersInjectionBindings(Key key) { - return resolvedMembersInjectionBindings.get(key); + private void addNodes(ResolvedBindings resolvedBindings) { + if (resolvedBindings.isEmpty()) { + addNode(missingBinding(resolvedBindings.key())); + return; + } + resolvedBindings.bindingNodesOwnedBy(componentPath).forEach(this::addNode); } - private boolean requiresResolution(Key key) { - return new LegacyRequiresResolutionChecker().requiresResolution(key); + private void addNode(Node node) { + network.addNode(node); + // Subcomponent creator bindings have an implicit edge to the subcomponent they create. + if (node instanceof BindingNode && ((BindingNode) node).kind() == SUBCOMPONENT_CREATOR) { + addSubcomponentEdge((BindingNode) node); + } } - private boolean requiresResolution(Binding binding) { - return new LegacyRequiresResolutionChecker().requiresResolution(binding); + private void addDependencyEdges( + Node parent, ResolvedBindings dependencies, DependencyRequest request) { + if (dependencies.isEmpty()) { + addDependencyEdge(parent, missingBinding(request.key()), request); + } else { + dependencies.bindingNodes() + .forEach(dependency -> addDependencyEdge(parent, dependency, request)); + } } - private final class LegacyRequiresResolutionChecker { - private final Set<Object> cycleChecker = new HashSet<>(); + private void addDependencyEdge(Node source, Node target, DependencyRequest request) { + boolean isEntryPoint = source instanceof ComponentNode; + addEdge(source, target, new DependencyEdgeImpl(request, isEntryPoint)); + } - /** - * Returns {@code true} if any of the bindings resolved for {@code key} are multibindings with - * contributions declared within this component's modules or optional bindings with present - * values declared within this component's modules, or if any of its unscoped dependencies - * depend on such bindings. - * - * <p>We don't care about scoped dependencies because they will never depend on bindings from - * subcomponents. - * - * @throws IllegalArgumentException if {@link #getPreviouslyResolvedBindings(Key)} is empty - */ - 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)) { + private void addSubcomponentEdge(BindingNode binding) { + checkState(binding.kind() == SUBCOMPONENT_CREATOR); + Resolver owningResolver = + getResolverLineage().reverse().stream() + .filter(resolver -> resolver.componentPath.equals(binding.componentPath())) + .collect(onlyElement()); + ComponentDescriptor subcomponent = + owningResolver.componentDescriptor.getChildComponentWithBuilderType( + binding.key().type().xprocessing().getTypeElement()); + ComponentNode subcomponentNode = + ComponentNodeImpl.create( + owningResolver.componentPath.childPath( + DaggerTypeElement.from(subcomponent.typeElement())), + subcomponent); + addEdge( + binding, + subcomponentNode, + new SubcomponentCreatorBindingEdgeImpl(binding.subcomponentDeclarations())); + } + + private void addChildFactoryMethodEdge(Resolver subcomponentResolver) { + componentDescriptor + .getFactoryMethodForChildComponent(subcomponentResolver.componentDescriptor) + .ifPresent( + childFactoryMethod + -> addEdge( + componentNode, + subcomponentResolver.componentNode, + new ChildFactoryMethodEdgeImpl(childFactoryMethod.methodElement()))); + } + + private void addEdge(Node source, Node target, Edge edge) { + network.addNode(source); + network.addNode(target); + network.addEdge(source, target, edge); + } + + private MissingBinding missingBinding(Key key) { + // Put all missing binding nodes in the root component. This simplifies the binding graph + // and produces better error messages for users since all dependents point to the same node. + return MissingBindingImpl.create(rootResolver().componentPath, key); + } + + private Resolver rootResolver() { + return parentResolver.isPresent() ? parentResolver.get().rootResolver() : this; + } + + private final class RequiresResolutionChecker { + private final Map<Node, Boolean> dependsOnMissingBindingCache = new HashMap<>(); + private final Map<Node, Boolean> dependsOnLocalBindingsCache = new HashMap<>(); + + boolean requiresResolution(BindingNode binding) { + // If we're not allowed to float then the binding cannot be re-resolved in this component. + if (isNotAllowedToFloat(binding)) { return false; } - return reentrantComputeIfAbsent( - keyDependsOnLocalBindingsCache, key, this::requiresResolutionUncached); - } - - /** - * Returns {@code true} if {@code binding} is unscoped (or has {@link Reusable @Reusable} - * scope) and depends on multibindings with contributions declared within this component's - * modules, or if any of its unscoped or {@link Reusable @Reusable} scoped dependencies depend - * on such local multibindings. - * - * <p>We don't care about non-reusable scoped dependencies because they will never depend on - * multibindings with contributions from subcomponents. - */ - private boolean requiresResolution(Binding binding) { - if (!cycleChecker.add(binding)) { - return false; - } - return reentrantComputeIfAbsent( - bindingDependsOnLocalBindingsCache, binding, this::requiresResolutionUncached); - } - - 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 (hasLocalBindings(previouslyResolvedBindings)) { + if (hasLocalBindings(binding)) { return true; } - - for (Binding binding : previouslyResolvedBindings.bindings()) { - if (requiresResolution(binding)) { - return true; - } - } - return false; + return shouldCheckDependencies(binding) + // Try to re-resolving bindings that depend on missing bindings. The missing bindings + // will still end up being reported for cases where the binding is not allowed to float, + // but re-resolving allows cases that are allowed to float to be re-resolved which can + // prevent misleading dependency traces that include all floatable bindings. + // E.g. see MissingBindingSuggestionsTest#bindsMissingBinding_fails(). + && (dependsOnLocalBinding(binding) || dependsOnMissingBinding(binding)); } - private boolean requiresResolutionUncached(Binding binding) { - if ((!binding.scope().isPresent() || binding.scope().get().isReusable()) + private boolean isNotAllowedToFloat(BindingNode binding) { + // In general, @Provides/@Binds/@Production bindings are allowed to float to get access to + // multibinding contributions that are contributed in subcomponents. However, they aren't + // allowed to float to get access to missing bindings that are installed in subcomponents, + // so we prevent floating if these bindings depend on a missing binding. + return binding.kind() != BindingKind.INJECTION + && binding.kind() != BindingKind.ASSISTED_INJECTION + && dependsOnMissingBinding(binding); + } + + private boolean dependsOnMissingBinding(BindingNode binding) { + if (!dependsOnMissingBindingCache.containsKey(binding)) { + visitUncachedDependencies(binding); + } + return checkNotNull(dependsOnMissingBindingCache.get(binding)); + } + + private boolean dependsOnLocalBinding(BindingNode binding) { + if (!dependsOnLocalBindingsCache.containsKey(binding)) { + visitUncachedDependencies(binding); + } + return checkNotNull(dependsOnLocalBindingsCache.get(binding)); + } + + private void visitUncachedDependencies(BindingNode binding) { + // We use Tarjan's algorithm to visit the uncached dependencies of the binding grouped by + // strongly connected nodes (i.e. cycles) and iterated in reverse topological order. + for (ImmutableSet<Node> cycleNodes : stronglyConnectedNodes(binding)) { + // As a sanity check, verify that none of the keys in the cycle are cached yet. + checkState(cycleNodes.stream().noneMatch(dependsOnLocalBindingsCache::containsKey)); + checkState(cycleNodes.stream().noneMatch(dependsOnMissingBindingCache::containsKey)); + boolean dependsOnMissingBinding = + cycleNodes.stream().anyMatch(this::isMissingBinding) + || cycleNodes.stream() + .filter(this::shouldCheckDependencies) + .flatMap(this::dependencyStream) + .filter(not(cycleNodes::contains)) + .anyMatch(dependsOnMissingBindingCache::get); + // All keys in the cycle have the same cached value since they all depend on each other. + cycleNodes.forEach( + cycleNode -> dependsOnMissingBindingCache.put(cycleNode, dependsOnMissingBinding)); + + // Note that we purposely don't filter out scoped bindings below. In particular, there are + // currently 3 cases where hasLocalBinding will return true: + // + // 1) The binding is MULTIBOUND_SET/MULTIBOUND_MAP and depends on an explicit + // multibinding contributions in the current component. + // 2) The binding is OPTIONAL and depends on an explicit binding contributed in the + // current component. + // 3) The binding has a duplicate explicit binding contributed in this component. + // + // For case #1 and #2 it's not actually required to check for scope because those are + // synthetic bindings which are never scoped. + // + // For case #3 we actually want don't want to rule out a scoped binding, e.g. in the case + // where we have a floating @Inject Foo(Bar bar) binding with @Singleton Bar provided in + // the ParentComponent and a duplicate Bar provided in the ChildComponent we want to + // reprocess Foo so that we can report the duplicate Bar binding. + boolean dependsOnLocalBindings = + // First, check if any of the bindings themselves depends on local bindings. + cycleNodes.stream().anyMatch(this::hasLocalBindings) + // Next, check if any of the dependencies (that aren't in the cycle itself) depend + // on local bindings. We should be guaranteed that all dependencies are cached since + // Tarjan's algorithm is traversed in reverse topological order. + || cycleNodes.stream() + .filter(this::shouldCheckDependencies) + .flatMap(this::dependencyStream) + .filter(not(cycleNodes::contains)) + .anyMatch(dependsOnLocalBindingsCache::get); + // All keys in the cycle have the same cached value since they all depend on each other. + cycleNodes.forEach( + cycleNode -> dependsOnLocalBindingsCache.put(cycleNode, dependsOnLocalBindings)); + } + } + + /** + * Returns a list of strongly connected components in reverse topological order, starting from + * the given {@code rootNode} and traversing its transitive dependencies. + * + * <p>Note that the returned list may not include all transitive dependencies of the {@code + * rootNode} because we intentionally stop at dependencies that: + * + * <ul> + * <li> Already have a cached value. + * <li> Are scoped to an ancestor component (i.e. cannot depend on local bindings). + * </ul> + */ + private ImmutableList<ImmutableSet<Node>> stronglyConnectedNodes(BindingNode rootNode) { + return TarjanSCCs.compute( + ImmutableSet.of(rootNode), + node -> shouldCheckDependencies(node) + ? dependencyStream(node) + // Skip dependencies that are already cached + .filter(dep -> !dependsOnLocalBindingsCache.containsKey(dep)) + .collect(toImmutableSet()) + : ImmutableSet.of()); + } + + private Stream<Node> dependencyStream(Node node) { + return network.successors(node).stream(); + } + + private boolean shouldCheckDependencies(Node node) { + if (!(node instanceof BindingNode)) { + return false; + } + // Note: we can skip dependencies for scoped bindings because while there could be + // duplicates underneath the scoped binding, those duplicates are technically unused so + // Dagger shouldn't validate them. + BindingNode binding = (BindingNode) node; + return !isScopedToComponent(binding) // TODO(beder): Figure out what happens with production subcomponents. - && !binding.bindingType().equals(BindingType.PRODUCTION)) { - for (DependencyRequest dependency : binding.dependencies()) { - if (requiresResolution(dependency.key())) { - return true; - } - } - } - return false; + && !binding.kind().equals(BindingKind.PRODUCTION); } - } - private boolean hasLocalBindings(Binding binding) { - return hasLocalMultibindingContributions(binding.key()) - || hasLocalOptionalBindingContribution( - binding.key(), ImmutableSet.of((ContributionBinding) binding)); - } + private boolean isScopedToComponent(BindingNode binding) { + return binding.scope().isPresent() && !binding.scope().get().isReusable(); + } - private boolean hasLocalBindings(ResolvedBindings resolvedBindings) { - return hasLocalMultibindingContributions(resolvedBindings.key()) - || hasLocalOptionalBindingContribution(resolvedBindings); + private boolean isMissingBinding(Node binding) { + return binding instanceof MissingBinding; + } + + private boolean hasLocalBindings(Node node) { + if (!(node instanceof BindingNode)) { + return false; + } + BindingNode binding = (BindingNode) node; + return hasLocalMultibindingContributions(binding) + || hasLocalOptionalBindingContribution(binding) + || hasDuplicateExplicitBinding(binding); + } } /** - * Returns {@code true} if there is at least one multibinding contribution declared within - * this component's modules that matches the key. + * Returns {@code true} if there's a contribution in this component matching the given binding + * key. */ - private boolean hasLocalMultibindingContributions(Key requestKey) { - return keysMatchingRequest(requestKey) - .stream() - .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty()); + private boolean hasLocalMultibindingContributions(BindingNode binding) { + return !declarations.multibindingContributions(binding.key()).isEmpty() + || !declarations.delegateMultibindingContributions(binding.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(); + private boolean hasLocalOptionalBindingContribution(BindingNode binding) { + if (binding.kind() == OPTIONAL) { + return hasLocalExplicitBindings(keyFactory.unwrapOptional(binding.key()).get()); } 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(); + return !getOptionalBindingDeclarations(binding.key()).isEmpty(); } } - } - /** - * A multimap of those {@code declarations} that are multibinding contribution declarations, - * indexed by the key of the set or map to which they contribute. - */ - static <T extends BindingDeclaration> - ImmutableSetMultimap<Key, T> multibindingContributionsByMultibindingKey( - Iterable<T> declarations) { - ImmutableSetMultimap.Builder<Key, T> builder = ImmutableSetMultimap.builder(); - for (T declaration : declarations) { - if (declaration.key().multibindingContributionIdentifier().isPresent()) { - builder.put(declaration.key().withoutMultibindingContributionIdentifier(), declaration); - } + /** + * Returns {@code true} if there is at least one explicit binding that matches the given key. + */ + private boolean hasLocalExplicitBindings(Key requestKey) { + return !declarations.bindings(requestKey).isEmpty() + || !declarations.delegates(requestKey).isEmpty(); } - return builder.build(); + + /** Returns {@code true} if this resolver has a duplicate explicit binding to resolve. */ + private boolean hasDuplicateExplicitBinding(BindingNode binding) { + // By default, we don't actually report an error when an explicit binding tries to override + // an injection binding (b/312202845). For now, ignore injection bindings unless we actually + // will report an error, otherwise we'd end up silently overriding the binding rather than + // reporting a duplicate. + // TODO(b/312202845): This can be removed once b/312202845 is fixed. + if (binding.kind() == BindingKind.INJECTION + && !compilerOptions.explicitBindingConflictsWithInjectValidationType() + .diagnosticKind() + .equals(Optional.of(Diagnostic.Kind.ERROR))) { + return false; + } + + // If the current component has an explicit binding for the same key it must be a duplicate. + return hasLocalExplicitBindings(binding.key()); + } } }
diff --git a/java/dagger/internal/codegen/binding/BindingGraphTransformations.java b/java/dagger/internal/codegen/binding/BindingGraphTransformations.java new file mode 100644 index 0000000..405d6b2 --- /dev/null +++ b/java/dagger/internal/codegen/binding/BindingGraphTransformations.java
@@ -0,0 +1,119 @@ +/* + * 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.binding; + +import static com.google.common.base.Preconditions.checkState; +import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.common.graph.EndpointPair; +import com.google.common.graph.MutableNetwork; +import com.google.common.graph.Network; +import com.google.common.graph.NetworkBuilder; +import dagger.internal.codegen.base.TarjanSCCs; +import dagger.internal.codegen.model.BindingGraph.Edge; +import dagger.internal.codegen.model.BindingGraph.Node; +import java.util.Map; + +/** Transformations on the binding graph network. */ +final class BindingGraphTransformations { + /** Returns a network where {@link BindingType} is present for all binding nodes. */ + static MutableNetwork<Node, Edge> withFixedBindingTypes(MutableNetwork<Node, Edge> network) { + ImmutableSet<BindingNode> bindingsToFix = bindingsWithMissingBindingTypes(network); + if (bindingsToFix.isEmpty()) { + return network; + } + + MutableNetwork<Node, Edge> fixedNetwork = withFixedBindingTypes(network, bindingsToFix); + + // Check that all bindings now have a BindingType in the fixed network. + checkState(bindingsWithMissingBindingTypes(fixedNetwork).isEmpty()); + return fixedNetwork; + } + + private static MutableNetwork<Node, Edge> withFixedBindingTypes( + Network<Node, Edge> network, ImmutableSet<BindingNode> bindingsToFix) { + // Topologically sort the bindings so that we're guaranteed all dependencies of a binding are + // fixed before the bindings itself is fixed. + ImmutableList<ImmutableSet<BindingNode>> topologicallySortedBindingsToFix = + TarjanSCCs.compute( + bindingsToFix, + binding -> + network.successors(binding).stream() + .flatMap(instancesOf(BindingNode.class)) + // Filter because we only care about direct dependencies on bindings that need + // to be fixed. There might be other cycles through nodes that already have a + // type, but those don't matter because it won't affect how we will fix the + // types for these bindings. + .filter(bindingsToFix::contains) + .collect(toImmutableSet())); + + Map<BindingNode, BindingNode> replacements = + Maps.newHashMapWithExpectedSize(bindingsToFix.size()); + for (ImmutableSet<BindingNode> connectedBindings : topologicallySortedBindingsToFix) { + BindingType successorBindingType = + connectedBindings.stream() + .flatMap(binding -> network.successors(binding).stream()) + .flatMap(instancesOf(BindingNode.class)) + .filter(binding -> !connectedBindings.contains(binding)) + .map(binding -> replacements.getOrDefault(binding, binding)) + .anyMatch(BindingNode::isProduction) + ? BindingType.PRODUCTION + : BindingType.PROVISION; + for (BindingNode bindingNode : connectedBindings) { + replacements.put(bindingNode, bindingNode.withBindingType(successorBindingType)); + } + } + return withReplacedBindings(network, ImmutableMap.copyOf(replacements)); + } + + private static ImmutableSet<BindingNode> bindingsWithMissingBindingTypes( + Network<Node, Edge> network) { + return network.nodes().stream() + .flatMap(instancesOf(BindingNode.class)) + .filter(binding -> binding.delegate().optionalBindingType().isEmpty()) + .collect(toImmutableSet()); + } + + // Note: This method creates an entirely new network rather than replacing individual nodes and + // edges in the original network. We can reconsider this choice, e.g. if it turns out to be + // too inefficient, but my initial thought is that this approach is a bit nicer because it + // maintains the original node and edge iteration order, which could be nice for debugging. + private static MutableNetwork<Node, Edge> withReplacedBindings( + Network<Node, Edge> network, ImmutableMap<? extends Node, ? extends Node> replacementNodes) { + MutableNetwork<Node, Edge> newNetwork = NetworkBuilder.from(network).build(); + for (Node node : network.nodes()) { + newNetwork.addNode(replacementNodes.containsKey(node) ? replacementNodes.get(node) : node); + } + for (Edge edge : network.edges()) { + EndpointPair<Node> incidentNodes = network.incidentNodes(edge); + Node source = incidentNodes.source(); + Node target = incidentNodes.target(); + newNetwork.addEdge( + replacementNodes.containsKey(source) ? replacementNodes.get(source) : source, + replacementNodes.containsKey(target) ? replacementNodes.get(target) : target, + edge); + } + return newNetwork; + } + + private BindingGraphTransformations() {} +}
diff --git a/java/dagger/internal/codegen/binding/BindingNode.java b/java/dagger/internal/codegen/binding/BindingNode.java index 7856420..9818c39 100644 --- a/java/dagger/internal/codegen/binding/BindingNode.java +++ b/java/dagger/internal/codegen/binding/BindingNode.java
@@ -16,14 +16,11 @@ package dagger.internal.codegen.binding; -import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.BindingType.PRODUCTION; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import dagger.BindsOptionalOf; -import dagger.Module; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.ComponentPath; import dagger.internal.codegen.model.DaggerElement; @@ -31,37 +28,19 @@ import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.Scope; -import dagger.multibindings.Multibinds; import java.util.Optional; +import javax.inject.Inject; /** * An implementation of {@link dagger.internal.codegen.model.Binding} that also exposes {@link - * BindingDeclaration}s associated with the binding. + * Declaration}s associated with the binding. */ // TODO(dpb): Consider a supertype of dagger.internal.codegen.model.Binding that // dagger.internal.codegen.binding.Binding // could also implement. @AutoValue public abstract class BindingNode implements dagger.internal.codegen.model.Binding { - public static BindingNode create( - ComponentPath component, - Binding delegate, - ImmutableSet<MultibindingDeclaration> multibindingDeclarations, - ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations, - ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations, - BindingDeclarationFormatter bindingDeclarationFormatter) { - BindingNode node = - new AutoValue_BindingNode( - component, - delegate, - multibindingDeclarations, - optionalBindingDeclarations, - subcomponentDeclarations); - node.bindingDeclarationFormatter = checkNotNull(bindingDeclarationFormatter); - return node; - } - - private BindingDeclarationFormatter bindingDeclarationFormatter; + private DeclarationFormatter declarationFormatter; public abstract Binding delegate(); @@ -81,7 +60,7 @@ * <li>{@linkplain Multibinds multibinding} declarations * </ul> */ - public final Iterable<BindingDeclaration> associatedDeclarations() { + public final Iterable<Declaration> associatedDeclarations() { return Iterables.concat( multibindingDeclarations(), optionalBindingDeclarations(), subcomponentDeclarations()); } @@ -133,6 +112,77 @@ @Override public final String toString() { - return bindingDeclarationFormatter.format(delegate()); + return declarationFormatter.format(delegate()); + } + + public BindingNode withBindingType(BindingType bindingType) { + return create( + componentPath(), + ((ContributionBinding) delegate()).withBindingType(bindingType), + multibindingDeclarations(), + optionalBindingDeclarations(), + subcomponentDeclarations(), + declarationFormatter); + } + + static final class Factory { + private final DeclarationFormatter declarationFormatter; + + @Inject + Factory(DeclarationFormatter declarationFormatter) { + this.declarationFormatter = declarationFormatter; + } + + public BindingNode forContributionBindings( + ComponentPath component, + ContributionBinding delegate, + Iterable<MultibindingDeclaration> multibindingDeclarations, + Iterable<OptionalBindingDeclaration> optionalBindingDeclarations, + Iterable<SubcomponentDeclaration> subcomponentDeclarations) { + return create( + component, + delegate, + ImmutableSet.copyOf(multibindingDeclarations), + ImmutableSet.copyOf(optionalBindingDeclarations), + ImmutableSet.copyOf(subcomponentDeclarations)); + } + + public BindingNode forMembersInjectionBinding( + ComponentPath component, MembersInjectionBinding delegate) { + return create(component, delegate, ImmutableSet.of(), ImmutableSet.of(), ImmutableSet.of()); + } + + private BindingNode create( + ComponentPath component, + Binding delegate, + ImmutableSet<MultibindingDeclaration> multibindingDeclarations, + ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations, + ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations) { + return BindingNode.create( + component, + delegate, + multibindingDeclarations, + optionalBindingDeclarations, + subcomponentDeclarations, + declarationFormatter); + } + } + + private static BindingNode create( + ComponentPath component, + Binding delegate, + ImmutableSet<MultibindingDeclaration> multibindingDeclarations, + ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations, + ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations, + DeclarationFormatter declarationFormatter) { + BindingNode node = + new AutoValue_BindingNode( + component, + delegate, + multibindingDeclarations, + optionalBindingDeclarations, + subcomponentDeclarations); + node.declarationFormatter = declarationFormatter; + return node; } }
diff --git a/java/dagger/internal/codegen/binding/BoundInstanceBinding.java b/java/dagger/internal/codegen/binding/BoundInstanceBinding.java new file mode 100644 index 0000000..e974de2 --- /dev/null +++ b/java/dagger/internal/codegen/binding/BoundInstanceBinding.java
@@ -0,0 +1,74 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#BOUND_INSTANCE}. */ +@CheckReturnValue +@AutoValue +public abstract class BoundInstanceBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.BOUND_INSTANCE; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public final ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_BoundInstanceBinding.Builder(); + } + + /** A {@link BoundInstanceBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<BoundInstanceBinding, Builder> { + abstract Builder nullability(Nullability nullability); + } +}
diff --git a/java/dagger/internal/codegen/binding/ComponentBinding.java b/java/dagger/internal/codegen/binding/ComponentBinding.java new file mode 100644 index 0000000..a5eda78 --- /dev/null +++ b/java/dagger/internal/codegen/binding/ComponentBinding.java
@@ -0,0 +1,76 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#COMPONENT}. */ +@CheckReturnValue +@AutoValue +public abstract class ComponentBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.COMPONENT; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public final ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_ComponentBinding.Builder(); + } + + /** A {@link ComponentBinding} builder. */ + @AutoValue.Builder + abstract static class Builder extends ContributionBinding.Builder<ComponentBinding, Builder> {} +}
diff --git a/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java b/java/dagger/internal/codegen/binding/ComponentCreatorDescriptor.java index 254ca7e..cf978a2 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.ComponentCreatorKind; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; import dagger.internal.codegen.xprocessing.XElements; import java.util.List; @@ -217,7 +218,10 @@ DependencyRequest request = dependencyRequestFactory.forRequiredResolvedVariable(parameter, parameterType); return ComponentRequirement.forBoundInstance( - request.key(), request.isNullable(), elementForVariableName); + request.key(), + request.isNullable(), + elementForVariableName, + Nullability.of(elementForVariableName)); } return parameterType.getTypeElement().hasAnyAnnotation(moduleAnnotations())
diff --git a/java/dagger/internal/codegen/binding/ComponentDeclarations.java b/java/dagger/internal/codegen/binding/ComponentDeclarations.java new file mode 100644 index 0000000..2855722 --- /dev/null +++ b/java/dagger/internal/codegen/binding/ComponentDeclarations.java
@@ -0,0 +1,389 @@ +/* + * 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.binding; + +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; +import static com.google.common.collect.Iterables.getOnlyElement; +import static dagger.internal.codegen.binding.SourceFiles.generatedMonitoringModuleName; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import androidx.room.compiler.processing.XProcessingEnv; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSetMultimap; +import com.google.common.collect.Multimaps; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.WildcardTypeName; +import dagger.internal.codegen.base.DaggerSuperficialValidation; +import dagger.internal.codegen.base.FrameworkTypes; +import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.model.DaggerAnnotation; +import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.Key.MultibindingContributionIdentifier; +import java.util.Optional; +import javax.inject.Inject; + +/** Stores the bindings and declarations of a component by key. */ +final class ComponentDeclarations { + private final KeyFactory keyFactory; + private final ImmutableSetMultimap<Key, ContributionBinding> bindings; + private final ImmutableSetMultimap<Key, DelegateDeclaration> delegates; + private final ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindings; + private final ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponents; + private final ImmutableSetMultimap<TypeNameKey, MultibindingDeclaration> multibindings; + private final ImmutableSetMultimap<TypeNameKey, ContributionBinding> multibindingContributions; + private final ImmutableSetMultimap<TypeNameKey, DelegateDeclaration> + delegateMultibindingContributions; + + private ComponentDeclarations( + KeyFactory keyFactory, + ImmutableSetMultimap<Key, ContributionBinding> bindings, + ImmutableSetMultimap<Key, DelegateDeclaration> delegates, + ImmutableSetMultimap<Key, OptionalBindingDeclaration> optionalBindings, + ImmutableSetMultimap<Key, SubcomponentDeclaration> subcomponents, + ImmutableSetMultimap<TypeNameKey, MultibindingDeclaration> multibindings, + ImmutableSetMultimap<TypeNameKey, ContributionBinding> multibindingContributions, + ImmutableSetMultimap<TypeNameKey, DelegateDeclaration> delegateMultibindingContributions) { + this.keyFactory = keyFactory; + this.bindings = bindings; + this.delegates = delegates; + this.optionalBindings = optionalBindings; + this.subcomponents = subcomponents; + this.multibindings = multibindings; + this.multibindingContributions = multibindingContributions; + this.delegateMultibindingContributions = delegateMultibindingContributions; + } + + ImmutableSet<ContributionBinding> bindings(Key key) { + return bindings.get(key); + } + + ImmutableSet<DelegateDeclaration> delegates(Key key) { + // @Binds @IntoMap declarations have key Map<K, V> but may be requested as + // Map<K, Provider/Producer<V>> keys, so unwrap the multibinding map contribution key first. + // TODO(b/366277730): This can be simplified to "delegates.get(key)" once the flag for + // "useFrameworkTypeInMapMultibindingContributionKey" is removed. + return delegates.get( + key.multibindingContributionIdentifier().isPresent() + // TODO(bcorso): Consider using TypeNameKey here instead of Key, to avoid losing + // variance information when unwrapping KSP types (see TypeNameKey's javadoc). + ? keyFactory.unwrapMapValueType(key) + : key); + } + + /** + * Returns the delegate multibinding contributions (e.g. {@code @Binds @IntoMap}) for the given + * {@code key}, or an empty set if none exist. + * + * <p>For map multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Map<K, V>} + * <li> {@code Map<K, Provider<V>>} + * <li> {@code Map<K, Producer<V>>} + * <li> {@code Map<K, Produced<V>>} + * </ul> + * + * <p>For set multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Set<V>} + * <li> {@code Set<Produced<V>>} + * </ul> + */ + ImmutableSet<DelegateDeclaration> delegateMultibindingContributions(Key key) { + return delegateMultibindingContributions.get(unwrapMultibindingKey(key)); + } + + /** + * Returns the multibinding declarations (i.e. {@code @Multibinds}) for the given {@code key}, or + * an empty set if none exists. + * + * <p>For map multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Map<K, V>} + * <li> {@code Map<K, Provider<V>>} + * <li> {@code Map<K, Producer<V>>} + * <li> {@code Map<K, Produced<V>>} + * </ul> + * + * <p>For set multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Set<V>} + * <li> {@code Set<Produced<V>>} + * </ul> + */ + ImmutableSet<MultibindingDeclaration> multibindings(Key key) { + return multibindings.get(unwrapMultibindingKey(key)); + } + + /** + * Returns the multibinding contributions (e.g. {@code @Provides @IntoMap}) for the given + * {@code key}, or an empty set if none exists. + * + * <p>For map multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Map<K, V>} + * <li> {@code Map<K, Provider<V>>} + * <li> {@code Map<K, Producer<V>>} + * <li> {@code Map<K, Produced<V>>} + * </ul> + * + * <p>For set multibindings, the following request keys represent the same underlying binding and + * will return the same results: + * <ul> + * <li> {@code Set<V>} + * <li> {@code Set<Produced<V>>} + * </ul> + */ + ImmutableSet<ContributionBinding> multibindingContributions(Key key) { + return multibindingContributions.get(unwrapMultibindingKey(key)); + } + + ImmutableSet<OptionalBindingDeclaration> optionalBindings(Key key) { + return optionalBindings.get(key); + } + + ImmutableSet<SubcomponentDeclaration> subcomponents(Key key) { + return subcomponents.get(key); + } + + ImmutableSet<Declaration> allDeclarations() { + return ImmutableSet.<Declaration>builder() + .addAll(bindings.values()) + .addAll(delegates.values()) + .addAll(multibindings.values()) + .addAll(optionalBindings.values()) + .addAll(subcomponents.values()) + .build(); + } + + static final class Factory { + private final XProcessingEnv processingEnv; + private final KeyFactory keyFactory; + private final ModuleDescriptor.Factory moduleDescriptorFactory; + + @Inject + Factory( + XProcessingEnv processingEnv, + KeyFactory keyFactory, + ModuleDescriptor.Factory moduleDescriptorFactory) { + this.processingEnv = processingEnv; + this.keyFactory = keyFactory; + this.moduleDescriptorFactory = moduleDescriptorFactory; + } + + ComponentDeclarations create( + Optional<ComponentDescriptor> parentDescriptor, ComponentDescriptor descriptor) { + ImmutableSet.Builder<ContributionBinding> bindings = ImmutableSet.builder(); + ImmutableSet.Builder<DelegateDeclaration> delegates = ImmutableSet.builder(); + ImmutableSet.Builder<MultibindingDeclaration> multibindings = ImmutableSet.builder(); + ImmutableSet.Builder<OptionalBindingDeclaration> optionalBindings =ImmutableSet.builder(); + ImmutableSet.Builder<SubcomponentDeclaration> subcomponents = ImmutableSet.builder(); + + bindings.addAll(descriptor.bindings()); + delegates.addAll(descriptor.delegateDeclarations()); + multibindings.addAll(descriptor.multibindingDeclarations()); + optionalBindings.addAll(descriptor.optionalBindingDeclarations()); + subcomponents.addAll(descriptor.subcomponentDeclarations()); + + // Note: The implicit production modules are not included directly in the component descriptor + // because we don't know whether to install them or not without knowing the parent component. + for (ModuleDescriptor module : implicitProductionModules(descriptor, parentDescriptor)) { + bindings.addAll(module.bindings()); + delegates.addAll(module.delegateDeclarations()); + multibindings.addAll(module.multibindingDeclarations()); + optionalBindings.addAll(module.optionalDeclarations()); + subcomponents.addAll(module.subcomponentDeclarations()); + } + + return new ComponentDeclarations( + keyFactory, + indexDeclarationsByKey(bindings.build()), + indexDeclarationsByKey(delegates.build()), + indexDeclarationsByKey(optionalBindings.build()), + indexDeclarationsByKey(subcomponents.build()), + // The @Multibinds declarations and @IntoSet/@IntoMap multibinding contributions are all + // indexed by their "unwrapped" multibinding key (i.e. Map<K, V> or Set<V>) so that we + // don't have to check multiple different keys to gather all of the contributions. + indexDeclarationsByUnwrappedMultibindingKey(multibindings.build()), + indexDeclarationsByUnwrappedMultibindingKey(multibindingContributions(bindings.build())), + indexDeclarationsByUnwrappedMultibindingKey( + multibindingContributions(delegates.build()))); + } + + /** + * Returns all the modules that should be installed in the component. For production components + * and production subcomponents that have a parent that is not a production component or + * subcomponent, also includes the production monitoring module for the component and the + * production executor module. + */ + private ImmutableSet<ModuleDescriptor> implicitProductionModules( + ComponentDescriptor descriptor, Optional<ComponentDescriptor> parentDescriptor) { + return shouldIncludeImplicitProductionModules(descriptor, parentDescriptor) + ? ImmutableSet.of( + moduleDescriptorFactory.create( + DaggerSuperficialValidation.requireTypeElement( + processingEnv, + toJavaPoet(generatedMonitoringModuleName(descriptor.typeElement())))), + moduleDescriptorFactory.create( + processingEnv.requireTypeElement(TypeNames.PRODUCTION_EXECTUTOR_MODULE))) + : ImmutableSet.of(); + } + + private static boolean shouldIncludeImplicitProductionModules( + ComponentDescriptor descriptor, Optional<ComponentDescriptor> parentDescriptor) { + return descriptor.isProduction() + && descriptor.isRealComponent() + && (parentDescriptor.isEmpty() || !parentDescriptor.get().isProduction()); + } + + /** Indexes {@code bindingDeclarations} by {@link Declaration#key()}. */ + private static <T extends Declaration> + ImmutableSetMultimap<Key, T> indexDeclarationsByKey(Iterable<T> declarations) { + return ImmutableSetMultimap.copyOf(Multimaps.index(declarations, Declaration::key)); + } + + /** Indexes {@code bindingDeclarations} by the unwrapped multibinding key. */ + private <T extends Declaration> ImmutableSetMultimap<TypeNameKey, T> + indexDeclarationsByUnwrappedMultibindingKey(Iterable<T> declarations) { + return ImmutableSetMultimap.copyOf( + Multimaps.index( + declarations, + declaration -> + unwrapMultibindingKey( + declaration.key().withoutMultibindingContributionIdentifier()))); + } + + private static <T extends Declaration> ImmutableSet<T> multibindingContributions( + ImmutableSet<T> declarations) { + return declarations.stream() + .filter(declaration -> declaration.key().multibindingContributionIdentifier().isPresent()) + .collect(toImmutableSet()); + } + } + + /** + * Returns a {@link TypeNameKey} with the same qualifiers and multibinding identifier as the + * original key, but with an unwrapped typed. + * + * <p>In this case, an unwrapped type is a map or set where the value type has been stripped of a + * leading framework type. If the given type is neither a map nor set type, then the original type + * is returned. + * + * <p>The following map types have an unwrapped type equal to {@code Map<K, V>}: + * <ul> + * <li> {@code Map<K, V>} + * <li> {@code Map<K, Provider<V>>} + * <li> {@code Map<K, Producer<V>>} + * <li> {@code Map<K, Produced<V>>} + * </ul> + * + * <p>The following set types have an unwrapped type equal to {@code Set<V>}: + * <ul> + * <li> {@code Set<V>} + * <li> {@code Set<Produced<V>>} + * </ul> + */ + private static TypeNameKey unwrapMultibindingKey(Key multibindingKey) { + return TypeNameKey.from( + multibindingKey.multibindingContributionIdentifier(), + multibindingKey.qualifier(), + unwrapMultibindingTypeName(multibindingKey.type().xprocessing().getTypeName())); + } + + private static TypeName unwrapMultibindingTypeName(TypeName typeName) { + if (isValidMapMultibindingTypeName(typeName)) { + ParameterizedTypeName mapTypeName = (ParameterizedTypeName) typeName; + TypeName mapKeyTypeName = mapTypeName.typeArguments.get(0); + TypeName mapValueTypeName = mapTypeName.typeArguments.get(1); + return ParameterizedTypeName.get( + mapTypeName.rawType, + mapKeyTypeName, + unwrapFrameworkTypeName(mapValueTypeName, FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES)); + } + if (isValidSetMultibindingTypeName(typeName)) { + ParameterizedTypeName setTypeName = (ParameterizedTypeName) typeName; + TypeName setValueTypeName = getOnlyElement(setTypeName.typeArguments); + return ParameterizedTypeName.get( + setTypeName.rawType, + unwrapFrameworkTypeName(setValueTypeName, FrameworkTypes.SET_VALUE_FRAMEWORK_TYPES)); + } + return typeName; + } + + private static boolean isValidMapMultibindingTypeName(TypeName typeName) { + if (!(typeName instanceof ParameterizedTypeName)) { + return false; + } + ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName; + return parameterizedTypeName.rawType.equals(TypeNames.MAP) + && parameterizedTypeName.typeArguments.size() == 2 + && !(parameterizedTypeName.typeArguments.get(0) instanceof WildcardTypeName) + && !(parameterizedTypeName.typeArguments.get(1) instanceof WildcardTypeName); + } + + private static boolean isValidSetMultibindingTypeName(TypeName typeName) { + if (!(typeName instanceof ParameterizedTypeName)) { + return false; + } + ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName; + return parameterizedTypeName.rawType.equals(TypeNames.SET) + && parameterizedTypeName.typeArguments.size() == 1 + && !(getOnlyElement(parameterizedTypeName.typeArguments) instanceof WildcardTypeName); + } + + private static TypeName unwrapFrameworkTypeName( + TypeName typeName, ImmutableSet<ClassName> frameworkTypeNames) { + if (typeName instanceof ParameterizedTypeName) { + ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) typeName; + if (frameworkTypeNames.contains(parameterizedTypeName.rawType)) { + typeName = getOnlyElement(parameterizedTypeName.typeArguments); + } + } + return typeName; + } + + /** + * Represents a class similar to {@link Key} but uses {@link TypeName} rather than {@code XType}. + * + * <p>We use {@code TypeName} rather than {@code XType} here because we can lose variance + * information when unwrapping an {@code XType} in KSP (b/352142595), and using {@code TypeName} + * avoids this issue. + */ + @AutoValue + abstract static class TypeNameKey { + static TypeNameKey from( + Optional<MultibindingContributionIdentifier> multibindingContributionIdentifier, + Optional<DaggerAnnotation> qualifier, + TypeName typeName) { + return new AutoValue_ComponentDeclarations_TypeNameKey( + multibindingContributionIdentifier, qualifier, typeName); + } + + abstract Optional<MultibindingContributionIdentifier> multibindingContributionIdentifier(); + + abstract Optional<DaggerAnnotation> qualifier(); + + abstract TypeName type(); + } +}
diff --git a/java/dagger/internal/codegen/binding/ComponentDependencyBinding.java b/java/dagger/internal/codegen/binding/ComponentDependencyBinding.java new file mode 100644 index 0000000..9b52a2c --- /dev/null +++ b/java/dagger/internal/codegen/binding/ComponentDependencyBinding.java
@@ -0,0 +1,77 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#COMPONENT_DEPENDENCY}. */ +@CheckReturnValue +@AutoValue +public abstract class ComponentDependencyBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.COMPONENT_DEPENDENCY; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_ComponentDependencyBinding.Builder(); + } + + /** A {@link ComponentDependencyBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<ComponentDependencyBinding, Builder> {} +}
diff --git a/java/dagger/internal/codegen/binding/ComponentDependencyProductionBinding.java b/java/dagger/internal/codegen/binding/ComponentDependencyProductionBinding.java new file mode 100644 index 0000000..c646acc --- /dev/null +++ b/java/dagger/internal/codegen/binding/ComponentDependencyProductionBinding.java
@@ -0,0 +1,77 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#COMPONENT_PRODUCTION}. */ +@CheckReturnValue +@AutoValue +public abstract class ComponentDependencyProductionBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.COMPONENT_PRODUCTION; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PRODUCTION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_ComponentDependencyProductionBinding.Builder(); + } + + /** A {@link ComponentDependencyProductionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<ComponentDependencyProductionBinding, Builder> {} +}
diff --git a/java/dagger/internal/codegen/binding/ComponentDependencyProvisionBinding.java b/java/dagger/internal/codegen/binding/ComponentDependencyProvisionBinding.java new file mode 100644 index 0000000..5ae15e1 --- /dev/null +++ b/java/dagger/internal/codegen/binding/ComponentDependencyProvisionBinding.java
@@ -0,0 +1,74 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#COMPONENT_PROVISION}. */ +@CheckReturnValue +@AutoValue +public abstract class ComponentDependencyProvisionBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.COMPONENT_PROVISION; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_ComponentDependencyProvisionBinding.Builder(); + } + + /** A {@link ComponentDependencyProvisionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<ComponentDependencyProvisionBinding, Builder> { + abstract Builder nullability(Nullability nullability); + } +}
diff --git a/java/dagger/internal/codegen/binding/ComponentDescriptor.java b/java/dagger/internal/codegen/binding/ComponentDescriptor.java index b0a0183..fc2b674 100644 --- a/java/dagger/internal/codegen/binding/ComponentDescriptor.java +++ b/java/dagger/internal/codegen/binding/ComponentDescriptor.java
@@ -48,6 +48,7 @@ import com.google.auto.value.extension.memoized.Memoized; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -87,6 +88,8 @@ @CheckReturnValue @AutoValue public abstract class ComponentDescriptor { + private BindingFactory bindingFactory; + /** The annotation that specifies that {@link #typeElement()} is a component. */ public abstract ComponentAnnotation annotation(); @@ -273,20 +276,6 @@ builderType.getQualifiedName()); } - /** 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)); - } - - @Memoized - ImmutableMap<BindingRequest, ComponentMethodDescriptor> firstMatchingComponentMethods() { - Map<BindingRequest, ComponentMethodDescriptor> methods = new HashMap<>(); - for (ComponentMethodDescriptor method : entryPointMethods()) { - methods.putIfAbsent(BindingRequest.bindingRequest(method.dependencyRequest().get()), method); - } - return ImmutableMap.copyOf(methods); - } - /** The entry point methods on the component type. Each has a {@link DependencyRequest}. */ public final ImmutableSet<ComponentMethodDescriptor> entryPointMethods() { return componentMethods().stream() @@ -315,6 +304,130 @@ : Optional.empty(); } + /** Returns the bindings for the component. */ + @Memoized + public ImmutableSet<ContributionBinding> bindings() { + ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder(); + componentBinding().ifPresent(builder::add); + return builder + .addAll(componentDependencyBindings()) + .addAll(boundInstanceBindings()) + .addAll(subcomponentCreatorBindings()) + .addAll(moduleBindings()) + .build(); + } + + /** Returns the binding for the component, itself, if this is a real component. */ + @Memoized + Optional<ContributionBinding> componentBinding() { + return isRealComponent() + ? Optional.of(bindingFactory.componentBinding(typeElement())) + : Optional.empty(); + } + + /** Returns the bindings for the component dependency and those contributed by its methods. */ + @Memoized + ImmutableSet<ContributionBinding> componentDependencyBindings() { + ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder(); + for (ComponentRequirement dependency : dependencies()) { + builder.add(bindingFactory.componentDependencyBinding(dependency)); + + // Within a component dependency, we want to allow the same method to appear multiple + // times assuming it is the exact same method. We do this by tracking a set of bindings + // we've already added with the binding element removed since that is the only thing + // allowed to differ. + HashMultimap<String, ContributionBinding> dedupeBindings = HashMultimap.create(); + XTypeElements.getAllMethods(dependency.typeElement()).stream() + // MembersInjection methods aren't "provided" explicitly, so ignore them. + .filter(ComponentDescriptor::isComponentContributionMethod) + .forEach( + method -> { + ContributionBinding binding = + isProduction() && isComponentProductionMethod(method) + ? bindingFactory.componentDependencyProductionMethodBinding(method) + : bindingFactory.componentDependencyProvisionMethodBinding(method); + if (dedupeBindings.put( + getSimpleName(method), + // Remove the binding element since we know that will be different, but + // everything else we want to be the same to consider it a duplicate. + binding.toBuilder().clearBindingElement().build())) { + builder.add(binding); + } + }); + } + return builder.build(); + } + + /** Returns the {@code @BindsInstance} bindings required to create this component. */ + @Memoized + ImmutableSet<ContributionBinding> boundInstanceBindings() { + return creatorDescriptor().isPresent() + ? creatorDescriptor().get().boundInstanceRequirements().stream() + .map( + requirement -> + bindingFactory.boundInstanceBinding( + requirement, + creatorDescriptor().get().elementForRequirement(requirement))) + .collect(toImmutableSet()) + : ImmutableSet.of(); + } + + /** Returns the subcomponent creator bindings for this component. */ + @Memoized + ImmutableSet<ContributionBinding> subcomponentCreatorBindings() { + ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder(); + childComponentsDeclaredByBuilderEntryPoints() + .forEach( + (builderEntryPoint, childComponent) -> { + if (!childComponentsDeclaredByModules().contains(childComponent)) { + builder.add( + bindingFactory.subcomponentCreatorBinding( + builderEntryPoint.methodElement(), typeElement())); + } + }); + return builder.build(); + } + + @Memoized + ImmutableSet<ContributionBinding> moduleBindings() { + return modules().stream() + .map(ModuleDescriptor::bindings) + .flatMap(ImmutableSet::stream) + .collect(toImmutableSet()); + } + + @Memoized + public ImmutableSet<DelegateDeclaration> delegateDeclarations() { + return modules().stream() + .map(ModuleDescriptor::delegateDeclarations) + .flatMap(ImmutableSet::stream) + .collect(toImmutableSet()); + } + + @Memoized + public ImmutableSet<MultibindingDeclaration> multibindingDeclarations() { + return modules().stream() + .map(ModuleDescriptor::multibindingDeclarations) + .flatMap(ImmutableSet::stream) + .collect(toImmutableSet()); + } + + @Memoized + public ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations() { + return modules().stream() + .map(ModuleDescriptor::optionalDeclarations) + .flatMap(ImmutableSet::stream) + .collect(toImmutableSet()); + } + + @Memoized + public ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations() { + return modules().stream() + .map(ModuleDescriptor::subcomponentDeclarations) + .flatMap(ImmutableSet::stream) + .collect(toImmutableSet()); + } + @Memoized @Override public int hashCode() { @@ -378,7 +491,7 @@ * Returns {@code true} if a method could be a component entry point but not a members-injection * method. */ - static boolean isComponentContributionMethod(XMethodElement method) { + private static boolean isComponentContributionMethod(XMethodElement method) { return method.getParameters().isEmpty() && !isVoid(method.getReturnType()) && !method.getEnclosingElement().getClassName().equals(TypeName.OBJECT) @@ -386,7 +499,7 @@ } /** Returns {@code true} if a method could be a component production entry point. */ - static boolean isComponentProductionMethod(XMethodElement method) { + private static boolean isComponentProductionMethod(XMethodElement method) { return isComponentContributionMethod(method) && isFutureType(method.getReturnType()); } @@ -394,6 +507,7 @@ @Singleton public static final class Factory implements ClearableCache { private final XProcessingEnv processingEnv; + private final BindingFactory bindingFactory; private final DependencyRequestFactory dependencyRequestFactory; private final ModuleDescriptor.Factory moduleDescriptorFactory; private final InjectionAnnotations injectionAnnotations; @@ -403,11 +517,13 @@ @Inject Factory( XProcessingEnv processingEnv, + BindingFactory bindingFactory, DependencyRequestFactory dependencyRequestFactory, ModuleDescriptor.Factory moduleDescriptorFactory, InjectionAnnotations injectionAnnotations, DaggerSuperficialValidation superficialValidation) { this.processingEnv = processingEnv; + this.bindingFactory = bindingFactory; this.dependencyRequestFactory = dependencyRequestFactory; this.moduleDescriptorFactory = moduleDescriptorFactory; this.injectionAnnotations = injectionAnnotations; @@ -514,17 +630,20 @@ .map(this::subcomponentDescriptor) .collect(toImmutableSet()); - return new AutoValue_ComponentDescriptor( - componentAnnotation, - typeElement, - componentDependencies, - transitiveModules, - scopes, - subcomponentsFromModules, - subcomponentsByFactoryMethod.buildOrThrow(), - subcomponentsByBuilderMethod.buildOrThrow(), - componentMethodsBuilder.build(), - creatorDescriptor); + ComponentDescriptor componentDescriptor = + new AutoValue_ComponentDescriptor( + componentAnnotation, + typeElement, + componentDependencies, + transitiveModules, + scopes, + subcomponentsFromModules, + subcomponentsByFactoryMethod.buildOrThrow(), + subcomponentsByBuilderMethod.buildOrThrow(), + componentMethodsBuilder.build(), + creatorDescriptor); + componentDescriptor.bindingFactory = bindingFactory; + return componentDescriptor; } private ComponentMethodDescriptor getDescriptorForComponentMethod(
diff --git a/java/dagger/internal/codegen/binding/ComponentRequirement.java b/java/dagger/internal/codegen/binding/ComponentRequirement.java index 1779ec1..5813506 100644 --- a/java/dagger/internal/codegen/binding/ComponentRequirement.java +++ b/java/dagger/internal/codegen/binding/ComponentRequirement.java
@@ -34,6 +34,7 @@ import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.xprocessing.Nullability; import dagger.internal.codegen.xprocessing.XTypeElements; import java.util.Optional; @@ -106,6 +107,16 @@ */ abstract Optional<NullPolicy> overrideNullPolicy(); + /** + * The nullability of the requirement. If set, this is used to determine the nullability of the + * requirement's type. + */ + public Nullability getNullability() { + return nullability; + } + + private Nullability nullability = Nullability.NOT_NULLABLE; + /** The requirement's null policy. */ public NullPolicy nullPolicy() { if (overrideNullPolicy().isPresent()) { @@ -179,6 +190,10 @@ return ParameterSpec.builder(type().getTypeName(), variableName()).build(); } + public static ComponentRequirement forDependency(ComponentDependencyBinding binding) { + return forDependency(binding.key().type().xprocessing()); + } + public static ComponentRequirement forDependency(XType type) { checkArgument(isDeclared(checkNotNull(type))); return create(Kind.DEPENDENCY, type); @@ -189,18 +204,20 @@ return create(Kind.MODULE, type); } - public static ComponentRequirement forBoundInstance(ContributionBinding binding) { + public static ComponentRequirement forBoundInstance(BoundInstanceBinding binding) { checkArgument(binding.kind().equals(BindingKind.BOUND_INSTANCE)); - return forBoundInstance(binding.key(), binding.isNullable(), binding.bindingElement().get()); + return forBoundInstance( + binding.key(), binding.isNullable(), binding.bindingElement().get(), binding.nullability()); } static ComponentRequirement forBoundInstance( - Key key, boolean nullable, XElement elementForVariableName) { + Key key, boolean nullable, XElement elementForVariableName, Nullability nullability) { return create( Kind.BOUND_INSTANCE, key.type().xprocessing(), nullable ? Optional.of(NullPolicy.ALLOW) : Optional.empty(), Optional.of(key), + nullability, getSimpleName(elementForVariableName)); } @@ -208,9 +225,10 @@ return create( kind, type, - Optional.empty(), - Optional.empty(), - simpleVariableName(type.getTypeElement().getClassName())); + /* overrideNullPolicy= */ Optional.empty(), + /* key= */ Optional.empty(), + Nullability.NOT_NULLABLE, + simpleVariableName(type.getTypeElement().asClassName())); } private static ComponentRequirement create( @@ -218,10 +236,12 @@ XType type, Optional<NullPolicy> overrideNullPolicy, Optional<Key> key, + Nullability nullability, String variableName) { ComponentRequirement requirement = new AutoValue_ComponentRequirement( kind, type.getTypeName(), overrideNullPolicy, key, variableName); + requirement.nullability = nullability; requirement.type = type; return requirement; }
diff --git a/java/dagger/internal/codegen/binding/ContributionBinding.java b/java/dagger/internal/codegen/binding/ContributionBinding.java index f8950a3..9cfc722 100644 --- a/java/dagger/internal/codegen/binding/ContributionBinding.java +++ b/java/dagger/internal/codegen/binding/ContributionBinding.java
@@ -16,23 +16,27 @@ package dagger.internal.codegen.binding; +import static com.google.common.base.Preconditions.checkState; import static dagger.internal.codegen.xprocessing.XElements.asMethod; -import static java.util.Arrays.asList; +import static dagger.internal.codegen.xprocessing.XElements.isAbstract; +import static dagger.internal.codegen.xprocessing.XElements.isStatic; +import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XElementKt; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableSet; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CheckReturnValue; -import dagger.internal.codegen.base.ContributionType; import dagger.internal.codegen.base.ContributionType.HasContributionType; import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.base.SetType; +import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.model.BindingKind; -import dagger.internal.codegen.model.DaggerAnnotation; -import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.Scope; +import dagger.internal.codegen.xprocessing.Nullability; import dagger.internal.codegen.xprocessing.XTypes; import java.util.Optional; @@ -46,8 +50,20 @@ /** Returns the nullability of this binding. */ public abstract Nullability nullability(); - // Note: We're using DaggerAnnotation instead of XAnnotation for its equals/hashcode - public abstract Optional<DaggerAnnotation> mapKey(); + private static final ImmutableSet<BindingKind> KINDS_TO_CHECK_FOR_NULL = + ImmutableSet.of(BindingKind.PROVISION, BindingKind.COMPONENT_PROVISION); + + public boolean shouldCheckForNull(CompilerOptions compilerOptions) { + return KINDS_TO_CHECK_FOR_NULL.contains(kind()) + && contributedPrimitiveType().isEmpty() + && !isNullable() + && compilerOptions.doCheckForNulls(); + } + + /** Returns the map key if this is a {@code Map} multibinding contribution. */ + public Optional<XAnnotation> mapKey() { + return bindingElement().flatMap(MapKeys::getMapKey); + } /** If {@link #bindingElement()} is a method that returns a primitive type, returns that type. */ public final Optional<XType> contributedPrimitiveType() { @@ -59,7 +75,11 @@ @Override public boolean requiresModuleInstance() { - return !isContributingModuleKotlinObject() && super.requiresModuleInstance(); + return contributingModule().isPresent() + && bindingElement().isPresent() + && !isAbstract(bindingElement().get()) + && !isStatic(bindingElement().get()) + && !isContributingModuleKotlinObject(); } @Override @@ -97,33 +117,47 @@ public abstract Builder<?, ?> toBuilder(); + /** Returns a new {@link ContributionBinding} with the given {@link BindingType}. */ + final ContributionBinding withBindingType(BindingType bindingType) { + checkState(optionalBindingType().isEmpty()); + switch (kind()) { + case DELEGATE: + return ((DelegateBinding) this).toBuilder() + .optionalBindingType(Optional.of(bindingType)) + .build(); + case OPTIONAL: + return ((OptionalBinding) this).toBuilder() + .optionalBindingType(Optional.of(bindingType)) + .build(); + case MULTIBOUND_MAP: + return ((MultiboundMapBinding) this).toBuilder() + .optionalBindingType(Optional.of(bindingType)) + .build(); + case MULTIBOUND_SET: + return ((MultiboundSetBinding) this).toBuilder() + .optionalBindingType(Optional.of(bindingType)) + .build(); + default: + throw new AssertionError("Unexpected binding kind: " + kind()); + } + } + /** * Base builder for {@link com.google.auto.value.AutoValue @AutoValue} subclasses of {@link * ContributionBinding}. */ - public abstract static class Builder<C extends ContributionBinding, B extends Builder<C, B>> { + abstract static class Builder<C extends ContributionBinding, B extends Builder<C, B>> { @CanIgnoreReturnValue - public abstract B dependencies(Iterable<DependencyRequest> dependencies); + abstract B unresolved(Optional<? extends Binding> unresolved); @CanIgnoreReturnValue - public B dependencies(DependencyRequest... dependencies) { - return dependencies(asList(dependencies)); - } - - @CanIgnoreReturnValue - public abstract B unresolved(C unresolved); - - @CanIgnoreReturnValue - public abstract B contributionType(ContributionType contributionType); - - @CanIgnoreReturnValue - public abstract B bindingElement(XElement bindingElement); + abstract B bindingElement(XElement bindingElement); @CanIgnoreReturnValue abstract B bindingElement(Optional<XElement> bindingElement); @CanIgnoreReturnValue - public final B clearBindingElement() { + final B clearBindingElement() { return bindingElement(Optional.empty()); }; @@ -131,16 +165,10 @@ abstract B contributingModule(XTypeElement contributingModule); @CanIgnoreReturnValue - public abstract B key(Key key); + abstract B key(Key key); @CanIgnoreReturnValue - public abstract B nullability(Nullability nullability); - - @CanIgnoreReturnValue - abstract B mapKey(Optional<DaggerAnnotation> mapKey); - - @CanIgnoreReturnValue - public abstract B kind(BindingKind kind); + abstract B scope(Optional<Scope> scope); abstract C build(); }
diff --git a/java/dagger/internal/codegen/binding/Declaration.java b/java/dagger/internal/codegen/binding/Declaration.java new file mode 100644 index 0000000..a980820 --- /dev/null +++ b/java/dagger/internal/codegen/binding/Declaration.java
@@ -0,0 +1,88 @@ +/* + * 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.binding; + +import static dagger.internal.codegen.extension.Optionals.emptiesLast; +import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import static java.util.Comparator.comparing; + +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XTypeElement; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.xprocessing.XElements; +import java.util.Comparator; +import java.util.Optional; + +/** An object that declares or specifies a binding. */ +public abstract class Declaration { + /** + * A comparator that compares binding declarations with elements. + * + * <p>Compares, in order: + * + * <ol> + * <li>Contributing module or enclosing type name + * <li>Binding element's simple name + * <li>Binding element's type + * </ol> + * + * Any binding declarations without elements are last. + */ + public static final Comparator<Declaration> COMPARATOR = + comparing( + (Declaration declaration) -> + declaration.contributingModule().isPresent() + ? declaration.contributingModule() + : declaration.bindingTypeElement(), + emptiesLast(comparing(XTypeElement::getQualifiedName))) + .thenComparing( + Declaration::bindingElement, + emptiesLast( + comparing((XElement element) -> getSimpleName(element)) + .thenComparing(XElements::toStableString))); + + /** The {@link Key} of this declaration. */ + public abstract Key key(); + + /** + * The {@link XElement} that declares this binding. Absent for {@linkplain BindingKind binding + * kinds} that are not always declared by exactly one element. + * + * <p>For example, consider {@link BindingKind#MULTIBOUND_SET}. A component with many + * {@code @IntoSet} bindings for the same key will have a synthetic binding that depends on all + * contributions, but with no identifying binding element. A {@code @Multibinds} method will also + * contribute a synthetic binding, but since multiple {@code @Multibinds} methods can coexist in + * the same component (and contribute to one single binding), it has no binding element. + */ + public abstract Optional<XElement> bindingElement(); + + /** + * The type enclosing the {@link #bindingElement()}, or {@link Optional#empty()} if {@link + * #bindingElement()} is empty. + */ + public final Optional<XTypeElement> bindingTypeElement() { + return bindingElement().map(XElements::closestEnclosingTypeElement); + } + + /** + * The installed module class that contributed the {@link #bindingElement()}. May be a subclass of + * the class that contains {@link #bindingElement()}. Absent if {@link #bindingElement()} is + * empty. + */ + public abstract Optional<XTypeElement> contributingModule(); +}
diff --git a/java/dagger/internal/codegen/binding/BindingDeclarationFormatter.java b/java/dagger/internal/codegen/binding/DeclarationFormatter.java similarity index 77% rename from java/dagger/internal/codegen/binding/BindingDeclarationFormatter.java rename to java/dagger/internal/codegen/binding/DeclarationFormatter.java index d55886b..eaa8b4f 100644 --- a/java/dagger/internal/codegen/binding/BindingDeclarationFormatter.java +++ b/java/dagger/internal/codegen/binding/DeclarationFormatter.java
@@ -32,27 +32,27 @@ import javax.inject.Inject; /** - * Formats a {@link BindingDeclaration} into a {@link String} suitable for use in error messages. + * Formats a {@link Declaration} into a {@link String} suitable for use in error messages. */ -public final class BindingDeclarationFormatter extends Formatter<BindingDeclaration> { +public final class DeclarationFormatter extends Formatter<Declaration> { private final MethodSignatureFormatter methodSignatureFormatter; @Inject - BindingDeclarationFormatter(MethodSignatureFormatter methodSignatureFormatter) { + DeclarationFormatter(MethodSignatureFormatter methodSignatureFormatter) { this.methodSignatureFormatter = methodSignatureFormatter; } /** * Returns {@code true} for declarations that this formatter can format. Specifically bindings - * from subcomponent declarations or those with {@linkplain BindingDeclaration#bindingElement() + * from subcomponent declarations or those with {@linkplain Declaration#bindingElement() * binding elements} that are methods, constructors, or types. */ - public boolean canFormat(BindingDeclaration bindingDeclaration) { - if (bindingDeclaration instanceof SubcomponentDeclaration) { + public boolean canFormat(Declaration declaration) { + if (declaration instanceof SubcomponentDeclaration) { return true; } - if (bindingDeclaration.bindingElement().isPresent()) { - XElement bindingElement = bindingDeclaration.bindingElement().get(); + if (declaration.bindingElement().isPresent()) { + XElement bindingElement = declaration.bindingElement().get(); return isMethodParameter(bindingElement) || isTypeElement(bindingElement) || isExecutable(bindingElement); @@ -62,13 +62,13 @@ } @Override - public String format(BindingDeclaration bindingDeclaration) { - if (bindingDeclaration instanceof SubcomponentDeclaration) { - return formatSubcomponentDeclaration((SubcomponentDeclaration) bindingDeclaration); + public String format(Declaration declaration) { + if (declaration instanceof SubcomponentDeclaration) { + return formatSubcomponentDeclaration((SubcomponentDeclaration) declaration); } - if (bindingDeclaration.bindingElement().isPresent()) { - XElement bindingElement = bindingDeclaration.bindingElement().get(); + if (declaration.bindingElement().isPresent()) { + XElement bindingElement = declaration.bindingElement().get(); if (isMethodParameter(bindingElement)) { return elementToString(bindingElement); } else if (isTypeElement(bindingElement)) { @@ -77,14 +77,14 @@ } else if (isExecutable(bindingElement)) { return methodSignatureFormatter.format( asExecutable(bindingElement), - bindingDeclaration.contributingModule().map(XTypeElement::getType)); + declaration.contributingModule().map(XTypeElement::getType)); } throw new IllegalArgumentException("Formatting unsupported for element: " + bindingElement); } return String.format( "Dagger-generated binding for %s", - stripCommonTypePrefixes(bindingDeclaration.key().toString())); + stripCommonTypePrefixes(declaration.key().toString())); } private String formatSubcomponentDeclaration(SubcomponentDeclaration subcomponentDeclaration) {
diff --git a/java/dagger/internal/codegen/binding/DelegateBinding.java b/java/dagger/internal/codegen/binding/DelegateBinding.java new file mode 100644 index 0000000..b6f7b9c --- /dev/null +++ b/java/dagger/internal/codegen/binding/DelegateBinding.java
@@ -0,0 +1,78 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#DELEGATE}. */ +@CheckReturnValue +@AutoValue +public abstract class DelegateBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.DELEGATE; + } + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(delegateRequest()); + } + + /** Returns a request for the binding that this binding delegates to. */ + abstract DependencyRequest delegateRequest(); + + @Override + public boolean requiresModuleInstance() { + return false; + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_DelegateBinding.Builder(); + } + + /** A {@link DelegateBinding} builder. */ + @AutoValue.Builder + abstract static class Builder extends ContributionBinding.Builder<DelegateBinding, Builder> { + abstract Builder delegateRequest(DependencyRequest delegateRequest); + + abstract Builder optionalBindingType(Optional<BindingType> bindingType); + + abstract Builder contributionType(ContributionType contributionType); + + abstract Builder nullability(Nullability nullability); + } +}
diff --git a/java/dagger/internal/codegen/binding/DelegateDeclaration.java b/java/dagger/internal/codegen/binding/DelegateDeclaration.java index 76d4287..c8365a8 100644 --- a/java/dagger/internal/codegen/binding/DelegateDeclaration.java +++ b/java/dagger/internal/codegen/binding/DelegateDeclaration.java
@@ -37,7 +37,7 @@ /** The declaration for a delegate binding established by a {@link Binds} method. */ @AutoValue -public abstract class DelegateDeclaration extends BindingDeclaration +public abstract class DelegateDeclaration extends Declaration implements HasContributionType { abstract DependencyRequest delegateRequest();
diff --git a/java/dagger/internal/codegen/binding/DependencyRequestFactory.java b/java/dagger/internal/codegen/binding/DependencyRequestFactory.java index a96eeda..bd16acc 100644 --- a/java/dagger/internal/codegen/binding/DependencyRequestFactory.java +++ b/java/dagger/internal/codegen/binding/DependencyRequestFactory.java
@@ -21,13 +21,11 @@ import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.base.RequestKinds.extractKeyType; -import static dagger.internal.codegen.base.RequestKinds.frameworkClassName; import static dagger.internal.codegen.base.RequestKinds.getRequestKind; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedParameter; import static dagger.internal.codegen.model.RequestKind.FUTURE; import static dagger.internal.codegen.model.RequestKind.INSTANCE; import static dagger.internal.codegen.model.RequestKind.MEMBERS_INJECTION; -import static dagger.internal.codegen.model.RequestKind.PRODUCER; import static dagger.internal.codegen.model.RequestKind.PROVIDER; import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf; import static dagger.internal.codegen.xprocessing.XTypes.unwrapType; @@ -47,6 +45,7 @@ import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.Nullability; import java.util.List; import java.util.Optional; import javax.inject.Inject; @@ -104,21 +103,11 @@ .build(); } - // TODO(b/28555349): support PROVIDER_OF_LAZY here too - private static final ImmutableSet<RequestKind> WRAPPING_MAP_VALUE_FRAMEWORK_TYPES = - ImmutableSet.of(PROVIDER, PRODUCER); - private RequestKind multibindingContributionRequestKind( Key multibindingKey, ContributionBinding multibindingContribution) { switch (multibindingContribution.contributionType()) { case MAP: - MapType mapType = MapType.from(multibindingKey); - for (RequestKind kind : WRAPPING_MAP_VALUE_FRAMEWORK_TYPES) { - if (mapType.valuesAreTypeOf(frameworkClassName(kind))) { - return kind; - } - } - // fall through + return MapType.from(multibindingKey).valueRequestKind(); case SET: case SET_VALUES: return INSTANCE; @@ -206,15 +195,14 @@ * Returns a synthetic request for the present value of an optional binding generated from a * {@link dagger.BindsOptionalOf} declaration. */ - DependencyRequest forSyntheticPresentOptionalBinding(Key requestKey, RequestKind kind) { + DependencyRequest forSyntheticPresentOptionalBinding(Key requestKey) { Optional<Key> key = keyFactory.unwrapOptional(requestKey); checkArgument(key.isPresent(), "not a request for optional: %s", requestKey); + RequestKind kind = getRequestKind(OptionalType.from(requestKey).valueType()); return DependencyRequest.builder() .kind(kind) .key(key.get()) - .isNullable( - requestKindImplicitlyAllowsNull( - getRequestKind(OptionalType.from(requestKey).valueType()))) + .isNullable(requestKindImplicitlyAllowsNull(kind)) .build(); }
diff --git a/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java b/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java index 853ee99..20f0b12 100644 --- a/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java +++ b/java/dagger/internal/codegen/binding/DependencyRequestFormatter.java
@@ -21,11 +21,16 @@ import static androidx.room.compiler.processing.XElementKt.isVariableElement; import static dagger.internal.codegen.base.ElementFormatter.elementToString; import static dagger.internal.codegen.base.RequestKinds.requestType; +import static java.util.stream.Collectors.joining; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XProcessingEnv; -import com.google.errorprone.annotations.CanIgnoreReturnValue; +import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableCollection; import dagger.internal.codegen.base.Formatter; +import dagger.internal.codegen.model.BindingGraph; +import dagger.internal.codegen.model.BindingGraph.DependencyEdge; +import dagger.internal.codegen.model.BindingGraph.Node; import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.xprocessing.XTypes; @@ -58,12 +63,33 @@ this.processingEnv = processingEnv; } + public String formatEdges(ImmutableCollection<DependencyEdge> edges, BindingGraph graph) { + return edges.stream() + .map(edge -> formatEdge(edge, graph)) + .filter(line -> !line.isEmpty()) + .collect(joining("\n")); + } + + public String formatEdge(DependencyEdge edge, BindingGraph graph) { + Node sourceNode = graph.network().incidentNodes(edge).source(); + XTypeElement sourceComponent = sourceNode.componentPath().currentComponent().xprocessing(); + return format(Optional.of(sourceComponent), edge.dependencyRequest()); + } + @Override public String format(DependencyRequest request) { + return format(Optional.empty(), request); + } + + private String format(Optional<XTypeElement> optionalComponent, DependencyRequest request) { if (!request.requestElement().isPresent()) { return ""; } XElement requestElement = request.requestElement().get().xprocessing(); + String componentReference = + optionalComponent + .map(component -> String.format("[%s] ", component.getQualifiedName())) + .orElse(""); if (isMethod(requestElement)) { return INDENT + request.key() @@ -71,6 +97,7 @@ + componentMethodRequestVerb(request) + " at\n" + DOUBLE_INDENT + + componentReference + elementToString(requestElement); } else if (isVariableElement(requestElement)) { return INDENT @@ -79,6 +106,7 @@ requestType(request.kind(), request.key().type().xprocessing(), processingEnv)) + " is injected at\n" + DOUBLE_INDENT + + componentReference + elementToString(requestElement); } else if (isTypeElement(requestElement)) { return ""; // types by themselves provide no useful information. @@ -87,21 +115,7 @@ } } - /** - * Appends a newline and the formatted dependency request unless {@link - * #format(DependencyRequest)} returns the empty string. - */ - @CanIgnoreReturnValue - public StringBuilder appendFormatLine( - StringBuilder builder, DependencyRequest dependencyRequest) { - String formatted = format(dependencyRequest); - if (!formatted.isEmpty()) { - builder.append('\n').append(formatted); - } - return builder; - } - - private String formatQualifier(Optional<DaggerAnnotation> maybeQualifier) { + private static String formatQualifier(Optional<DaggerAnnotation> maybeQualifier) { return maybeQualifier.map(qualifier -> qualifier + " ").orElse(""); } @@ -109,7 +123,7 @@ * Returns the verb for a component method dependency request. Returns "produced", "provided", or * "injected", depending on the kind of request. */ - private String componentMethodRequestVerb(DependencyRequest request) { + private static String componentMethodRequestVerb(DependencyRequest request) { switch (request.kind()) { case FUTURE: case PRODUCER:
diff --git a/java/dagger/internal/codegen/binding/FrameworkField.java b/java/dagger/internal/codegen/binding/FrameworkField.java index a9f3bbf..bb51968 100644 --- a/java/dagger/internal/codegen/binding/FrameworkField.java +++ b/java/dagger/internal/codegen/binding/FrameworkField.java
@@ -20,18 +20,17 @@ 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.collect.Iterables.getLast; import static dagger.internal.codegen.model.BindingKind.MEMBERS_INJECTOR; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import androidx.room.compiler.codegen.XClassName; +import androidx.room.compiler.codegen.XTypeName; 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; /** @@ -51,18 +50,13 @@ /** * Creates a framework 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 + * @param frameworkClassName the framework class that wraps the type (e.g., {@code Provider}). + * @param type the base type of the field (e.g., {@code Foo}). */ - 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( - fieldType, - fieldName.endsWith(suffix) ? fieldName : fieldName + suffix); + public static FrameworkField create(String fieldName, XClassName frameworkClassName, XType type) { + return createInternal(fieldName, frameworkClassName, Optional.of(type)); } /** @@ -72,15 +66,24 @@ * one for the binding's type. */ public static FrameworkField forBinding( - ContributionBinding binding, Optional<ClassName> frameworkClassName) { - return create( - fieldType(binding, frameworkClassName.orElse(binding.frameworkType().frameworkClassName())), - frameworkFieldName(binding)); + ContributionBinding binding, Optional<XClassName> frameworkClassName) { + return createInternal( + bindingName(binding), + frameworkClassName.orElse(binding.frameworkType().frameworkClassName()), + bindingType(binding)); } - private static TypeName fieldType(ContributionBinding binding, ClassName frameworkClassName) { + private static String bindingName(ContributionBinding binding) { + if (binding.bindingElement().isPresent()) { + String name = bindingElementName(binding.bindingElement().get()); + return binding.kind().equals(MEMBERS_INJECTOR) ? name + "MembersInjector" : name; + } + return KeyVariableNamer.name(binding.key()); + } + + private static Optional<XType> bindingType(ContributionBinding binding) { if (binding.contributionType().isMultibinding()) { - return ParameterizedTypeName.get(frameworkClassName, binding.contributedType().getTypeName()); + return Optional.of(binding.contributedType()); } // If the binding key type is a Map<K, Provider<V>>, we need to change field type to a raw @@ -89,19 +92,25 @@ // 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 Optional.empty(); } - return ParameterizedTypeName.get( - frameworkClassName, binding.key().type().xprocessing().getTypeName()); + return Optional.of(binding.key().type().xprocessing()); } - private static String frameworkFieldName(ContributionBinding binding) { - if (binding.bindingElement().isPresent()) { - String name = bindingElementName(binding.bindingElement().get()); - return binding.kind().equals(MEMBERS_INJECTOR) ? name + "MembersInjector" : name; - } - return KeyVariableNamer.name(binding.key()); + private static FrameworkField createInternal( + String fieldName, XClassName frameworkClassName, Optional<XType> type) { + return new AutoValue_FrameworkField( + frameworkFieldName(fieldName, frameworkClassName), + type.isPresent() + ? frameworkClassName.parametrizedBy(type.get().asTypeName()) + // Use a raw framework classname, e.g. Provider + : frameworkClassName); + } + + private static String frameworkFieldName(String fieldName, XClassName frameworkClassName) { + String suffix = getLast(frameworkClassName.getSimpleNames()); + return fieldName.endsWith(suffix) ? fieldName : fieldName + suffix; } private static String bindingElementName(XElement bindingElement) { @@ -118,7 +127,7 @@ } } - public abstract TypeName type(); - public abstract String name(); + + public abstract XTypeName type(); }
diff --git a/java/dagger/internal/codegen/binding/FrameworkType.java b/java/dagger/internal/codegen/binding/FrameworkType.java index c995948..bc4c8ce 100644 --- a/java/dagger/internal/codegen/binding/FrameworkType.java +++ b/java/dagger/internal/codegen/binding/FrameworkType.java
@@ -16,11 +16,12 @@ package dagger.internal.codegen.binding; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; +import androidx.room.compiler.codegen.XClassName; import androidx.room.compiler.processing.XProcessingEnv; -import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; @@ -29,6 +30,7 @@ import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.XTypeNames; import java.util.Optional; /** One of the core types initialized as fields in a generated component. */ @@ -142,9 +144,7 @@ from.codeBlock())); case PRODUCER: - return Expression.create(from.type(), to( - requestKind, - from.codeBlock())); + return from; default: throw new IllegalArgumentException( @@ -170,28 +170,30 @@ switch (requestKind) { case PROVIDER: return Optional.of(FrameworkType.PROVIDER); + case PRODUCER: + return Optional.of(FrameworkType.PRODUCER_NODE); default: return Optional.empty(); } } /** The class of fields of this type. */ - public ClassName frameworkClassName() { + public XClassName frameworkClassName() { switch (this) { case PROVIDER: - return TypeNames.DAGGER_PROVIDER; + return XTypeNames.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 // made to not implement Producer. - return TypeNames.PRODUCER; + return XTypeNames.PRODUCER; } throw new AssertionError("Unknown value: " + this.name()); } /** Returns the {@link #frameworkClassName()} parameterized with a type. */ public ParameterizedTypeName frameworkClassOf(TypeName valueType) { - return ParameterizedTypeName.get(frameworkClassName(), valueType); + return ParameterizedTypeName.get(toJavaPoet(frameworkClassName()), valueType); } /** The request kind that an instance of this framework type can satisfy directly, if any. */
diff --git a/java/dagger/internal/codegen/binding/InjectBindingRegistry.java b/java/dagger/internal/codegen/binding/InjectBindingRegistry.java index 45fea0a..46d57f7 100644 --- a/java/dagger/internal/codegen/binding/InjectBindingRegistry.java +++ b/java/dagger/internal/codegen/binding/InjectBindingRegistry.java
@@ -36,10 +36,9 @@ */ public interface InjectBindingRegistry { /** - * Returns a {@link ProvisionBinding} for {@code key}. If none has been registered yet, registers - * one. + * Returns an injection binding for {@code key}. If none has been registered yet, registers one. */ - Optional<ProvisionBinding> getOrFindProvisionBinding(Key key); + Optional<ContributionBinding> getOrFindInjectionBinding(Key key); /** * Returns a {@link MembersInjectionBinding} for {@code key}. If none has been registered yet, @@ -48,13 +47,14 @@ Optional<MembersInjectionBinding> getOrFindMembersInjectionBinding(Key key); /** - * Returns a {@link ProvisionBinding} for a {@link dagger.MembersInjector} of {@code key}. If none - * has been registered yet, registers one. + * Returns a {@link MembersInjectorBinding} for {@code key}. If none has been registered yet, + * registers one. */ - Optional<ProvisionBinding> getOrFindMembersInjectorProvisionBinding(Key key); + Optional<MembersInjectorBinding> getOrFindMembersInjectorBinding(Key key); @CanIgnoreReturnValue - Optional<ProvisionBinding> tryRegisterInjectConstructor(XConstructorElement constructorElement); + Optional<ContributionBinding> tryRegisterInjectConstructor( + XConstructorElement constructorElement); @CanIgnoreReturnValue Optional<MembersInjectionBinding> tryRegisterInjectField(XFieldElement fieldElement); @@ -64,11 +64,11 @@ /** * This method ensures that sources for all registered {@link Binding bindings} (either explicitly - * or implicitly via {@link #getOrFindMembersInjectionBinding} or {@link - * #getOrFindProvisionBinding}) are generated. + * or implicitly via {@link #getOrFindMembersInjectionBinding} or + * {@link #getOrFindInjectionBinding}) are generated. */ void generateSourcesForRequiredBindings( - SourceFileGenerator<ProvisionBinding> factoryGenerator, + SourceFileGenerator<ContributionBinding> factoryGenerator, SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator) throws SourceFileGenerationException; }
diff --git a/java/dagger/internal/codegen/binding/InjectionAnnotations.java b/java/dagger/internal/codegen/binding/InjectionAnnotations.java index d4e1f90..13abe8b 100644 --- a/java/dagger/internal/codegen/binding/InjectionAnnotations.java +++ b/java/dagger/internal/codegen/binding/InjectionAnnotations.java
@@ -36,6 +36,7 @@ import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; +import androidx.room.compiler.codegen.XClassName; import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XElement; @@ -45,7 +46,6 @@ 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; @@ -54,6 +54,7 @@ import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.Scope; import dagger.internal.codegen.xprocessing.XAnnotations; +import dagger.internal.codegen.xprocessing.XTypeNames; import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; @@ -165,10 +166,10 @@ private Optional<XAnnotation> getScopeMetadata(XElement element) { return getGeneratedNameForScopeMetadata(element) .flatMap(factoryName -> Optional.ofNullable(processingEnv.findTypeElement(factoryName))) - .flatMap(factory -> Optional.ofNullable(factory.getAnnotation(TypeNames.SCOPE_METADATA))); + .flatMap(factory -> Optional.ofNullable(factory.getAnnotation(XTypeNames.SCOPE_METADATA))); } - private Optional<ClassName> getGeneratedNameForScopeMetadata(XElement element) { + private Optional<XClassName> getGeneratedNameForScopeMetadata(XElement element) { // Currently, we only support ScopeMetadata for inject-constructor types and provides methods. if (isTypeElement(element)) { return asTypeElement(element).getConstructors().stream() @@ -297,10 +298,10 @@ private Optional<XAnnotation> getQualifierMetadata(XElement element) { return getGeneratedNameForQualifierMetadata(element) .flatMap(name -> Optional.ofNullable(processingEnv.findTypeElement(name))) - .flatMap(type -> Optional.ofNullable(type.getAnnotation(TypeNames.QUALIFIER_METADATA))); + .flatMap(type -> Optional.ofNullable(type.getAnnotation(XTypeNames.QUALIFIER_METADATA))); } - private Optional<ClassName> getGeneratedNameForQualifierMetadata(XElement element) { + private Optional<XClassName> getGeneratedNameForQualifierMetadata(XElement element) { // Currently we only support @QualifierMetadata for @Inject fields, @Inject method parameters, // @Inject constructor parameters, @Provides methods, and @Provides method parameters. if (isField(element) && hasInjectAnnotation(element)) { @@ -349,8 +350,7 @@ return element.hasAnyAnnotation(TypeNames.INJECT, TypeNames.INJECT_JAVAX); } - /** Returns true if the given element is annotated with {@link Inject}. */ - public static boolean hasInjectOrAssistedInjectAnnotation(XElement element) { + private static boolean hasInjectOrAssistedInjectAnnotation(XElement element) { return element.hasAnyAnnotation( TypeNames.INJECT, TypeNames.INJECT_JAVAX, TypeNames.ASSISTED_INJECT); }
diff --git a/java/dagger/internal/codegen/binding/InjectionBinding.java b/java/dagger/internal/codegen/binding/InjectionBinding.java new file mode 100644 index 0000000..657b392 --- /dev/null +++ b/java/dagger/internal/codegen/binding/InjectionBinding.java
@@ -0,0 +1,97 @@ +/* + * 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.binding; + +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#INJECTION}. */ +@CheckReturnValue +@AutoValue +public abstract class InjectionBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.INJECTION; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + /** Dependencies necessary to invoke the {@code @Inject} annotated constructor. */ + public abstract ImmutableSet<DependencyRequest> constructorDependencies(); + + /** {@link InjectionSite}s for all {@code @Inject} members. */ + public abstract ImmutableSortedSet<InjectionSite> injectionSites(); + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.<DependencyRequest>builder() + .addAll(constructorDependencies()) + .addAll( + injectionSites().stream() + .flatMap(i -> i.dependencies().stream()) + .collect(toImmutableSet())) + .build(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_InjectionBinding.Builder(); + } + + /** A {@link InjectionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder extends ContributionBinding.Builder<InjectionBinding, Builder> { + abstract Builder constructorDependencies(Iterable<DependencyRequest> constructorDependencies); + + abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites); + } +}
diff --git a/java/dagger/internal/codegen/binding/KeyFactory.java b/java/dagger/internal/codegen/binding/KeyFactory.java index d7f78c1..693382e 100644 --- a/java/dagger/internal/codegen/binding/KeyFactory.java +++ b/java/dagger/internal/codegen/binding/KeyFactory.java
@@ -24,12 +24,9 @@ import static dagger.internal.codegen.base.RequestKinds.extractKeyType; import static dagger.internal.codegen.binding.MapKeys.getMapKey; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.extension.Optionals.firstPresent; import static dagger.internal.codegen.javapoet.TypeNames.isFutureType; import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; import static dagger.internal.codegen.xprocessing.XTypes.unwrapType; -import static java.util.Arrays.asList; import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XMethodElement; @@ -37,7 +34,6 @@ 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.squareup.javapoet.ClassName; import dagger.Binds; import dagger.BindsOptionalOf; @@ -47,6 +43,7 @@ import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.base.RequestKinds; import dagger.internal.codegen.base.SetType; +import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DaggerExecutableElement; @@ -56,19 +53,22 @@ import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.multibindings.Multibinds; -import java.util.Map; import java.util.Optional; -import java.util.stream.Stream; import javax.inject.Inject; /** A factory for {@link Key}s. */ public final class KeyFactory { private final XProcessingEnv processingEnv; + private final CompilerOptions compilerOptions; private final InjectionAnnotations injectionAnnotations; @Inject - KeyFactory(XProcessingEnv processingEnv, InjectionAnnotations injectionAnnotations) { + KeyFactory( + XProcessingEnv processingEnv, + CompilerOptions compilerOptions, + InjectionAnnotations injectionAnnotations) { this.processingEnv = processingEnv; + this.compilerOptions = compilerOptions; this.injectionAnnotations = injectionAnnotations; } @@ -82,8 +82,23 @@ processingEnv.requireTypeElement(TypeNames.MAP), keyType.boxed(), valueType.boxed()); } + /** + * If {@code key}'s type is {@code Optional<T>} for some {@code T}, returns a key with the same + * qualifier whose type is {@linkplain RequestKinds#extractKeyType(RequestKind, XType)} + * extracted} from {@code T}. + */ + Key optionalOf(Key key) { + return key.withType(DaggerType.from(optionalOf(key.type().xprocessing()))); + } + + private XType optionalOf(XType type) { + return processingEnv.getDeclaredType( + processingEnv.requireTypeElement(TypeNames.JDK_OPTIONAL), type.boxed()); + } + /** Returns {@code Map<KeyType, FrameworkType<ValueType>>}. */ private XType mapOfFrameworkType(XType keyType, ClassName frameworkClassName, XType valueType) { + checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName)); return mapOf( keyType, processingEnv.getDeclaredType( @@ -113,10 +128,12 @@ } public Key forProvidesMethod(XMethodElement method, XTypeElement contributingModule) { + checkArgument(method.hasAnnotation(TypeNames.PROVIDES)); return forBindingMethod(method, contributingModule, Optional.of(TypeNames.PROVIDER)); } public Key forProducesMethod(XMethodElement method, XTypeElement contributingModule) { + checkArgument(method.hasAnnotation(TypeNames.PRODUCES)); return forBindingMethod(method, contributingModule, Optional.of(TypeNames.PRODUCER)); } @@ -205,7 +222,8 @@ method.getAllAnnotations().stream() .map(XAnnotations::toString) .collect(toImmutableList())); - return frameworkClassName.isPresent() + return (frameworkClassName.isPresent() + && compilerOptions.useFrameworkTypeInMapMultibindingContributionKey()) ? mapOfFrameworkType(mapKeyType.get(), frameworkClassName.get(), returnType) : mapOf(mapKeyType.get(), returnType); case SET_VALUES: @@ -219,12 +237,14 @@ /** * Returns the key for a binding associated with a {@link DelegateDeclaration}. * - * <p>If {@code delegateDeclaration} is {@code @IntoMap}, transforms the {@code Map<K, V>} key - * from {@link DelegateDeclaration#key()} to {@code Map<K, FrameworkType<V>>}. If {@code - * delegateDeclaration} is not a map contribution, its key is returned. + * <p>If {@code delegateDeclaration} is a multibinding map contribution and + * {@link CompilerOptions#useFrameworkTypeInMapMultibindingContributionKey()} is enabled, then + * transforms the {@code Map<K, V>} key into {@code Map<K, FrameworkType<V>>}, otherwise returns + * the unaltered key. */ Key forDelegateBinding(DelegateDeclaration delegateDeclaration, ClassName frameworkType) { return delegateDeclaration.contributionType().equals(ContributionType.MAP) + && compilerOptions.useFrameworkTypeInMapMultibindingContributionKey() ? wrapMapValue(delegateDeclaration.key(), frameworkType) : delegateDeclaration.key(); } @@ -268,40 +288,6 @@ } /** - * If {@code requestKey} is for a {@code Map<K, V>} or {@code Map<K, Produced<V>>}, returns keys - * for {@code Map<K, Provider<V>>} and {@code Map<K, Producer<V>>} (if Dagger-Producers is on the - * classpath). - */ - ImmutableSet<Key> implicitFrameworkMapKeys(Key requestKey) { - return Stream.of(implicitMapProviderKeyFrom(requestKey), implicitMapProducerKeyFrom(requestKey)) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(toImmutableSet()); - } - - /** - * Optionally extract a {@link Key} for the underlying provision binding(s) if such a valid key - * can be inferred from the given key. Specifically, if the key represents a {@link Map}{@code <K, - * V>} or {@code Map<K, Producer<V>>}, a key of {@code Map<K, Provider<V>>} will be returned. - */ - Optional<Key> implicitMapProviderKeyFrom(Key possibleMapKey) { - return firstPresent( - rewrapMapKey(possibleMapKey, TypeNames.PRODUCED, TypeNames.PROVIDER), - wrapMapKey(possibleMapKey, TypeNames.PROVIDER)); - } - - /** - * Optionally extract a {@link Key} for the underlying production binding(s) if such a valid key - * can be inferred from the given key. Specifically, if the key represents a {@link Map}{@code <K, - * V>} or {@code Map<K, Produced<V>>}, a key of {@code Map<K, Producer<V>>} will be returned. - */ - Optional<Key> implicitMapProducerKeyFrom(Key possibleMapKey) { - return firstPresent( - rewrapMapKey(possibleMapKey, TypeNames.PRODUCED, TypeNames.PRODUCER), - wrapMapKey(possibleMapKey, TypeNames.PRODUCER)); - } - - /** * If {@code key}'s type is {@code Map<K, Provider<V>>}, {@code Map<K, Producer<V>>}, or {@code * Map<K, Produced<V>>}, returns a key with the same qualifier and {@link * Key#multibindingContributionIdentifier()} whose type is simply {@code Map<K, V>}. @@ -311,82 +297,41 @@ public Key unwrapMapValueType(Key key) { if (MapType.isMap(key)) { MapType mapType = MapType.from(key); - if (!mapType.isRawType()) { - for (ClassName frameworkClass : - asList(TypeNames.PROVIDER, TypeNames.PRODUCER, TypeNames.PRODUCED)) { - if (mapType.valuesAreTypeOf(frameworkClass)) { - return key.withType( - DaggerType.from( - mapOf(mapType.keyType(), mapType.unwrappedValueType(frameworkClass)))); - } - } + if (!mapType.isRawType() && mapType.valuesAreFrameworkType()) { + return key.withType( + DaggerType.from(mapOf(mapType.keyType(), mapType.unwrappedFrameworkValueType()))); } } return key; } - /** Converts a {@link Key} of type {@code Map<K, V>} to {@code Map<K, Provider<V>>}. */ - private Key wrapMapValue(Key key, ClassName newWrappingClassName) { - checkArgument(FrameworkTypes.isFrameworkType(processingEnv.requireType(newWrappingClassName))); - return wrapMapKey(key, newWrappingClassName).get(); - } - /** - * If {@code key}'s type is {@code Map<K, CurrentWrappingClass<Bar>>}, returns a key with type - * {@code Map<K, NewWrappingClass<Bar>>} with the same qualifier. Otherwise returns {@link - * Optional#empty()}. + * Returns a key with the type {@code Map<K, FrameworkType<V>>} if the given key has a type of + * {@code Map<K, V>}. Otherwise, returns the unaltered key. * - * <p>Returns {@link Optional#empty()} if {@code newWrappingClass} is not in the classpath. - * - * @throws IllegalArgumentException if {@code newWrappingClass} is the same as {@code - * currentWrappingClass} + * @throws IllegalArgumentException if the {@code frameworkClassName} is not a valid framework + * type for multibinding maps. + * @throws IllegalStateException if the {@code key} is already wrapped in a (different) framework + * type. */ - public Optional<Key> rewrapMapKey( - Key possibleMapKey, ClassName currentWrappingClassName, ClassName newWrappingClassName) { - checkArgument(!currentWrappingClassName.equals(newWrappingClassName)); - if (MapType.isMap(possibleMapKey)) { - MapType mapType = MapType.from(possibleMapKey); - if (!mapType.isRawType() && mapType.valuesAreTypeOf(currentWrappingClassName)) { - XTypeElement wrappingElement = processingEnv.findTypeElement(newWrappingClassName); - if (wrappingElement == null) { + private Key wrapMapValue(Key key, ClassName frameworkClassName) { + checkArgument(FrameworkTypes.MAP_VALUE_FRAMEWORK_TYPES.contains(frameworkClassName)); + if (MapType.isMap(key)) { + MapType mapType = MapType.from(key); + if (!mapType.isRawType() && !mapType.valuesAreTypeOf(frameworkClassName)) { + checkState(!mapType.valuesAreFrameworkType()); + XTypeElement frameworkTypeElement = processingEnv.findTypeElement(frameworkClassName); + if (frameworkTypeElement == null) { // This target might not be compiled with Producers, so wrappingClass might not have an // associated element. - return Optional.empty(); + return key; } XType wrappedValueType = - processingEnv.getDeclaredType( - wrappingElement, mapType.unwrappedValueType(currentWrappingClassName)); - return Optional.of( - possibleMapKey.withType(DaggerType.from(mapOf(mapType.keyType(), wrappedValueType)))); + processingEnv.getDeclaredType(frameworkTypeElement, mapType.valueType()); + return key.withType(DaggerType.from(mapOf(mapType.keyType(), wrappedValueType))); } } - return Optional.empty(); - } - - /** - * If {@code key}'s type is {@code Map<K, Foo>} and {@code Foo} is not {@code WrappingClass - * <Bar>}, returns a key with type {@code Map<K, WrappingClass<Foo>>} with the same qualifier. - * Otherwise returns {@link Optional#empty()}. - * - * <p>Returns {@link Optional#empty()} if {@code WrappingClass} is not in the classpath. - */ - private Optional<Key> wrapMapKey(Key possibleMapKey, ClassName wrappingClassName) { - if (MapType.isMap(possibleMapKey)) { - MapType mapType = MapType.from(possibleMapKey); - if (!mapType.isRawType() && !mapType.valuesAreTypeOf(wrappingClassName)) { - XTypeElement wrappingElement = processingEnv.findTypeElement(wrappingClassName); - if (wrappingElement == null) { - // This target might not be compiled with Producers, so wrappingClass might not have an - // associated element. - return Optional.empty(); - } - XType wrappedValueType = - processingEnv.getDeclaredType(wrappingElement, mapType.valueType()); - return Optional.of( - possibleMapKey.withType(DaggerType.from(mapOf(mapType.keyType(), wrappedValueType)))); - } - } - return Optional.empty(); + return key; } /**
diff --git a/java/dagger/internal/codegen/binding/BindingGraphConverter.java b/java/dagger/internal/codegen/binding/LegacyBindingGraphConverter.java similarity index 70% rename from java/dagger/internal/codegen/binding/BindingGraphConverter.java rename to java/dagger/internal/codegen/binding/LegacyBindingGraphConverter.java index adb4435..fd86dd9 100644 --- a/java/dagger/internal/codegen/binding/BindingGraphConverter.java +++ b/java/dagger/internal/codegen/binding/LegacyBindingGraphConverter.java
@@ -23,16 +23,13 @@ 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.graph.ImmutableNetwork; import com.google.common.graph.MutableNetwork; 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.binding.LegacyBindingGraphFactory.LegacyBindingGraph; +import dagger.internal.codegen.binding.LegacyBindingGraphFactory.LegacyResolvedBindings; import dagger.internal.codegen.model.BindingGraph.ComponentNode; import dagger.internal.codegen.model.BindingGraph.DependencyEdge; import dagger.internal.codegen.model.BindingGraph.Edge; @@ -41,30 +38,23 @@ 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 java.util.ArrayDeque; import java.util.Deque; -import java.util.HashMap; import java.util.HashSet; -import java.util.Map; import java.util.Set; import javax.inject.Inject; /** Converts {@link BindingGraph}s to {@link dagger.internal.codegen.model.BindingGraph}s. */ -final class BindingGraphConverter { - private final BindingDeclarationFormatter bindingDeclarationFormatter; - +final class LegacyBindingGraphConverter { @Inject - BindingGraphConverter(BindingDeclarationFormatter bindingDeclarationFormatter) { - this.bindingDeclarationFormatter = bindingDeclarationFormatter; - } + LegacyBindingGraphConverter() {} /** * Creates the external {@link dagger.internal.codegen.model.BindingGraph} representing the given * internal {@link BindingGraph}. */ BindingGraph convert(LegacyBindingGraph legacyBindingGraph, boolean isFullBindingGraph) { - MutableNetwork<Node, Edge> network = asNetwork(legacyBindingGraph); + MutableNetwork<Node, Edge> network = Converter.convertToNetwork(legacyBindingGraph); ComponentNode rootNode = legacyBindingGraph.componentNode(); // When bindings are copied down into child graphs because they transitively depend on local @@ -76,18 +66,18 @@ unreachableNodes(network.asGraph(), rootNode).forEach(network::removeNode); } - TopLevelBindingGraph topLevelBindingGraph = - TopLevelBindingGraph.create(ImmutableNetwork.copyOf(network), isFullBindingGraph); - return BindingGraph.create(rootNode, topLevelBindingGraph); + return BindingGraph.create( + ImmutableNetwork.copyOf(network), + isFullBindingGraph); } - private MutableNetwork<Node, Edge> asNetwork(LegacyBindingGraph graph) { - Converter converter = new Converter(); - converter.visitRootComponent(graph); - return converter.network; - } + private static final class Converter { + static MutableNetwork<Node, Edge> convertToNetwork(LegacyBindingGraph graph) { + Converter converter = new Converter(); + converter.visitRootComponent(graph); + return converter.network; + } - private final class Converter { /** The path from the root graph to the currently visited graph. */ private final Deque<LegacyBindingGraph> bindingGraphPath = new ArrayDeque<>(); @@ -95,9 +85,6 @@ NetworkBuilder.directed().allowsParallelEdges(true).allowsSelfLoops(true).build(); private final Set<BindingNode> bindings = new HashSet<>(); - private final Map<ResolvedBindings, ImmutableSet<BindingNode>> resolvedBindingsMap = - new HashMap<>(); - private void visitRootComponent(LegacyBindingGraph graph) { visitComponent(graph); } @@ -127,8 +114,8 @@ addDependencyEdges(graph.componentNode(), entryPointMethod.dependencyRequest().get()); } - for (ResolvedBindings resolvedBindings : graph.resolvedBindings()) { - for (BindingNode binding : bindingNodes(resolvedBindings)) { + for (LegacyResolvedBindings resolvedBindings : graph.resolvedBindings()) { + for (BindingNode binding : resolvedBindings.bindingNodes()) { if (bindings.add(binding)) { network.addNode(binding); for (DependencyRequest dependencyRequest : binding.dependencies()) { @@ -140,8 +127,7 @@ network.addEdge( binding, subcomponentNode(binding.key().type().xprocessing(), graph), - new SubcomponentCreatorBindingEdgeImpl( - resolvedBindings.subcomponentDeclarations())); + new SubcomponentCreatorBindingEdgeImpl(binding.subcomponentDeclarations())); } } } @@ -171,21 +157,6 @@ } /** - * Returns the subpath from the root component to the matching {@code ancestor} of the current - * component. - */ - private ComponentPath pathFromRootToAncestor(XTypeElement ancestor) { - for (LegacyBindingGraph graph : bindingGraphPath) { - if (graph.componentDescriptor().typeElement().equals(ancestor)) { - return graph.componentPath(); - } - } - throw new IllegalArgumentException( - String.format( - "%s is not in the current path: %s", ancestor.getQualifiedName(), componentPath())); - } - - /** * Returns the LegacyBindingGraph for {@code ancestor}, where {@code ancestor} is in the * component path of the current traversal. */ @@ -205,11 +176,11 @@ * binding(s) that satisfy a dependency request. */ private void addDependencyEdges(Node source, DependencyRequest dependencyRequest) { - ResolvedBindings dependencies = resolvedDependencies(source, dependencyRequest); + LegacyResolvedBindings dependencies = resolvedDependencies(source, dependencyRequest); if (dependencies.isEmpty()) { addDependencyEdge(source, dependencyRequest, missingBindingNode(dependencies)); } else { - for (BindingNode dependency : bindingNodes(dependencies)) { + for (BindingNode dependency : dependencies.bindingNodes()) { addDependencyEdge(source, dependencyRequest, dependency); } } @@ -243,42 +214,13 @@ return false; } - private ResolvedBindings resolvedDependencies( + private LegacyResolvedBindings resolvedDependencies( Node source, DependencyRequest dependencyRequest) { return graphForAncestor(source.componentPath().currentComponent().xprocessing()) .resolvedBindings(bindingRequest(dependencyRequest)); } - private ImmutableSet<BindingNode> bindingNodes(ResolvedBindings resolvedBindings) { - return resolvedBindingsMap.computeIfAbsent(resolvedBindings, this::uncachedBindingNodes); - } - - private ImmutableSet<BindingNode> uncachedBindingNodes(ResolvedBindings resolvedBindings) { - ImmutableSet.Builder<BindingNode> bindingNodes = ImmutableSet.builder(); - resolvedBindings - .allBindings() - .asMap() - .forEach( - (component, bindings) -> { - for (Binding binding : bindings) { - bindingNodes.add(bindingNode(resolvedBindings, binding, component)); - } - }); - return bindingNodes.build(); - } - - private BindingNode bindingNode( - ResolvedBindings resolvedBindings, Binding binding, XTypeElement owningComponent) { - return BindingNode.create( - pathFromRootToAncestor(owningComponent), - binding, - resolvedBindings.multibindingDeclarations(), - resolvedBindings.optionalBindingDeclarations(), - resolvedBindings.subcomponentDeclarations(), - bindingDeclarationFormatter); - } - - private MissingBinding missingBindingNode(ResolvedBindings dependencies) { + private MissingBinding missingBindingNode(LegacyResolvedBindings dependencies) { // Put all missing binding nodes in the root component. This simplifies the binding graph // and produces better error messages for users since all dependents point to the same node. return MissingBindingImpl.create( @@ -296,18 +238,4 @@ subcomponent); } } - - @AutoValue - abstract static class MissingBindingImpl extends MissingBinding { - static MissingBinding create(ComponentPath component, Key key) { - return new AutoValue_BindingGraphConverter_MissingBindingImpl(component, key); - } - - @Memoized - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object o); - } }
diff --git a/java/dagger/internal/codegen/binding/LegacyBindingGraphFactory.java b/java/dagger/internal/codegen/binding/LegacyBindingGraphFactory.java new file mode 100644 index 0000000..4e95c2e --- /dev/null +++ b/java/dagger/internal/codegen/binding/LegacyBindingGraphFactory.java
@@ -0,0 +1,892 @@ +/* + * 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 com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; +import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedFactoryType; +import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; +import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION; +import static dagger.internal.codegen.model.BindingKind.DELEGATE; +import static dagger.internal.codegen.model.BindingKind.INJECTION; +import static dagger.internal.codegen.model.BindingKind.OPTIONAL; +import static dagger.internal.codegen.model.BindingKind.SUBCOMPONENT_CREATOR; +import static dagger.internal.codegen.model.RequestKind.MEMBERS_INJECTION; +import static dagger.internal.codegen.xprocessing.XTypes.isDeclared; +import static dagger.internal.codegen.xprocessing.XTypes.isTypeOf; +import static java.util.function.Predicate.isEqual; + +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 dagger.Reusable; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.base.Keys; +import dagger.internal.codegen.base.MapType; +import dagger.internal.codegen.base.SetType; +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 java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Queue; +import java.util.Set; +import javax.inject.Inject; + +/** A factory for {@link BindingGraph} objects. */ +public final class LegacyBindingGraphFactory { + + static boolean useLegacyBindingGraphFactory( + CompilerOptions compilerOptions, ComponentDescriptor componentDescriptor) { + return !compilerOptions.useBindingGraphFix(); + } + + static boolean hasStrictMultibindingsExemption( + CompilerOptions compilerOptions, ContributionBinding binding) { + // We only give the exemption to multibound map contributions. + if (!binding.contributionType().equals(ContributionType.MAP)) { + return false; + } + return !compilerOptions.strictMultibindingValidation(); + } + + private final InjectBindingRegistry injectBindingRegistry; + private final KeyFactory keyFactory; + private final BindingFactory bindingFactory; + private final BindingNode.Factory bindingNodeFactory; + private final ComponentDeclarations.Factory componentDeclarationsFactory; + private final LegacyBindingGraphConverter legacyBindingGraphConverter; + private final CompilerOptions compilerOptions; + + @Inject + LegacyBindingGraphFactory( + InjectBindingRegistry injectBindingRegistry, + KeyFactory keyFactory, + BindingFactory bindingFactory, + BindingNode.Factory bindingNodeFactory, + ComponentDeclarations.Factory componentDeclarationsFactory, + LegacyBindingGraphConverter legacyBindingGraphConverter, + CompilerOptions compilerOptions) { + this.injectBindingRegistry = injectBindingRegistry; + this.keyFactory = keyFactory; + this.bindingFactory = bindingFactory; + this.bindingNodeFactory = bindingNodeFactory; + this.componentDeclarationsFactory = componentDeclarationsFactory; + this.legacyBindingGraphConverter = legacyBindingGraphConverter; + this.compilerOptions = compilerOptions; + } + + /** + * Creates a binding graph for a component. + * + * @param createFullBindingGraph if {@code true}, the binding graph will include all bindings; + * otherwise it will include only bindings reachable from at least one entry point + */ + public BindingGraph create( + ComponentDescriptor componentDescriptor, boolean createFullBindingGraph) { + return legacyBindingGraphConverter.convert( + createLegacyBindingGraph(Optional.empty(), componentDescriptor, createFullBindingGraph), + createFullBindingGraph); + } + + private LegacyBindingGraph createLegacyBindingGraph( + Optional<Resolver> parentResolver, + ComponentDescriptor componentDescriptor, + boolean createFullBindingGraph) { + Resolver requestResolver = new Resolver(parentResolver, componentDescriptor); + + componentDescriptor.entryPointMethods().stream() + .map(method -> method.dependencyRequest().get()) + .forEach( + entryPoint -> { + if (entryPoint.kind().equals(MEMBERS_INJECTION)) { + requestResolver.resolveMembersInjection(entryPoint.key()); + } else { + requestResolver.resolve(entryPoint.key()); + } + }); + + if (createFullBindingGraph) { + // Resolve the keys for all bindings in all modules, stripping any multibinding contribution + // identifier so that the multibinding itself is resolved. + requestResolver.declarations.allDeclarations().stream() + // TODO(b/349155899): Consider resolving all declarations in full binding graph mode, not + // just those from modules. + .filter(declaration -> declaration.contributingModule().isPresent()) + .map(Declaration::key) + .map(Key::withoutMultibindingContributionIdentifier) + .forEach(requestResolver::resolve); + } + + // Resolve all bindings for subcomponents, creating subgraphs for all subcomponents that have + // been detected during binding resolution. If a binding for a subcomponent is never resolved, + // no BindingGraph will be created for it and no implementation will be generated. This is + // done in a queue since resolving one subcomponent might resolve a key for a subcomponent + // from a parent graph. This is done until no more new subcomponents are resolved. + Set<ComponentDescriptor> resolvedSubcomponents = new HashSet<>(); + ImmutableList.Builder<LegacyBindingGraph> subgraphs = ImmutableList.builder(); + for (ComponentDescriptor subcomponent : + Iterables.consumingIterable(requestResolver.subcomponentsToResolve)) { + if (resolvedSubcomponents.add(subcomponent)) { + subgraphs.add( + createLegacyBindingGraph( + Optional.of(requestResolver), subcomponent, createFullBindingGraph)); + } + } + + return new LegacyBindingGraph(requestResolver, subgraphs.build()); + } + + /** 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. */ + public ComponentNode componentNode() { + return componentNode; + } + + /** Returns the {@link ComponentPath} associated with this binding graph. */ + public ComponentPath componentPath() { + return resolver.componentPath; + } + + /** Returns the {@link ComponentDescriptor} associated with this binding graph. */ + public ComponentDescriptor componentDescriptor() { + return resolver.componentDescriptor; + } + + /** + * Returns the {@link LegacyResolvedBindings} 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. + */ + public LegacyResolvedBindings resolvedBindings(BindingRequest request) { + return request.isRequestKind(RequestKind.MEMBERS_INJECTION) + ? resolver.getResolvedMembersInjectionBindings(request.key()) + : resolver.getResolvedContributionBindings(request.key()); + } + + /** + * Returns all {@link LegacyResolvedBindings} for the given request. + * + * <p>Note that this only returns the bindings resolved in this component. Bindings resolved in + * parent components are not included. + */ + public Iterable<LegacyResolvedBindings> 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. */ + public ImmutableList<LegacyBindingGraph> subgraphs() { + return resolvedSubgraphs; + } + } + + /** + * The collection of bindings that have been resolved for a key. For valid graphs, contains + * exactly one binding. + * + * <p>Separate {@link LegacyResolvedBindings} instances should be used if a {@link + * MembersInjectionBinding} and a {@link ProvisionBinding} for the same key exist in the same + * component. (This will only happen if a type has an {@code @Inject} constructor and members, the + * component has a members injection method, and the type is also requested normally.) + */ + @AutoValue + abstract static class LegacyResolvedBindings { + /** + * Creates a {@link LegacyResolvedBindings} appropriate for when there are no bindings for a + * key. + */ + static LegacyResolvedBindings create(Key key) { + return create(key, ImmutableSet.of()); + } + + /** Creates a {@link LegacyResolvedBindings} for a single binding. */ + static LegacyResolvedBindings create(Key key, BindingNode bindingNode) { + return create(key, ImmutableSet.of(bindingNode)); + } + + /** Creates a {@link LegacyResolvedBindings} for multiple bindings. */ + static LegacyResolvedBindings create(Key key, ImmutableSet<BindingNode> bindingNodes) { + return new AutoValue_LegacyBindingGraphFactory_LegacyResolvedBindings(key, bindingNodes); + } + + /** The binding key for which the {@link #bindings()} have been resolved. */ + abstract Key key(); + + /** All binding nodes for {@link #key()}, regardless of which component owns them. */ + abstract ImmutableSet<BindingNode> bindingNodes(); + + // Computing the hash code is an expensive operation. + @Memoized + @Override + public abstract int hashCode(); + + // Suppresses ErrorProne warning that hashCode was overridden w/o equals + @Override + public abstract boolean equals(Object other); + + /** All bindings for {@link #key()}, regardless of which component owns them. */ + final ImmutableSet<Binding> bindings() { + return bindingNodes().stream() + .map(BindingNode::delegate) + .collect(toImmutableSet()); + } + + /** Returns {@code true} if there are no {@link #bindings()}. */ + final boolean isEmpty() { + return bindingNodes().isEmpty(); + } + + /** All bindings for {@link #key()} that are owned by a component. */ + ImmutableSet<BindingNode> bindingNodesOwnedBy(ComponentPath componentPath) { + return bindingNodes().stream() + .filter(bindingNode -> bindingNode.componentPath().equals(componentPath)) + .collect(toImmutableSet()); + } + + /** Returns the binding node representing the given binding, or throws ISE if none exist. */ + final BindingNode forBinding(Binding binding) { + return bindingNodes().stream() + .filter(bindingNode -> bindingNode.delegate().equals(binding)) + .collect(onlyElement()); + } + } + + private final class Resolver { + final ComponentPath componentPath; + final Optional<Resolver> parentResolver; + final ComponentDescriptor componentDescriptor; + final ComponentDeclarations declarations; + final Map<Key, LegacyResolvedBindings> resolvedContributionBindings = new LinkedHashMap<>(); + final Map<Key, LegacyResolvedBindings> resolvedMembersInjectionBindings = new LinkedHashMap<>(); + final Deque<Key> cycleStack = new ArrayDeque<>(); + final Map<Key, Boolean> keyDependsOnLocalBindingsCache = new HashMap<>(); + final Map<Binding, Boolean> bindingDependsOnLocalBindingsCache = new HashMap<>(); + final Queue<ComponentDescriptor> subcomponentsToResolve = new ArrayDeque<>(); + + Resolver(Optional<Resolver> parentResolver, ComponentDescriptor componentDescriptor) { + this.parentResolver = parentResolver; + this.componentDescriptor = checkNotNull(componentDescriptor); + DaggerTypeElement componentType = DaggerTypeElement.from(componentDescriptor.typeElement()); + componentPath = + parentResolver.isPresent() + ? parentResolver.get().componentPath.childPath(componentType) + : ComponentPath.create(ImmutableList.of(componentType)); + declarations = + componentDeclarationsFactory.create( + parentResolver.map(parent -> parent.componentDescriptor), + componentDescriptor); + subcomponentsToResolve.addAll( + componentDescriptor.childComponentsDeclaredByFactoryMethods().values()); + subcomponentsToResolve.addAll( + componentDescriptor.childComponentsDeclaredByBuilderEntryPoints().values()); + } + + /** + * Returns the resolved contribution bindings for the given {@link Key}: + * + * <ul> + * <li>All explicit bindings for: + * <ul> + * <li>the requested key + * <li>{@code Set<T>} if the requested key's type is {@code Set<Produced<T>>} + * <li>{@code Map<K, Provider<V>>} if the requested key's type is {@code Map<K, + * Producer<V>>}. + * </ul> + * <li>An implicit {@link Inject @Inject}-annotated constructor binding if there is one and + * there are no explicit bindings or synthetic bindings. + * </ul> + */ + LegacyResolvedBindings lookUpBindings(Key requestKey) { + Set<ContributionBinding> bindings = new LinkedHashSet<>(); + Set<ContributionBinding> multibindingContributions = new LinkedHashSet<>(); + Set<MultibindingDeclaration> multibindingDeclarations = new LinkedHashSet<>(); + Set<OptionalBindingDeclaration> optionalBindingDeclarations = new LinkedHashSet<>(); + Set<SubcomponentDeclaration> subcomponentDeclarations = new LinkedHashSet<>(); + + // Gather all bindings, multibindings, optional, and subcomponent declarations/contributions. + for (Resolver resolver : getResolverLineage()) { + bindings.addAll(resolver.getLocalExplicitBindings(requestKey)); + multibindingContributions.addAll(resolver.getLocalMultibindingContributions(requestKey)); + multibindingDeclarations.addAll(resolver.declarations.multibindings(requestKey)); + subcomponentDeclarations.addAll(resolver.declarations.subcomponents(requestKey)); + // The optional binding declarations are keyed by the unwrapped type. + keyFactory.unwrapOptional(requestKey) + .map(resolver.declarations::optionalBindings) + .ifPresent(optionalBindingDeclarations::addAll); + } + + // Add synthetic multibinding + if (!multibindingContributions.isEmpty() || !multibindingDeclarations.isEmpty()) { + if (MapType.isMap(requestKey)) { + bindings.add(bindingFactory.multiboundMap(requestKey, multibindingContributions)); + } else if (SetType.isSet(requestKey)) { + bindings.add(bindingFactory.multiboundSet(requestKey, multibindingContributions)); + } else { + throw new AssertionError("Unexpected type in multibinding key: " + requestKey); + } + } + + // Add synthetic optional binding + if (!optionalBindingDeclarations.isEmpty()) { + ImmutableSet<Binding> optionalContributions = + lookUpBindings(keyFactory.unwrapOptional(requestKey).get()).bindings(); + bindings.add( + optionalContributions.isEmpty() + ? bindingFactory.syntheticAbsentOptionalDeclaration(requestKey) + : bindingFactory.syntheticPresentOptionalDeclaration( + requestKey, optionalContributions)); + } + + // Add subcomponent creator binding + if (!subcomponentDeclarations.isEmpty()) { + ContributionBinding binding = + bindingFactory.subcomponentCreatorBinding( + ImmutableSet.copyOf(subcomponentDeclarations)); + bindings.add(binding); + addSubcomponentToOwningResolver(binding); + } + + // Add members injector binding + if (isTypeOf(requestKey.type().xprocessing(), TypeNames.MEMBERS_INJECTOR)) { + injectBindingRegistry.getOrFindMembersInjectorBinding(requestKey).ifPresent(bindings::add); + } + + // Add Assisted Factory binding + if (isDeclared(requestKey.type().xprocessing()) + && isAssistedFactoryType(requestKey.type().xprocessing().getTypeElement())) { + bindings.add( + bindingFactory.assistedFactoryBinding( + requestKey.type().xprocessing().getTypeElement(), + Optional.of(requestKey.type().xprocessing()))); + } + + // If there are no bindings, add the implicit @Inject-constructed binding if there is one. + if (bindings.isEmpty()) { + injectBindingRegistry + .getOrFindInjectionBinding(requestKey) + .filter(this::isCorrectlyScopedInSubcomponent) + .ifPresent(bindings::add); + } + + return LegacyResolvedBindings.create( + requestKey, + bindings.stream() + .map( + binding -> { + Optional<BindingNode> bindingNodeOwnedByAncestor = + getBindingNodeOwnedByAncestor(requestKey, binding); + // If a binding is owned by an ancestor we use the corresponding BindingNode + // instance directly rather than creating a new instance to avoid accidentally + // including additional multi/optional/subcomponent declarations that don't + // exist in the ancestor's BindingNode instance. + return bindingNodeOwnedByAncestor.isPresent() + ? bindingNodeOwnedByAncestor.get() + : bindingNodeFactory.forContributionBindings( + componentPath, + binding, + multibindingDeclarations, + optionalBindingDeclarations, + subcomponentDeclarations); + }) + .collect(toImmutableSet())); + } + + /** + * Returns true if this binding graph resolution is for a subcomponent and the {@code @Inject} + * binding's scope correctly matches one of the components in the current component ancestry. + * If not, it means the binding is not owned by any of the currently known components, and will + * be owned by a future ancestor (or, if never owned, will result in an incompatibly scoped + * binding error at the root component). + */ + private boolean isCorrectlyScopedInSubcomponent(ContributionBinding binding) { + checkArgument(binding.kind() == INJECTION || binding.kind() == ASSISTED_INJECTION); + if (!rootComponent().isSubcomponent() + || !binding.scope().isPresent() + || binding.scope().get().isReusable()) { + return true; + } + + Resolver owningResolver = getOwningResolver(binding).orElse(this); + ComponentDescriptor owningComponent = owningResolver.componentDescriptor; + return owningComponent.scopes().contains(binding.scope().get()); + } + + private ComponentDescriptor rootComponent() { + return parentResolver.map(Resolver::rootComponent).orElse(componentDescriptor); + } + + /** Returns the resolved members injection bindings for the given {@link Key}. */ + LegacyResolvedBindings lookUpMembersInjectionBinding(Key requestKey) { + // no explicit deps for members injection, so just look it up + Optional<MembersInjectionBinding> binding = + injectBindingRegistry.getOrFindMembersInjectionBinding(requestKey); + return binding.isPresent() + ? LegacyResolvedBindings.create( + requestKey, + bindingNodeFactory.forMembersInjectionBinding(componentPath, binding.get())) + : LegacyResolvedBindings.create(requestKey); + } + + /** + * When a binding is resolved for a {@link SubcomponentDeclaration}, adds corresponding {@link + * ComponentDescriptor subcomponent} to a queue in the owning component's resolver. The queue + * will be used to detect which subcomponents need to be resolved. + */ + private void addSubcomponentToOwningResolver(ContributionBinding subcomponentCreatorBinding) { + checkArgument(subcomponentCreatorBinding.kind().equals(SUBCOMPONENT_CREATOR)); + Resolver owningResolver = getOwningResolver(subcomponentCreatorBinding).get(); + + XTypeElement builderType = + subcomponentCreatorBinding.key().type().xprocessing().getTypeElement(); + owningResolver.subcomponentsToResolve.add( + owningResolver.componentDescriptor.getChildComponentWithBuilderType(builderType)); + } + + private ImmutableSet<ContributionBinding> createDelegateBindings( + ImmutableSet<DelegateDeclaration> delegateDeclarations) { + ImmutableSet.Builder<ContributionBinding> builder = ImmutableSet.builder(); + for (DelegateDeclaration delegateDeclaration : delegateDeclarations) { + builder.add(createDelegateBinding(delegateDeclaration)); + } + return builder.build(); + } + + /** + * Creates one (and only one) delegate binding for a delegate declaration, based on the resolved + * bindings of the right-hand-side of a {@link dagger.Binds} method. If there are duplicate + * bindings for the dependency key, there should still be only one binding for the delegate key. + */ + private ContributionBinding createDelegateBinding(DelegateDeclaration delegateDeclaration) { + Key delegateKey = delegateDeclaration.delegateRequest().key(); + if (cycleStack.contains(delegateKey)) { + return bindingFactory.unresolvedDelegateBinding(delegateDeclaration); + } + + LegacyResolvedBindings resolvedDelegate; + try { + cycleStack.push(delegateKey); + resolvedDelegate = lookUpBindings(delegateKey); + } finally { + cycleStack.pop(); + } + if (resolvedDelegate.bindings().isEmpty()) { + // This is guaranteed to result in a missing binding error, so it doesn't matter if the + // binding is a Provision or Production, except if it is a @IntoMap method, in which + // case the key will be of type Map<K, Provider<V>>, which will be "upgraded" into a + // Map<K, Producer<V>> if it's requested in a ProductionComponent. This may result in a + // strange error, that the RHS needs to be provided with an @Inject or @Provides + // annotated method, but a user should be able to figure out if a @Produces annotation + // is needed. + // TODO(gak): revisit how we model missing delegates if/when we clean up how we model + // binding declarations + return bindingFactory.unresolvedDelegateBinding(delegateDeclaration); + } + // It doesn't matter which of these is selected, since they will later on produce a + // duplicate binding error. + ContributionBinding explicitDelegate = + (ContributionBinding) resolvedDelegate.bindings().iterator().next(); + return bindingFactory.delegateBinding(delegateDeclaration, explicitDelegate); + } + + /** + * Returns a {@link BindingNode} for the given binding that is owned by an ancestor component, + * if one exists. Otherwise returns {@link Optional#empty()}. + */ + private Optional<BindingNode> getBindingNodeOwnedByAncestor( + Key requestKey, ContributionBinding binding) { + if (canBeResolvedInParent(requestKey, binding)) { + // Resolve in the parent to make sure we have the most recent multi/optional contributions. + parentResolver.get().resolve(requestKey); + if (!requiresResolution(binding)) { + return Optional.of(getPreviouslyResolvedBindings(requestKey).get().forBinding(binding)); + } + } + return Optional.empty(); + } + + private boolean canBeResolvedInParent(Key requestKey, ContributionBinding binding) { + if (parentResolver.isEmpty()) { + return false; + } + Optional<Resolver> owningResolver = getOwningResolver(binding); + if (owningResolver.isPresent()) { + return !owningResolver.get().equals(this); + } + return !Keys.isComponentOrCreator(requestKey) + // TODO(b/305748522): Allow caching for assisted injection bindings. + && binding.kind() != BindingKind.ASSISTED_INJECTION + && getPreviouslyResolvedBindings(requestKey).isPresent() + && getPreviouslyResolvedBindings(requestKey).get().bindings().contains(binding); + } + + private Optional<Resolver> getOwningResolver(ContributionBinding binding) { + // TODO(ronshapiro): extract the different pieces of this method into their own methods + if ((binding.scope().isPresent() && binding.scope().get().isProductionScope()) + || binding.kind().equals(BindingKind.PRODUCTION)) { + for (Resolver requestResolver : getResolverLineage()) { + // Resolve @Inject @ProductionScope bindings at the highest production component. + if (binding.kind().equals(INJECTION) + && requestResolver.componentDescriptor.isProduction()) { + return Optional.of(requestResolver); + } + + // Resolve explicit @Produces and @ProductionScope bindings at the highest component that + // installs the binding. + if (requestResolver.containsExplicitBinding(binding)) { + return Optional.of(requestResolver); + } + } + } + + if (binding.scope().isPresent() && binding.scope().get().isReusable()) { + for (Resolver requestResolver : getResolverLineage().reverse()) { + // If a @Reusable binding was resolved in an ancestor, use that component. + LegacyResolvedBindings resolvedBindings = + requestResolver.resolvedContributionBindings.get(binding.key()); + if (resolvedBindings != null && resolvedBindings.bindings().contains(binding)) { + return Optional.of(requestResolver); + } + } + // If a @Reusable binding was not resolved in any ancestor, resolve it here. + return Optional.empty(); + } + + // TODO(b/359893922): we currently iterate from child to parent to find an owning resolver, + // but we probably want to iterate from parent to child to catch missing bindings in + // misconfigured repeated modules. + for (Resolver requestResolver : getResolverLineage().reverse()) { + if (requestResolver.containsExplicitBinding(binding)) { + return Optional.of(requestResolver); + } + } + + // look for scope separately. we do this for the case where @Singleton can appear twice + // in the † compatibility mode + Optional<Scope> bindingScope = binding.scope(); + if (bindingScope.isPresent()) { + for (Resolver requestResolver : getResolverLineage().reverse()) { + if (requestResolver.componentDescriptor.scopes().contains(bindingScope.get())) { + return Optional.of(requestResolver); + } + } + } + return Optional.empty(); + } + + private boolean containsExplicitBinding(ContributionBinding binding) { + return declarations.bindings(binding.key()).contains(binding) + || resolverContainsDelegateDeclarationForBinding(binding) + || !declarations.subcomponents(binding.key()).isEmpty(); + } + + /** Returns true if {@code binding} was installed in a module in this resolver's component. */ + private boolean resolverContainsDelegateDeclarationForBinding(ContributionBinding binding) { + if (!binding.kind().equals(DELEGATE)) { + return false; + } + if (hasStrictMultibindingsExemption(compilerOptions, binding)) { + return false; + } + return declarations.delegates(binding.key()).stream() + .anyMatch( + declaration -> + declaration.contributingModule().equals(binding.contributingModule()) + && declaration.bindingElement().equals(binding.bindingElement())); + } + + /** Returns the resolver lineage from parent to child. */ + private ImmutableList<Resolver> getResolverLineage() { + ImmutableList.Builder<Resolver> resolverList = ImmutableList.builder(); + for (Optional<Resolver> currentResolver = Optional.of(this); + currentResolver.isPresent(); + currentResolver = currentResolver.get().parentResolver) { + resolverList.add(currentResolver.get()); + } + return resolverList.build().reverse(); + } + + /** + * Returns the explicit {@link ContributionBinding}s that match the {@code key} from this + * resolver. + */ + private ImmutableSet<ContributionBinding> getLocalExplicitBindings(Key key) { + return ImmutableSet.<ContributionBinding>builder() + .addAll(declarations.bindings(key)) + .addAll(createDelegateBindings(declarations.delegates(key))) + .build(); + } + + /** + * Returns the explicit multibinding contributions that contribute to the map or set requested + * by {@code key} from this resolver. + */ + private ImmutableSet<ContributionBinding> getLocalMultibindingContributions(Key key) { + return ImmutableSet.<ContributionBinding>builder() + .addAll(declarations.multibindingContributions(key)) + .addAll(createDelegateBindings(declarations.delegateMultibindingContributions(key))) + .build(); + } + + /** + * Returns the {@link OptionalBindingDeclaration}s that match the {@code key} from this and all + * ancestor resolvers. + */ + private ImmutableSet<OptionalBindingDeclaration> getOptionalBindingDeclarations(Key key) { + Optional<Key> unwrapped = keyFactory.unwrapOptional(key); + if (unwrapped.isEmpty()) { + return ImmutableSet.of(); + } + ImmutableSet.Builder<OptionalBindingDeclaration> declarations = ImmutableSet.builder(); + for (Resolver resolver : getResolverLineage()) { + declarations.addAll(resolver.declarations.optionalBindings(unwrapped.get())); + } + return declarations.build(); + } + + /** + * Returns the {@link LegacyResolvedBindings} for {@code key} that was resolved in this resolver + * or an ancestor resolver. Only checks for {@link ContributionBinding}s as {@link + * MembersInjectionBinding}s are not inherited. + */ + private Optional<LegacyResolvedBindings> getPreviouslyResolvedBindings(Key key) { + Optional<LegacyResolvedBindings> result = + Optional.ofNullable(resolvedContributionBindings.get(key)); + if (result.isPresent()) { + return result; + } else if (parentResolver.isPresent()) { + return parentResolver.get().getPreviouslyResolvedBindings(key); + } else { + return Optional.empty(); + } + } + + private void resolveMembersInjection(Key key) { + LegacyResolvedBindings bindings = lookUpMembersInjectionBinding(key); + resolveDependencies(bindings); + resolvedMembersInjectionBindings.put(key, bindings); + } + + void resolve(Key key) { + // If we find a cycle, stop resolving. The original request will add it with all of the + // other resolved deps. + if (cycleStack.contains(key)) { + return; + } + + // If the binding was previously resolved in this (sub)component, don't resolve it again. + if (resolvedContributionBindings.containsKey(key)) { + return; + } + + cycleStack.push(key); + try { + LegacyResolvedBindings bindings = lookUpBindings(key); + resolvedContributionBindings.put(key, bindings); + resolveDependencies(bindings); + } finally { + cycleStack.pop(); + } + } + + /** + * {@link #resolve(Key) Resolves} each of the dependencies of the bindings owned by this + * component. + */ + private void resolveDependencies(LegacyResolvedBindings resolvedBindings) { + for (BindingNode binding : resolvedBindings.bindingNodesOwnedBy(componentPath)) { + for (DependencyRequest dependency : binding.dependencies()) { + resolve(dependency.key()); + } + } + } + + private LegacyResolvedBindings 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); + } + + private LegacyResolvedBindings getResolvedMembersInjectionBindings(Key key) { + return resolvedMembersInjectionBindings.get(key); + } + + private boolean requiresResolution(Binding binding) { + return new RequiresResolutionChecker().requiresResolution(binding); + } + + private final class RequiresResolutionChecker { + private final Set<Object> cycleChecker = new HashSet<>(); + + /** + * Returns {@code true} if any of the bindings resolved for {@code key} are multibindings with + * contributions declared within this component's modules or optional bindings with present + * values declared within this component's modules, or if any of its unscoped dependencies + * depend on such bindings. + * + * <p>We don't care about scoped dependencies because they will never depend on bindings from + * subcomponents. + * + * @throws IllegalArgumentException if {@link #getPreviouslyResolvedBindings(Key)} is empty + */ + 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::requiresResolutionUncached); + } + + /** + * Returns {@code true} if {@code binding} is unscoped (or has {@link Reusable @Reusable} + * scope) and depends on multibindings with contributions declared within this component's + * modules, or if any of its unscoped or {@link Reusable @Reusable} scoped dependencies depend + * on such local multibindings. + * + * <p>We don't care about non-reusable scoped dependencies because they will never depend on + * multibindings with contributions from subcomponents. + */ + private boolean requiresResolution(Binding binding) { + if (!cycleChecker.add(binding)) { + return false; + } + return reentrantComputeIfAbsent( + bindingDependsOnLocalBindingsCache, binding, this::requiresResolutionUncached); + } + + private boolean requiresResolutionUncached(Key key) { + checkArgument( + getPreviouslyResolvedBindings(key).isPresent(), + "no previously resolved bindings in %s for %s", + Resolver.this, + key); + LegacyResolvedBindings previouslyResolvedBindings = + getPreviouslyResolvedBindings(key).get(); + if (hasLocalBindings(previouslyResolvedBindings)) { + return true; + } + + for (Binding binding : previouslyResolvedBindings.bindings()) { + if (requiresResolution(binding)) { + return true; + } + } + return false; + } + + private boolean requiresResolutionUncached(Binding binding) { + if ((!binding.scope().isPresent() || binding.scope().get().isReusable()) + // TODO(beder): Figure out what happens with production subcomponents. + && !binding.kind().equals(BindingKind.PRODUCTION)) { + for (DependencyRequest dependency : binding.dependencies()) { + if (requiresResolution(dependency.key())) { + return true; + } + } + } + return false; + } + } + + private boolean hasLocalBindings(LegacyResolvedBindings 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 !declarations.multibindingContributions(requestKey).isEmpty() + || !declarations.delegateMultibindingContributions(requestKey).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(LegacyResolvedBindings resolvedBindings) { + return hasLocalOptionalBindingContribution( + resolvedBindings.key(), resolvedBindings.bindings()); + } + + private boolean hasLocalOptionalBindingContribution( + Key key, ImmutableSet<? extends Binding> previouslyResolvedBindings) { + if (previouslyResolvedBindings.stream() + .map(Binding::kind) + .anyMatch(isEqual(OPTIONAL))) { + return hasLocalExplicitBindings(keyFactory.unwrapOptional(key).get()); + } 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(); + } + } + + /** + * Returns {@code true} if there is at least one explicit binding that matches the given key. + */ + private boolean hasLocalExplicitBindings(Key requestKey) { + return !declarations.bindings(requestKey).isEmpty() + || !declarations.delegates(requestKey).isEmpty(); + } + } +}
diff --git a/java/dagger/internal/codegen/binding/MapKeys.java b/java/dagger/internal/codegen/binding/MapKeys.java index 61ef9f2..a38bf8a 100644 --- a/java/dagger/internal/codegen/binding/MapKeys.java +++ b/java/dagger/internal/codegen/binding/MapKeys.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.binding; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static androidx.room.compiler.processing.XTypeKt.isArray; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.getOnlyElement; @@ -46,13 +47,14 @@ import dagger.internal.codegen.base.DaggerSuperficialValidation; import dagger.internal.codegen.base.MapKeyAccessibility; import dagger.internal.codegen.javapoet.TypeNames; -import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.xprocessing.XElements; import java.util.NoSuchElementException; import java.util.Optional; /** Methods for extracting {@link MapKey} annotations and key code blocks from binding elements. */ public final class MapKeys { + public static final String LAZY_CLASS_KEY_NAME_FIELD = "lazyClassKeyName"; + public static final String KEEP_FIELD_TYPE_FIELD = "keepFieldType"; /** * If {@code bindingElement} is annotated with a {@link MapKey} annotation, returns it. @@ -134,7 +136,7 @@ */ public static CodeBlock getMapKeyExpression( ContributionBinding binding, ClassName requestingClass, XProcessingEnv processingEnv) { - XAnnotation mapKeyAnnotation = binding.mapKey().get().xprocessing(); + XAnnotation mapKeyAnnotation = binding.mapKey().get(); return MapKeyAccessibility.isMapKeyAccessibleFrom( mapKeyAnnotation, requestingClass.packageName()) ? directMapKeyExpression(mapKeyAnnotation, processingEnv) @@ -176,7 +178,8 @@ * XProcessingEnv)} is generated. */ public static ClassName mapKeyProxyClassName(ContributionBinding binding) { - return elementBasedClassName(asExecutable(binding.bindingElement().get()), "MapKey"); + return toJavaPoet( + elementBasedClassName(asExecutable(binding.bindingElement().get()), "MapKey")); } /** @@ -188,7 +191,6 @@ ContributionBinding binding, XProcessingEnv processingEnv) { return binding .mapKey() - .map(DaggerAnnotation::xprocessing) .filter(mapKey -> !isMapKeyPubliclyAccessible(mapKey)) .map( mapKey -> @@ -213,12 +215,21 @@ && contributionBinding .mapKey() .get() - .xprocessing() .getClassName() .equals(TypeNames.LAZY_CLASS_KEY); } return false; } + public static CodeBlock getLazyClassMapKeyExpression(ContributionBinding contributionBinding) { + ClassName proxyClassName = + lazyClassKeyProxyClassName(XElements.asMethod(contributionBinding.bindingElement().get())); + return CodeBlock.of("$T.$N", proxyClassName, LAZY_CLASS_KEY_NAME_FIELD); + } + + public static ClassName lazyClassKeyProxyClassName(XMethodElement methodElement) { + return toJavaPoet(elementBasedClassName(methodElement, "_LazyMapKey")); + } + private MapKeys() {} }
diff --git a/java/dagger/internal/codegen/binding/MembersInjectionBinding.java b/java/dagger/internal/codegen/binding/MembersInjectionBinding.java index b546f6a..17580ee 100644 --- a/java/dagger/internal/codegen/binding/MembersInjectionBinding.java +++ b/java/dagger/internal/codegen/binding/MembersInjectionBinding.java
@@ -17,10 +17,11 @@ package dagger.internal.codegen.binding; import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static dagger.internal.codegen.xprocessing.XElements.isPrivate; -import static java.util.stream.Collectors.toList; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XFieldElement; @@ -33,19 +34,12 @@ import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.model.Scope; import java.util.Optional; -/** Represents the full members injection of a particular type. */ +/** A binding for a {@link BindingKind#MEMBERS_INJECTION}. */ @AutoValue public abstract class MembersInjectionBinding extends Binding { - static MembersInjectionBinding create( - Key key, - ImmutableSet<DependencyRequest> dependencies, - Optional<MembersInjectionBinding> unresolved, - ImmutableSortedSet<InjectionSite> injectionSites) { - return new AutoValue_MembersInjectionBinding(key, dependencies, unresolved, injectionSites); - } - @Override public final Optional<XElement> bindingElement() { return Optional.of(membersInjectedType()); @@ -56,9 +50,6 @@ } @Override - public abstract Optional<MembersInjectionBinding> unresolved(); - - @Override public Optional<XTypeElement> contributingModule() { return Optional.empty(); } @@ -67,8 +58,8 @@ public abstract ImmutableSortedSet<InjectionSite> injectionSites(); @Override - public BindingType bindingType() { - return BindingType.MEMBERS_INJECTION; + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.MEMBERS_INJECTION); } @Override @@ -81,6 +72,13 @@ return false; } + @Override + public final ImmutableSet<DependencyRequest> dependencies() { + return injectionSites().stream() + .flatMap(injectionSite -> injectionSite.dependencies().stream()) + .collect(toImmutableSet()); + } + /** * Returns {@code true} if any of this binding's injection sites are directly on the bound type. */ @@ -95,6 +93,11 @@ return false; } + @Override + public Optional<Scope> scope() { + return Optional.empty(); + } + @Memoized @Override public abstract int hashCode(); @@ -103,6 +106,22 @@ @Override public abstract boolean equals(Object obj); + static Builder builder() { + return new AutoValue_MembersInjectionBinding.Builder(); + } + + /** A {@link MembersInjectionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder { + abstract Builder key(Key key); + + abstract Builder unresolved(Optional<? extends Binding> unresolved); + + abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites); + + abstract MembersInjectionBinding build(); + } + /** Metadata about a field or method injection site. */ @AutoValue public abstract static class InjectionSite { @@ -131,7 +150,7 @@ .filter(InjectionAnnotations::hasInjectAnnotation) .filter(element -> !isPrivate(element)) .filter(element -> getSimpleName(element).equals(getSimpleName(this.element()))) - .collect(toList()) + .collect(toImmutableList()) .indexOf(element()); }
diff --git a/java/dagger/internal/codegen/binding/MembersInjectorBinding.java b/java/dagger/internal/codegen/binding/MembersInjectorBinding.java new file mode 100644 index 0000000..cd9a68d --- /dev/null +++ b/java/dagger/internal/codegen/binding/MembersInjectorBinding.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.internal.codegen.binding; + +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#MEMBERS_INJECTOR}. */ +@CheckReturnValue +@AutoValue +public abstract class MembersInjectorBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.MEMBERS_INJECTOR; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return injectionSites().stream() + .flatMap(i -> i.dependencies().stream()) + .collect(toImmutableSet()); + } + + /** {@link InjectionSite}s for all {@code @Inject} members. */ + public abstract ImmutableSortedSet<InjectionSite> injectionSites(); + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_MembersInjectorBinding.Builder(); + } + + /** A {@link MembersInjectorBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<MembersInjectorBinding, Builder> { + abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites); + } +}
diff --git a/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java b/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java index d7fea80..7738fe9 100644 --- a/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java +++ b/java/dagger/internal/codegen/binding/MethodSignatureFormatter.java
@@ -38,6 +38,7 @@ import com.google.common.collect.Streams; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.Formatter; +import dagger.internal.codegen.xprocessing.Nullability; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XTypes; import java.util.Iterator;
diff --git a/java/dagger/internal/codegen/binding/MissingBindingImpl.java b/java/dagger/internal/codegen/binding/MissingBindingImpl.java new file mode 100644 index 0000000..1d964e0 --- /dev/null +++ b/java/dagger/internal/codegen/binding/MissingBindingImpl.java
@@ -0,0 +1,38 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import dagger.internal.codegen.model.BindingGraph.MissingBinding; +import dagger.internal.codegen.model.ComponentPath; +import dagger.internal.codegen.model.Key; + +/** An implementation of {@link MissingBinding}. */ +@AutoValue +abstract class MissingBindingImpl extends MissingBinding { + static MissingBinding create(ComponentPath component, Key key) { + return new AutoValue_MissingBindingImpl(component, key); + } + + @Memoized + @Override + public abstract int hashCode(); + + @Override + public abstract boolean equals(Object o); +} \ No newline at end of file
diff --git a/java/dagger/internal/codegen/binding/ModuleDescriptor.java b/java/dagger/internal/codegen/binding/ModuleDescriptor.java index 62cfa7f..bde718f 100644 --- a/java/dagger/internal/codegen/binding/ModuleDescriptor.java +++ b/java/dagger/internal/codegen/binding/ModuleDescriptor.java
@@ -79,10 +79,13 @@ /** The kind of the module. */ public abstract ModuleKind kind(); + /** Whether the module is implicitly included rather than directly referenced in annotation. */ + public abstract boolean isImplicitlyIncluded(); + /** Returns all of the bindings declared in this module. */ @Memoized - public ImmutableSet<BindingDeclaration> allBindingDeclarations() { - return ImmutableSet.<BindingDeclaration>builder() + public ImmutableSet<Declaration> allBindingDeclarations() { + return ImmutableSet.<Declaration>builder() .addAll(bindings()) .addAll(delegateDeclarations()) .addAll(multibindingDeclarations()) @@ -93,7 +96,7 @@ /** Returns the keys of all bindings declared by this module. */ ImmutableSet<Key> allBindingKeys() { - return allBindingDeclarations().stream().map(BindingDeclaration::key).collect(toImmutableSet()); + return allBindingDeclarations().stream().map(Declaration::key).collect(toImmutableSet()); } /** A {@link ModuleDescriptor} factory. */ @@ -107,6 +110,7 @@ private final OptionalBindingDeclaration.Factory optionalBindingDeclarationFactory; private final DaggerSuperficialValidation superficialValidation; private final Map<XTypeElement, ModuleDescriptor> cache = new HashMap<>(); + private final Set<XTypeElement> implicitlyIncludedModules = new LinkedHashSet<>(); @Inject Factory( @@ -174,7 +178,8 @@ subcomponentDeclarationFactory.forModule(moduleElement), delegates.build(), optionalDeclarations.build(), - ModuleKind.forAnnotatedElement(moduleElement).get()); + ModuleKind.forAnnotatedElement(moduleElement).get(), + implicitlyIncludedModules.contains(moduleElement)); } private void collectCompanionModuleBindings( @@ -231,7 +236,10 @@ .ifPresent( moduleAnnotation -> { includedModules.addAll(moduleAnnotation.includes()); - includedModules.addAll(implicitlyIncludedModules(moduleElement)); + ImmutableSet<XTypeElement> daggerAndroidModules = + implicitlyIncludedModules(moduleElement); + includedModules.addAll(daggerAndroidModules); + implicitlyIncludedModules.addAll(daggerAndroidModules); }); return includedModules; } @@ -259,7 +267,7 @@ module.getPackageName(), String.format( "%s_%s", - classFileName(module.getClassName()), + classFileName(module.asClassName()), LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(method)))); }
diff --git a/java/dagger/internal/codegen/binding/MultibindingDeclaration.java b/java/dagger/internal/codegen/binding/MultibindingDeclaration.java index 54672fc..1cfded6 100644 --- a/java/dagger/internal/codegen/binding/MultibindingDeclaration.java +++ b/java/dagger/internal/codegen/binding/MultibindingDeclaration.java
@@ -42,7 +42,7 @@ * method annotated with {@link Multibinds @Multibinds}. */ @AutoValue -public abstract class MultibindingDeclaration extends BindingDeclaration +public abstract class MultibindingDeclaration extends Declaration implements HasContributionType { /**
diff --git a/java/dagger/internal/codegen/binding/MultiboundMapBinding.java b/java/dagger/internal/codegen/binding/MultiboundMapBinding.java new file mode 100644 index 0000000..0a8c971 --- /dev/null +++ b/java/dagger/internal/codegen/binding/MultiboundMapBinding.java
@@ -0,0 +1,71 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#MULTIBOUND_MAP}. */ +@CheckReturnValue +@AutoValue +public abstract class MultiboundMapBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.MULTIBOUND_MAP; + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_MultiboundMapBinding.Builder(); + } + + /** A {@link MultiboundMapBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<MultiboundMapBinding, Builder> { + abstract Builder dependencies(ImmutableSet<DependencyRequest> dependencies); + + abstract Builder optionalBindingType(Optional<BindingType> optionalBindingType); + } +}
diff --git a/java/dagger/internal/codegen/binding/MultiboundSetBinding.java b/java/dagger/internal/codegen/binding/MultiboundSetBinding.java new file mode 100644 index 0000000..607ade8 --- /dev/null +++ b/java/dagger/internal/codegen/binding/MultiboundSetBinding.java
@@ -0,0 +1,71 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#MULTIBOUND_SET}. */ +@CheckReturnValue +@AutoValue +public abstract class MultiboundSetBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.MULTIBOUND_SET; + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_MultiboundSetBinding.Builder(); + } + + /** A {@link MultiboundSetBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<MultiboundSetBinding, Builder> { + abstract Builder dependencies(ImmutableSet<DependencyRequest> dependencies); + + abstract Builder optionalBindingType(Optional<BindingType> optionalBindingType); + } +}
diff --git a/java/dagger/internal/codegen/binding/Nullability.java b/java/dagger/internal/codegen/binding/Nullability.java deleted file mode 100644 index 4231a8f..0000000 --- a/java/dagger/internal/codegen/binding/Nullability.java +++ /dev/null
@@ -1,106 +0,0 @@ -/* - * 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 androidx.room.compiler.processing.XElementKt.isMethod; -import static androidx.room.compiler.processing.XElementKt.isVariableElement; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.xprocessing.XElements.asMethod; -import static dagger.internal.codegen.xprocessing.XElements.asVariable; - -import androidx.room.compiler.processing.XAnnotation; -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 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. - * - * <p>Note that an element can be nullable if either: - * - * <ul> - * <li>The element is annotated with {@code Nullable} or - * <li>the associated kotlin type is nullable (i.e. {@code T?} types in Kotlin source). - * </ul> - */ -@AutoValue -public abstract class Nullability { - /** A constant that can represent any non-null element. */ - public static final Nullability NOT_NULLABLE = - new AutoValue_Nullability(false, ImmutableSet.of()); - - public static Nullability of(XElement element) { - 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 (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()); - } else { - return false; - } - } - - private static boolean isKotlinTypeNullable(XType type) { - return type.getNullability() == XNullability.NULLABLE; - } - - public abstract boolean isKotlinTypeNullable(); - - public abstract ImmutableSet<ClassName> nullableAnnotations(); - - public final boolean isNullable() { - return isKotlinTypeNullable() || !nullableAnnotations().isEmpty(); - } - - Nullability() {} -}
diff --git a/java/dagger/internal/codegen/binding/OptionalBinding.java b/java/dagger/internal/codegen/binding/OptionalBinding.java new file mode 100644 index 0000000..172db51 --- /dev/null +++ b/java/dagger/internal/codegen/binding/OptionalBinding.java
@@ -0,0 +1,86 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#OPTIONAL}. */ +@CheckReturnValue +@AutoValue +public abstract class OptionalBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.OPTIONAL; + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return delegateRequest().isPresent() + ? ImmutableSet.of(delegateRequest().get()) + : ImmutableSet.of(); + } + + /** Returns the delegate {@link DependencyRequest} if this represents a "present" optional. */ + abstract Optional<DependencyRequest> delegateRequest(); + + @Override + public boolean requiresModuleInstance() { + return false; + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_OptionalBinding.Builder(); + } + + /** A {@link OptionalBinding} builder. */ + @AutoValue.Builder + abstract static class Builder extends ContributionBinding.Builder<OptionalBinding, Builder> { + abstract Builder delegateRequest(DependencyRequest delegateRequest); + + abstract Builder optionalBindingType(Optional<BindingType> optionalBindingType); + } +}
diff --git a/java/dagger/internal/codegen/binding/OptionalBindingDeclaration.java b/java/dagger/internal/codegen/binding/OptionalBindingDeclaration.java index 60d56bb..ab183cc 100644 --- a/java/dagger/internal/codegen/binding/OptionalBindingDeclaration.java +++ b/java/dagger/internal/codegen/binding/OptionalBindingDeclaration.java
@@ -30,7 +30,7 @@ /** A {@link BindsOptionalOf} declaration. */ @AutoValue -abstract class OptionalBindingDeclaration extends BindingDeclaration { +abstract class OptionalBindingDeclaration extends Declaration { /** * {@inheritDoc}
diff --git a/java/dagger/internal/codegen/binding/ProductionBinding.java b/java/dagger/internal/codegen/binding/ProductionBinding.java index 0bcf8e7..574a864 100644 --- a/java/dagger/internal/codegen/binding/ProductionBinding.java +++ b/java/dagger/internal/codegen/binding/ProductionBinding.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 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. @@ -16,90 +16,56 @@ package dagger.internal.codegen.binding; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.javapoet.TypeNames.isFutureType; - -import androidx.room.compiler.processing.XMethodElement; -import androidx.room.compiler.processing.XType; 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.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CheckReturnValue; import dagger.internal.codegen.base.ContributionType; -import dagger.internal.codegen.base.SetType; +import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.DependencyRequest; -import dagger.internal.codegen.model.Key; +import dagger.internal.codegen.xprocessing.Nullability; import java.util.Optional; -import java.util.stream.Stream; -/** A value object representing the mechanism by which a {@link Key} can be produced. */ +/** A binding for a {@link BindingKind#PRODUCTION}. */ @CheckReturnValue @AutoValue public abstract class ProductionBinding extends ContributionBinding { - @Override - public BindingType bindingType() { - return BindingType.PRODUCTION; + public BindingKind kind() { + return BindingKind.PRODUCTION; } @Override - public abstract Optional<ProductionBinding> unresolved(); + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PRODUCTION); + } + @Override + @Memoized + public ContributionType contributionType() { + return ContributionType.fromBindingElement(bindingElement().get()); + } @Override - public ImmutableSet<DependencyRequest> implicitDependencies() { - return Stream.of(executorRequest(), monitorRequest()) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(toImmutableSet()); + public Nullability nullability() { + return Nullability.NOT_NULLABLE; } - /** What kind of object a {@code @Produces}-annotated method returns. */ - public enum ProductionKind { - /** A value. */ - IMMEDIATE, - /** A {@code ListenableFuture<T>}. */ - FUTURE, - /** A {@code Set<ListenableFuture<T>>}. */ - SET_OF_FUTURE; + /** Dependencies necessary to invoke the {@code @Produces} method. */ + public abstract ImmutableSet<DependencyRequest> explicitDependencies(); - /** Returns the kind of object a {@code @Produces}-annotated method returns. */ - public static ProductionKind fromProducesMethod(XMethodElement producesMethod) { - if (isFutureType(producesMethod.getReturnType())) { - return FUTURE; - } else if (ContributionType.fromBindingElement(producesMethod) - .equals(ContributionType.SET_VALUES) - && isFutureType(SetType.from(producesMethod.getReturnType()).elementType())) { - return SET_OF_FUTURE; - } else { - return IMMEDIATE; - } - } + @Override + @Memoized + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.<DependencyRequest>builder() + .add(executorRequest()) + .add(monitorRequest()) + .addAll(explicitDependencies()) + .build(); } - /** - * Returns the kind of object the produces method returns. All production bindings from - * {@code @Produces} methods will have a production kind, but synthetic production bindings may - * not. - */ - public abstract Optional<ProductionKind> productionKind(); + public abstract DependencyRequest executorRequest(); - /** Returns the list of types in the throws clause of the method. */ - public abstract ImmutableList<XType> thrownTypes(); - - /** - * If this production requires an executor, this will be the corresponding request. All - * production bindings from {@code @Produces} methods will have an executor request, but - * synthetic production bindings may not. - */ - abstract Optional<DependencyRequest> executorRequest(); - - /** If this production requires a monitor, this will be the corresponding request. All - * production bindings from {@code @Produces} methods will have a monitor request, but synthetic - * production bindings may not. - */ - abstract Optional<DependencyRequest> monitorRequest(); + public abstract DependencyRequest monitorRequest(); // Profiling determined that this method is called enough times that memoizing it had a measurable // performance improvement for large components. @@ -109,13 +75,6 @@ return super.requiresModuleInstance(); } - public static Builder builder() { - return new AutoValue_ProductionBinding.Builder() - .nullability(Nullability.NOT_NULLABLE) - .explicitDependencies(ImmutableList.<DependencyRequest>of()) - .thrownTypes(ImmutableList.<XType>of()); - } - @Override public abstract Builder toBuilder(); @@ -127,28 +86,17 @@ @Override public abstract boolean equals(Object obj); + static Builder builder() { + return new AutoValue_ProductionBinding.Builder(); + } + /** A {@link ProductionBinding} builder. */ @AutoValue.Builder - public abstract static class Builder - extends ContributionBinding.Builder<ProductionBinding, Builder> { - - @CanIgnoreReturnValue - @Override - public Builder dependencies(Iterable<DependencyRequest> dependencies) { - return explicitDependencies(dependencies); - } - - abstract Builder explicitDependencies(Iterable<DependencyRequest> dependencies); - - abstract Builder productionKind(ProductionKind productionKind); - - @Override - public abstract Builder unresolved(ProductionBinding unresolved); - - abstract Builder thrownTypes(Iterable<XType> thrownTypes); - + abstract static class Builder extends ContributionBinding.Builder<ProductionBinding, Builder> { abstract Builder executorRequest(DependencyRequest executorRequest); abstract Builder monitorRequest(DependencyRequest monitorRequest); + + abstract Builder explicitDependencies(Iterable<DependencyRequest> explicitDependencies); } }
diff --git a/java/dagger/internal/codegen/binding/ProvisionBinding.java b/java/dagger/internal/codegen/binding/ProvisionBinding.java index caf5904..7644155 100644 --- a/java/dagger/internal/codegen/binding/ProvisionBinding.java +++ b/java/dagger/internal/codegen/binding/ProvisionBinding.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 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. @@ -16,88 +16,33 @@ package dagger.internal.codegen.binding; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.model.BindingKind.COMPONENT_PROVISION; -import static dagger.internal.codegen.model.BindingKind.PROVISION; - import com.google.auto.value.AutoValue; import com.google.auto.value.extension.memoized.Memoized; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSortedSet; -import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CheckReturnValue; -import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; -import dagger.internal.codegen.compileroption.CompilerOptions; +import dagger.internal.codegen.base.ContributionType; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.DependencyRequest; -import dagger.internal.codegen.model.Key; -import dagger.internal.codegen.model.Scope; +import dagger.internal.codegen.xprocessing.Nullability; import java.util.Optional; -/** A value object representing the mechanism by which a {@link Key} can be provided. */ +/** A binding for a {@link BindingKind#PROVISION}. */ @CheckReturnValue @AutoValue public abstract class ProvisionBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.PROVISION; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } @Override @Memoized - public ImmutableSet<DependencyRequest> explicitDependencies() { - return ImmutableSet.<DependencyRequest>builder() - .addAll(provisionDependencies()) - .addAll(membersInjectionDependencies()) - .build(); - } - - /** - * Dependencies necessary to invoke an {@code @Inject} constructor or {@code @Provides} method. - */ - public abstract ImmutableSet<DependencyRequest> provisionDependencies(); - - @Memoized - ImmutableSet<DependencyRequest> membersInjectionDependencies() { - return injectionSites() - .stream() - .flatMap(i -> i.dependencies().stream()) - .collect(toImmutableSet()); - } - - /** - * {@link InjectionSite}s for all {@code @Inject} members if {@link #kind()} is {@link - * BindingKind#INJECTION}, otherwise empty. - */ - public abstract ImmutableSortedSet<InjectionSite> injectionSites(); - - @Override - public BindingType bindingType() { - return BindingType.PROVISION; - } - - @Override - public abstract Optional<ProvisionBinding> unresolved(); - - // TODO(ronshapiro): we should be able to remove this, but AutoValue barks on the Builder's scope - // method, saying that the method doesn't correspond to a property of ProvisionBinding - @Override - public abstract Optional<Scope> scope(); - - public static Builder builder() { - return new AutoValue_ProvisionBinding.Builder() - .nullability(Nullability.NOT_NULLABLE) - .provisionDependencies(ImmutableSet.of()) - .injectionSites(ImmutableSortedSet.of()); - } - - @Override - public abstract Builder toBuilder(); - - private static final ImmutableSet<BindingKind> KINDS_TO_CHECK_FOR_NULL = - ImmutableSet.of(PROVISION, COMPONENT_PROVISION); - - public boolean shouldCheckForNull(CompilerOptions compilerOptions) { - return KINDS_TO_CHECK_FOR_NULL.contains(kind()) - && !contributedPrimitiveType().isPresent() - && !isNullable() - && compilerOptions.doCheckForNulls(); + public ContributionType contributionType() { + return ContributionType.fromBindingElement(bindingElement().get()); } // Profiling determined that this method is called enough times that memoizing it had a measurable @@ -108,6 +53,9 @@ return super.requiresModuleInstance(); } + @Override + public abstract Builder toBuilder(); + @Memoized @Override public abstract int hashCode(); @@ -116,26 +64,15 @@ @Override public abstract boolean equals(Object obj); - /** A {@link ProvisionBinding} builder. */ - @AutoValue.Builder - public abstract static class Builder - extends ContributionBinding.Builder<ProvisionBinding, Builder> { - - @CanIgnoreReturnValue - @Override - public Builder dependencies(Iterable<DependencyRequest> dependencies) { - return provisionDependencies(dependencies); - } - - abstract Builder provisionDependencies(Iterable<DependencyRequest> provisionDependencies); - - public abstract Builder injectionSites(ImmutableSortedSet<InjectionSite> injectionSites); - - @CanIgnoreReturnValue // TODO(kak): remove this once open-source checkers understand AutoValue - @Override - public abstract Builder unresolved(ProvisionBinding unresolved); - - public abstract Builder scope(Optional<Scope> scope); + static Builder builder() { + return new AutoValue_ProvisionBinding.Builder(); } + /** A {@link ProvisionBinding} builder. */ + @AutoValue.Builder + abstract static class Builder extends ContributionBinding.Builder<ProvisionBinding, Builder> { + abstract Builder nullability(Nullability nullability); + + abstract Builder dependencies(Iterable<DependencyRequest> dependencies); + } }
diff --git a/java/dagger/internal/codegen/binding/ResolvedBindings.java b/java/dagger/internal/codegen/binding/ResolvedBindings.java index 406ae41..6ead759 100644 --- a/java/dagger/internal/codegen/binding/ResolvedBindings.java +++ b/java/dagger/internal/codegen/binding/ResolvedBindings.java
@@ -16,17 +16,12 @@ package dagger.internal.codegen.binding; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Iterables.getOnlyElement; +import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -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.ImmutableCollection; -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; @@ -41,32 +36,26 @@ */ @AutoValue abstract class ResolvedBindings { - /** The component path for the resolved bindings. */ - abstract ComponentPath componentPath(); + /** Creates a {@link ResolvedBindings} appropriate for when there are no bindings for a key. */ + static ResolvedBindings create(Key key) { + return create(key, ImmutableSet.of()); + } + + /** Creates a {@link ResolvedBindings} for a single binding. */ + static ResolvedBindings create(Key key, BindingNode bindingNode) { + return create(key, ImmutableSet.of(bindingNode)); + } + + /** Creates a {@link ResolvedBindings} for multiple bindings. */ + static ResolvedBindings create(Key key, ImmutableSet<BindingNode> bindingNodes) { + return new AutoValue_ResolvedBindings(key, bindingNodes); + } /** The binding key for which the {@link #bindings()} have been resolved. */ abstract Key key(); - /** - * The {@link ContributionBinding}s for {@link #key()} indexed by the component that owns the - * binding. Each key in the multimap is a part of the same component ancestry. - */ - abstract ImmutableSetMultimap<XTypeElement, ContributionBinding> allContributionBindings(); - - /** - * The {@link MembersInjectionBinding}s for {@link #key()} indexed by the component that owns the - * binding. Each key in the map is a part of the same component ancestry. - */ - abstract ImmutableMap<XTypeElement, MembersInjectionBinding> allMembersInjectionBindings(); - - /** The multibinding declarations for {@link #key()}. */ - abstract ImmutableSet<MultibindingDeclaration> multibindingDeclarations(); - - /** The subcomponent declarations for {@link #key()}. */ - abstract ImmutableSet<SubcomponentDeclaration> subcomponentDeclarations(); - - /** The optional binding declarations for {@link #key()}. */ - abstract ImmutableSet<OptionalBindingDeclaration> optionalBindingDeclarations(); + /** All binding nodes for {@link #key()}, regardless of which component owns them. */ + abstract ImmutableSet<BindingNode> bindingNodes(); // Computing the hash code is an expensive operation. @Memoized @@ -77,105 +66,29 @@ @Override public abstract boolean equals(Object other); - /** All bindings for {@link #key()}, indexed by the component that owns the binding. */ - final ImmutableSetMultimap<XTypeElement, ? extends Binding> allBindings() { - return !allMembersInjectionBindings().isEmpty() - ? allMembersInjectionBindings().asMultimap() - : allContributionBindings(); - } - /** All bindings for {@link #key()}, regardless of which component owns them. */ - final ImmutableCollection<? extends Binding> bindings() { - return allBindings().values(); + final ImmutableSet<Binding> bindings() { + return bindingNodes().stream() + .map(BindingNode::delegate) + .collect(toImmutableSet()); } - /** - * {@code true} if there are no {@link #bindings()}, {@link #multibindingDeclarations()}, {@link - * #optionalBindingDeclarations()}, or {@link #subcomponentDeclarations()}. - */ + /** Returns {@code true} if there are no {@link #bindings()}. */ final boolean isEmpty() { - return allMembersInjectionBindings().isEmpty() - && allContributionBindings().isEmpty() - && multibindingDeclarations().isEmpty() - && optionalBindingDeclarations().isEmpty() - && subcomponentDeclarations().isEmpty(); + return bindingNodes().isEmpty(); } /** All bindings for {@link #key()} that are owned by a component. */ - ImmutableSet<? extends Binding> bindingsOwnedBy(ComponentDescriptor component) { - return allBindings().get(component.typeElement()); + ImmutableSet<BindingNode> bindingNodesOwnedBy(ComponentPath componentPath) { + return bindingNodes().stream() + .filter(bindingNode -> bindingNode.componentPath().equals(componentPath)) + .collect(toImmutableSet()); } - /** - * All contribution bindings, regardless of owning component. Empty if this is a members-injection - * binding. - */ - @Memoized - ImmutableSet<ContributionBinding> contributionBindings() { - // TODO(ronshapiro): consider optimizing ImmutableSet.copyOf(Collection) for small immutable - // collections so that it doesn't need to call toArray(). Even though this method is memoized, - // toArray() can take ~150ms for large components, and there are surely other places in the - // processor that can benefit from this. - return ImmutableSet.copyOf(allContributionBindings().values()); - } - - /** The component that owns {@code binding}. */ - final XTypeElement owningComponent(ContributionBinding binding) { - checkArgument( - contributionBindings().contains(binding), - "binding is not resolved for %s: %s", - key(), - binding); - return getOnlyElement(allContributionBindings().inverse().get(binding)); - } - - /** 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(), - ImmutableSet.copyOf(multibindings), - ImmutableSet.copyOf(subcomponentDeclarations), - ImmutableSet.copyOf(optionalBindingDeclarations)); - } - - /** - * 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), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableSet.of()); - } - - /** - * Creates a {@link ResolvedBindings} appropriate for when there are no bindings for the key. - */ - static ResolvedBindings noBindings(ComponentPath componentPath, Key key) { - return new AutoValue_ResolvedBindings( - componentPath, - key, - ImmutableSetMultimap.of(), - ImmutableMap.of(), - ImmutableSet.of(), - ImmutableSet.of(), - ImmutableSet.of()); + /** Returns the binding node representing the given binding, or throws ISE if none exist. */ + final BindingNode forBinding(Binding binding) { + return bindingNodes().stream() + .filter(bindingNode -> bindingNode.delegate().equals(binding)) + .collect(onlyElement()); } }
diff --git a/java/dagger/internal/codegen/binding/SourceFiles.java b/java/dagger/internal/codegen/binding/SourceFiles.java index e8a1075..8319181 100644 --- a/java/dagger/internal/codegen/binding/SourceFiles.java +++ b/java/dagger/internal/codegen/binding/SourceFiles.java
@@ -16,36 +16,30 @@ package dagger.internal.codegen.binding; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static androidx.room.compiler.processing.XElementKt.isConstructor; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static dagger.internal.codegen.javapoet.TypeNames.DOUBLE_CHECK; -import static dagger.internal.codegen.javapoet.TypeNames.MAP_FACTORY; -import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCED_PRODUCER; -import static dagger.internal.codegen.javapoet.TypeNames.MAP_OF_PRODUCER_PRODUCER; -import static dagger.internal.codegen.javapoet.TypeNames.MAP_PRODUCER; -import static dagger.internal.codegen.javapoet.TypeNames.MAP_PROVIDER_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER; import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER; import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER_OF_LAZY; -import static dagger.internal.codegen.javapoet.TypeNames.SET_FACTORY; -import static dagger.internal.codegen.javapoet.TypeNames.SET_OF_PRODUCED_PRODUCER; -import static dagger.internal.codegen.javapoet.TypeNames.SET_PRODUCER; import static dagger.internal.codegen.model.BindingKind.ASSISTED_INJECTION; import static dagger.internal.codegen.model.BindingKind.INJECTION; -import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_MAP; -import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_SET; import static dagger.internal.codegen.xprocessing.XElements.asExecutable; +import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import static dagger.internal.codegen.xprocessing.XTypeElements.typeVariableNames; +import static dagger.internal.codegen.xprocessing.XTypeNames.simpleName; import static javax.lang.model.SourceVersion.isName; +import androidx.room.compiler.codegen.XClassName; import androidx.room.compiler.processing.XExecutableElement; import androidx.room.compiler.processing.XFieldElement; +import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XTypeElement; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -61,9 +55,11 @@ import com.squareup.javapoet.TypeVariableName; import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.base.SetType; +import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.RequestKind; +import dagger.internal.codegen.xprocessing.XTypeNames; import javax.inject.Inject; import javax.lang.model.SourceVersion; @@ -96,21 +92,12 @@ return Maps.toMap( binding.dependencies(), dependency -> { - ClassName frameworkClassName = + XClassName 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)); + DependencyVariableNamer.name(dependency), + frameworkClassName, + dependency.key().type().xprocessing()); }); } @@ -147,31 +134,39 @@ dep -> frameworkTypeUsageStatement(CodeBlock.of("$N", fields.get(dep)), dep.kind())); } + public static String generatedProxyMethodName(ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + case ASSISTED_INJECTION: + return "newInstance"; + case PROVISION: + XMethodElement method = asMethod(binding.bindingElement().get()); + String simpleName = getSimpleName(method); + // If the simple name is already defined in the factory, prepend "proxy" to the name. + return simpleName.contentEquals("get") || simpleName.contentEquals("create") + ? "proxy" + LOWER_CAMEL.to(UPPER_CAMEL, simpleName) + : simpleName; + default: + throw new AssertionError("Unexpected binding kind: " + binding); + } + } + /** Returns the generated factory or members injector name for a binding. */ - public static ClassName generatedClassNameForBinding(Binding binding) { - switch (binding.bindingType()) { + public static XClassName generatedClassNameForBinding(Binding binding) { + switch (binding.kind()) { + case ASSISTED_INJECTION: + case INJECTION: case PROVISION: case PRODUCTION: - ContributionBinding contribution = (ContributionBinding) binding; - switch (contribution.kind()) { - case ASSISTED_INJECTION: - case INJECTION: - case PROVISION: - case PRODUCTION: - return factoryNameForElement(asExecutable(binding.bindingElement().get())); - - case ASSISTED_FACTORY: - return siblingClassName(asTypeElement(binding.bindingElement().get()), "_Impl"); - - default: - throw new AssertionError(); - } - + return factoryNameForElement(asExecutable(binding.bindingElement().get())); + case ASSISTED_FACTORY: + return siblingClassName(asTypeElement(binding.bindingElement().get()), "_Impl"); case MEMBERS_INJECTION: return membersInjectorNameForType( ((MembersInjectionBinding) binding).membersInjectedType()); + default: + throw new AssertionError(); } - throw new AssertionError(); } /** @@ -182,35 +177,35 @@ * #generatedClassNameForBinding(Binding)} instead since this method does not validate that the * given element is actually a binding element or not. */ - public static ClassName factoryNameForElement(XExecutableElement element) { + public static XClassName factoryNameForElement(XExecutableElement element) { return elementBasedClassName(element, "Factory"); } /** - * Calculates an appropriate {@link ClassName} for a generated class that is based on {@code + * Calculates an appropriate {@link XClassName} for a generated class that is based on {@code * element}, appending {@code suffix} at the end. * - * <p>This will always return a {@linkplain ClassName#topLevelClassName() top level class name}, - * even if {@code element}'s enclosing class is a nested type. + * <p>This will always return a top level class name, even if {@code element}'s enclosing class is + * a nested type. */ - public static ClassName elementBasedClassName(XExecutableElement element, String suffix) { - ClassName enclosingClassName = element.getEnclosingElement().getClassName(); + public static XClassName elementBasedClassName(XExecutableElement element, String suffix) { + XClassName enclosingClassName = element.getEnclosingElement().asClassName(); String methodName = isConstructor(element) ? "" : LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(element)); - return ClassName.get( - enclosingClassName.packageName(), + return XClassName.Companion.get( + enclosingClassName.getPackageName(), classFileName(enclosingClassName) + "_" + methodName + suffix); } public static TypeName parameterizedGeneratedTypeNameForBinding(Binding binding) { - ClassName className = generatedClassNameForBinding(binding); + ClassName className = toJavaPoet(generatedClassNameForBinding(binding)); ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding); return typeParameters.isEmpty() ? className : ParameterizedTypeName.get(className, Iterables.toArray(typeParameters, TypeName.class)); } - public static ClassName membersInjectorNameForType(XTypeElement typeElement) { + public static XClassName membersInjectorNameForType(XTypeElement typeElement) { return siblingClassName(typeElement, "_MembersInjector"); } @@ -218,19 +213,42 @@ return field.getEnclosingElement().getClassName().canonicalName() + "." + getSimpleName(field); } - public static String classFileName(ClassName className) { - return CLASS_FILE_NAME_JOINER.join(className.simpleNames()); + /* + * TODO(ronshapiro): this isn't perfect, as collisions could still exist. Some examples: + * + * - @Inject void members() {} will generate a method that conflicts with the instance + * method `injectMembers(T)` + * - Adding the index could conflict with another member: + * @Inject void a(Object o) {} + * @Inject void a(String s) {} + * @Inject void a1(String s) {} + * + * Here, Method a(String) will add the suffix "1", which will conflict with the method + * generated for a1(String) + * - Members named "members" or "methods" could also conflict with the {@code static} injection + * method. + */ + public static String membersInjectorMethodName(InjectionSite injectionSite) { + int index = injectionSite.indexAmongAtInjectMembersWithSameSimpleName(); + String indexString = index == 0 ? "" : String.valueOf(index + 1); + return "inject" + + LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(injectionSite.element())) + + indexString; } - public static ClassName generatedMonitoringModuleName(XTypeElement componentElement) { + public static String classFileName(XClassName className) { + return CLASS_FILE_NAME_JOINER.join(className.getSimpleNames()); + } + + public static XClassName generatedMonitoringModuleName(XTypeElement componentElement) { return siblingClassName(componentElement, "_MonitoringModule"); } // TODO(ronshapiro): when JavaPoet migration is complete, replace the duplicated code // which could use this. - private static ClassName siblingClassName(XTypeElement typeElement, String suffix) { - ClassName className = typeElement.getClassName(); - return className.topLevelClassName().peerClass(classFileName(className) + suffix); + private static XClassName siblingClassName(XTypeElement typeElement, String suffix) { + XClassName className = typeElement.asClassName(); + return XClassName.Companion.get(className.getPackageName(), classFileName(className) + suffix); } /** @@ -243,31 +261,33 @@ * {@code Set<Produced<T>>}. * </ul> */ - public static ClassName setFactoryClassName(ContributionBinding binding) { - checkArgument(binding.kind().equals(MULTIBOUND_SET)); - if (binding.bindingType().equals(BindingType.PROVISION)) { - return SET_FACTORY; - } else { - SetType setType = SetType.from(binding.key()); - return setType.elementsAreTypeOf(TypeNames.PRODUCED) - ? SET_OF_PRODUCED_PRODUCER - : SET_PRODUCER; + public static XClassName setFactoryClassName(MultiboundSetBinding binding) { + switch (binding.bindingType()) { + case PROVISION: + return XTypeNames.SET_FACTORY; + case PRODUCTION: + SetType setType = SetType.from(binding.key()); + return setType.elementsAreTypeOf(TypeNames.PRODUCED) + ? XTypeNames.SET_OF_PRODUCED_PRODUCER + : XTypeNames.SET_PRODUCER; + default: + throw new IllegalArgumentException(binding.bindingType().toString()); } } /** The {@link java.util.Map} factory class name appropriate for map bindings. */ - public static ClassName mapFactoryClassName(ContributionBinding binding) { - checkState(binding.kind().equals(MULTIBOUND_MAP), binding.kind()); + public static XClassName mapFactoryClassName(MultiboundMapBinding binding) { MapType mapType = MapType.from(binding.key()); switch (binding.bindingType()) { case PROVISION: - return mapType.valuesAreTypeOf(PROVIDER) ? MAP_PROVIDER_FACTORY : MAP_FACTORY; + return mapType.valuesAreTypeOf(PROVIDER) + ? XTypeNames.MAP_PROVIDER_FACTORY : XTypeNames.MAP_FACTORY; case PRODUCTION: return mapType.valuesAreFrameworkType() ? mapType.valuesAreTypeOf(PRODUCER) - ? MAP_OF_PRODUCER_PRODUCER - : MAP_OF_PRODUCED_PRODUCER - : MAP_PRODUCER; + ? XTypeNames.MAP_OF_PRODUCER_PRODUCER + : XTypeNames.MAP_OF_PRODUCED_PRODUCER + : XTypeNames.MAP_PRODUCER; default: throw new IllegalArgumentException(binding.bindingType().toString()); } @@ -293,16 +313,15 @@ */ // TODO(gak): maybe this should be a function of TypeMirrors instead of Elements? public static String simpleVariableName(XTypeElement typeElement) { - return simpleVariableName(typeElement.getClassName()); + return simpleVariableName(typeElement.asClassName()); } /** - * Returns a name to be used for variables of the given {@linkplain ClassName}. Prefer - * semantically meaningful variable names, but if none can be derived, this will produce something - * readable. + * Returns a name to be used for variables of the given {@link XClassName}. Prefer semantically + * meaningful variable names, but if none can be derived, this will produce something readable. */ - public static String simpleVariableName(ClassName className) { - String candidateName = UPPER_CAMEL.to(LOWER_CAMEL, className.simpleName()); + public static String simpleVariableName(XClassName className) { + String candidateName = UPPER_CAMEL.to(LOWER_CAMEL, simpleName(className)); String variableName = protectAgainstKeywords(candidateName); verify(isName(variableName), "'%s' was expected to be a valid variable name", variableName); return variableName;
diff --git a/java/dagger/internal/codegen/binding/SubcomponentCreatorBinding.java b/java/dagger/internal/codegen/binding/SubcomponentCreatorBinding.java new file mode 100644 index 0000000..b236163 --- /dev/null +++ b/java/dagger/internal/codegen/binding/SubcomponentCreatorBinding.java
@@ -0,0 +1,77 @@ +/* + * 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.binding; + +import com.google.auto.value.AutoValue; +import com.google.auto.value.extension.memoized.Memoized; +import com.google.common.collect.ImmutableSet; +import com.google.errorprone.annotations.CheckReturnValue; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.model.BindingKind; +import dagger.internal.codegen.model.DependencyRequest; +import dagger.internal.codegen.xprocessing.Nullability; +import java.util.Optional; + +/** A binding for a {@link BindingKind#SUBCOMPONENT_CREATOR}. */ +@CheckReturnValue +@AutoValue +public abstract class SubcomponentCreatorBinding extends ContributionBinding { + @Override + public BindingKind kind() { + return BindingKind.SUBCOMPONENT_CREATOR; + } + + @Override + public Optional<BindingType> optionalBindingType() { + return Optional.of(BindingType.PROVISION); + } + + @Override + public ContributionType contributionType() { + return ContributionType.UNIQUE; + } + + @Override + public Nullability nullability() { + return Nullability.NOT_NULLABLE; + } + + @Override + public ImmutableSet<DependencyRequest> dependencies() { + return ImmutableSet.of(); + } + + @Override + public abstract Builder toBuilder(); + + @Memoized + @Override + public abstract int hashCode(); + + // TODO(ronshapiro,dpb): simplify the equality semantics + @Override + public abstract boolean equals(Object obj); + + static Builder builder() { + return new AutoValue_SubcomponentCreatorBinding.Builder(); + } + + /** A {@link SubcomponentCreatorBinding} builder. */ + @AutoValue.Builder + abstract static class Builder + extends ContributionBinding.Builder<SubcomponentCreatorBinding, Builder> {} +}
diff --git a/java/dagger/internal/codegen/binding/SubcomponentDeclaration.java b/java/dagger/internal/codegen/binding/SubcomponentDeclaration.java index 5df2dd9..a04c745 100644 --- a/java/dagger/internal/codegen/binding/SubcomponentDeclaration.java +++ b/java/dagger/internal/codegen/binding/SubcomponentDeclaration.java
@@ -36,7 +36,7 @@ * dagger.Module#subcomponents()}. */ @AutoValue -public abstract class SubcomponentDeclaration extends BindingDeclaration { +public abstract class SubcomponentDeclaration extends Declaration { /** * Key for the {@link dagger.Subcomponent.Builder} or {@link * dagger.producers.ProductionSubcomponent.Builder} of {@link #subcomponentType()}.
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java b/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java index c826c3d..dab9cb8 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java
@@ -42,8 +42,9 @@ MissingBindingValidator validation7, NullableBindingValidator validation8, ProvisionDependencyOnProducerBindingValidator validation9, - SetMultibindingValidator validation10, - SubcomponentFactoryMethodValidator validation11) { + InvalidProductionBindingScopeValidator validation10, + SetMultibindingValidator validation11, + SubcomponentFactoryMethodValidator validation12) { ImmutableSet<ValidationBindingGraphPlugin> plugins = ImmutableSet.of( validation1, @@ -56,7 +57,8 @@ validation8, validation9, validation10, - validation11); + validation11, + validation12); if (compilerOptions.experimentalDaggerErrorMessages()) { return ImmutableSet.of(factory.create(plugins)); } else {
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java index a2c53c4..0ed6641 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java
@@ -50,7 +50,6 @@ import dagger.internal.codegen.model.BindingGraph.DependencyEdge; import dagger.internal.codegen.model.BindingGraph.Node; import dagger.internal.codegen.model.BindingKind; -import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.validation.ValidationBindingGraphPlugin; @@ -179,20 +178,26 @@ } private String errorMessage(Cycle<Node> cycle, BindingGraph graph) { - StringBuilder message = new StringBuilder("Found a dependency cycle:"); - ImmutableList<DependencyRequest> cycleRequests = + return "Found a dependency cycle:" + + "\n" + + dependencyRequestFormatter.formatEdges(cycleEdges(cycle, graph), graph) + + "\n" + + Formatter.INDENT + + "..."; + } + + private ImmutableList<DependencyEdge> cycleEdges(Cycle<Node> cycle, BindingGraph graph) { + ImmutableList<DependencyEdge> cycleEdges = cycle.endpointPairs().stream() // TODO(dpb): Would be nice to take the dependency graph here. .map(endpointPair -> nonCycleBreakingEdge(endpointPair, graph)) - .map(DependencyEdge::dependencyRequest) .collect(toImmutableList()) .reverse(); - dependencyRequestFormatter.formatIndentedList(message, cycleRequests, 0); - message.append("\n") - .append(dependencyRequestFormatter.format(cycleRequests.get(0))) - .append("\n") - .append(Formatter.INDENT).append("..."); - return message.toString(); + // Add the first edge to the end of the list to complete the cycle. + return ImmutableList.<DependencyEdge>builder() + .addAll(cycleEdges) + .add(cycleEdges.get(0)) + .build(); } /**
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java index ea4d738..a15c67c 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java
@@ -19,8 +19,9 @@ import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; import static javax.tools.Diagnostic.Kind.ERROR; +import androidx.room.compiler.processing.XProcessingEnv; import dagger.internal.codegen.binding.KeyFactory; -import dagger.internal.codegen.compileroption.CompilerOptions; +import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.Binding; import dagger.internal.codegen.model.BindingGraph; import dagger.internal.codegen.model.BindingGraph.MaybeBinding; @@ -34,12 +35,12 @@ */ // TODO(dpb,beder): Validate this during @Inject/@Provides/@Produces validation. final class DependsOnProductionExecutorValidator extends ValidationBindingGraphPlugin { - private final CompilerOptions compilerOptions; + private final XProcessingEnv processingEnv; private final KeyFactory keyFactory; @Inject - DependsOnProductionExecutorValidator(CompilerOptions compilerOptions, KeyFactory keyFactory) { - this.compilerOptions = compilerOptions; + DependsOnProductionExecutorValidator(XProcessingEnv processingEnv, KeyFactory keyFactory) { + this.processingEnv = processingEnv; this.keyFactory = keyFactory; } @@ -50,7 +51,7 @@ @Override public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { - if (!compilerOptions.usesProducers()) { + if (!usesProducers()) { return; } @@ -69,4 +70,8 @@ diagnosticReporter.reportBinding( ERROR, binding, "%s may not depend on the production executor", binding.key()); } + + private boolean usesProducers() { + return processingEnv.findTypeElement(TypeNames.PRODUCES) != null; + } }
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java index 5f4dcfc..e357898 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java
@@ -38,9 +38,9 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import dagger.internal.codegen.base.Formatter; -import dagger.internal.codegen.binding.BindingDeclaration; -import dagger.internal.codegen.binding.BindingDeclarationFormatter; import dagger.internal.codegen.binding.BindingNode; +import dagger.internal.codegen.binding.Declaration; +import dagger.internal.codegen.binding.DeclarationFormatter; import dagger.internal.codegen.binding.MultibindingDeclaration; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.model.Binding; @@ -70,13 +70,13 @@ private static final Comparator<Binding> BY_LENGTH_OF_COMPONENT_PATH = comparing(binding -> binding.componentPath().components().size()); - private final BindingDeclarationFormatter bindingDeclarationFormatter; + private final DeclarationFormatter declarationFormatter; private final CompilerOptions compilerOptions; @Inject DuplicateBindingsValidator( - BindingDeclarationFormatter bindingDeclarationFormatter, CompilerOptions compilerOptions) { - this.bindingDeclarationFormatter = bindingDeclarationFormatter; + DeclarationFormatter declarationFormatter, CompilerOptions compilerOptions) { + this.declarationFormatter = declarationFormatter; this.compilerOptions = compilerOptions; } @@ -219,7 +219,7 @@ return String.format( "\n%s%s [%s]", Formatter.INDENT, - bindingDeclarationFormatter.format(((BindingNode) binding).delegate()), + declarationFormatter.format(((BindingNode) binding).delegate()), binding.componentPath()); } @@ -244,7 +244,7 @@ .append(multibindingTypeString(oneMultibinding)) .append(" bindings and declarations:"); formatDeclarations(message, 2, declarations(graph, multibindings)); - ImmutableSet<BindingDeclaration> uniqueBindingDeclarations = + ImmutableSet<Declaration> uniqueBindingDeclarations = duplicateBindings.stream() .filter(binding -> !binding.kind().isMultibinding()) .flatMap(binding -> declarations(graph, binding).stream()) @@ -267,25 +267,25 @@ private void formatDeclarations( StringBuilder builder, int indentLevel, - Iterable<? extends BindingDeclaration> bindingDeclarations) { - bindingDeclarationFormatter.formatIndentedList( + Iterable<? extends Declaration> bindingDeclarations) { + declarationFormatter.formatIndentedList( builder, ImmutableList.copyOf(bindingDeclarations), indentLevel); } - private ImmutableSet<BindingDeclaration> declarations( + private ImmutableSet<Declaration> declarations( BindingGraph graph, ImmutableCollection<Binding> bindings) { return bindings.stream() .flatMap(binding -> declarations(graph, binding).stream()) .distinct() - .sorted(BindingDeclaration.COMPARATOR) + .sorted(Declaration.COMPARATOR) .collect(toImmutableSet()); } - private ImmutableSet<BindingDeclaration> declarations(BindingGraph graph, Binding binding) { - ImmutableSet.Builder<BindingDeclaration> declarations = ImmutableSet.builder(); + private ImmutableSet<Declaration> declarations(BindingGraph graph, Binding binding) { + ImmutableSet.Builder<Declaration> declarations = ImmutableSet.builder(); BindingNode bindingNode = (BindingNode) binding; bindingNode.associatedDeclarations().forEach(declarations::add); - if (bindingDeclarationFormatter.canFormat(bindingNode.delegate())) { + if (declarationFormatter.canFormat(bindingNode.delegate())) { declarations.add(bindingNode.delegate()); } else { graph.requestedBindings(binding).stream()
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java index c1108a8..50198ef 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java
@@ -21,11 +21,10 @@ import static dagger.internal.codegen.model.BindingKind.INJECTION; import static dagger.internal.codegen.xprocessing.XElements.asExecutable; import static dagger.internal.codegen.xprocessing.XElements.closestEnclosingTypeElement; +import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.joining; import static javax.tools.Diagnostic.Kind.ERROR; -import com.google.common.collect.ImmutableSetMultimap; -import com.google.common.collect.Multimaps; import dagger.internal.codegen.base.Scopes; import dagger.internal.codegen.binding.MethodSignatureFormatter; import dagger.internal.codegen.compileroption.CompilerOptions; @@ -35,8 +34,8 @@ import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.validation.DiagnosticMessageGenerator; import dagger.internal.codegen.validation.ValidationBindingGraphPlugin; +import java.util.List; import java.util.Optional; -import java.util.Set; import javax.inject.Inject; import javax.tools.Diagnostic; @@ -45,7 +44,6 @@ * component. */ final class IncompatiblyScopedBindingsValidator extends ValidationBindingGraphPlugin { - private final MethodSignatureFormatter methodSignatureFormatter; private final CompilerOptions compilerOptions; private final DiagnosticMessageGenerator.Factory diagnosticMessageGeneratorFactory; @@ -69,36 +67,36 @@ public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { DiagnosticMessageGenerator diagnosticMessageGenerator = diagnosticMessageGeneratorFactory.create(bindingGraph); - ImmutableSetMultimap.Builder<ComponentNode, dagger.internal.codegen.model.Binding> - incompatibleBindings = ImmutableSetMultimap.builder(); - for (dagger.internal.codegen.model.Binding binding : bindingGraph.bindings()) { - binding - .scope() - .filter(scope -> !scope.isReusable()) - .ifPresent( - scope -> { - ComponentNode componentNode = - bindingGraph.componentNode(binding.componentPath()).get(); - if (!componentNode.scopes().contains(scope)) { - // @Inject bindings in module or subcomponent binding graphs will appear at the - // properly scoped ancestor component, so ignore them here. - if (binding.kind().equals(INJECTION) - && (bindingGraph.rootComponentNode().isSubcomponent() - || !bindingGraph.rootComponentNode().isRealComponent())) { - return; - } - incompatibleBindings.put(componentNode, binding); - } - }); + bindingGraph.bindings().stream() + .filter(binding -> hasIncompatibleScope(bindingGraph, binding)) + .collect(groupingBy(binding -> owningComponent(bindingGraph, binding))) + .forEach((owningComponent, bindings) -> + report(owningComponent, bindings, diagnosticReporter, diagnosticMessageGenerator)); + } + + private static boolean hasIncompatibleScope(BindingGraph bindingGraph, Binding binding) { + if (binding.scope().isEmpty() + || binding.scope().get().isReusable() + // @Inject bindings in module or subcomponent binding graphs will appear at the + // properly scoped ancestor component, so ignore them here. + || (binding.kind() == INJECTION && isSubcomponentOrModuleRoot(bindingGraph))) { + return false; } - Multimaps.asMap(incompatibleBindings.build()) - .forEach((componentNode, bindings) -> - report(componentNode, bindings, diagnosticReporter, diagnosticMessageGenerator)); + return !owningComponent(bindingGraph, binding).scopes().contains(binding.scope().get()); + } + + private static boolean isSubcomponentOrModuleRoot(BindingGraph bindingGraph) { + ComponentNode rootComponent = bindingGraph.rootComponentNode(); + return rootComponent.isSubcomponent() || !rootComponent.isRealComponent(); + } + + private static ComponentNode owningComponent(BindingGraph bindingGraph, Binding binding) { + return bindingGraph.componentNode(binding.componentPath()).get(); } private void report( ComponentNode componentNode, - Set<Binding> bindings, + List<Binding> bindings, DiagnosticReporter diagnosticReporter, DiagnosticMessageGenerator diagnosticMessageGenerator) { Diagnostic.Kind diagnosticKind = ERROR; @@ -128,7 +126,7 @@ for (Binding binding : bindings) { message.append('\n').append(INDENT); - // TODO(dpb): Use BindingDeclarationFormatter. + // TODO(dpb): Use DeclarationFormatter. // But that doesn't print scopes for @Inject-constructed types. switch (binding.kind()) { case DELEGATE:
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java index 2151295..6455f29 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java
@@ -33,7 +33,7 @@ @Inject InjectBindingValidator(InjectValidator injectValidator) { - this.injectValidator = injectValidator.whenGeneratingCode(); + this.injectValidator = injectValidator; } @Override @@ -50,7 +50,8 @@ private void validateInjectionBinding(Binding node, DiagnosticReporter diagnosticReporter) { ValidationReport typeReport = - injectValidator.validate(node.key().type().xprocessing().getTypeElement()); + injectValidator.validateWhenGeneratingCode( + node.key().type().xprocessing().getTypeElement()); for (Item item : typeReport.allItems()) { diagnosticReporter.reportBinding(item.kind(), node, item.message()); }
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/InvalidProductionBindingScopeValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/InvalidProductionBindingScopeValidator.java new file mode 100644 index 0000000..f8a510c --- /dev/null +++ b/java/dagger/internal/codegen/bindinggraphvalidation/InvalidProductionBindingScopeValidator.java
@@ -0,0 +1,54 @@ +/* + * 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.bindinggraphvalidation; + +import static javax.tools.Diagnostic.Kind.ERROR; + +import dagger.internal.codegen.model.Binding; +import dagger.internal.codegen.model.BindingGraph; +import dagger.internal.codegen.model.DiagnosticReporter; +import dagger.internal.codegen.validation.ValidationBindingGraphPlugin; +import javax.inject.Inject; + +/** Reports an error for each production binding type that is invalidly scoped. */ +final class InvalidProductionBindingScopeValidator extends ValidationBindingGraphPlugin { + + @Inject + InvalidProductionBindingScopeValidator() {} + + @Override + public String pluginName() { + return "Dagger/InvalidProductionBindingScope"; + } + + @Override + public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter reporter) { + // Note: ProducesMethodValidator validates that @Produces methods aren't scoped, but here we + // take that a step further and validate that anything that transitively depends on a @Produces + // method is also not scoped (i.e. all production binding types). + bindingGraph.bindings().stream() + .filter(Binding::isProduction) + .filter(binding -> binding.scope().isPresent()) + .forEach(binding -> reporter.reportBinding(ERROR, binding, errorMessage(binding))); + } + + private String errorMessage(Binding binding) { + return String.format( + "%s cannot be scoped because it delegates to an @Produces method.", + binding); + } +}
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java index 87e8771..8d92c6e 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java
@@ -17,31 +17,31 @@ package dagger.internal.codegen.bindinggraphvalidation; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Multimaps.filterKeys; import static dagger.internal.codegen.base.Formatter.INDENT; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; -import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSetMultimap; import static dagger.internal.codegen.model.BindingKind.MULTIBOUND_MAP; +import static dagger.internal.codegen.xprocessing.XAnnotations.getClassName; import static javax.tools.Diagnostic.Kind.ERROR; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSetMultimap; import com.google.common.collect.Multimaps; -import com.google.common.collect.SetMultimap; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.base.MapType; -import dagger.internal.codegen.binding.BindingDeclaration; -import dagger.internal.codegen.binding.BindingDeclarationFormatter; import dagger.internal.codegen.binding.BindingNode; import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.Declaration; +import dagger.internal.codegen.binding.DeclarationFormatter; import dagger.internal.codegen.binding.KeyFactory; -import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.Binding; 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 dagger.internal.codegen.xprocessing.XAnnotations; +import java.util.Comparator; +import java.util.HashSet; import java.util.Set; import javax.inject.Inject; @@ -51,13 +51,13 @@ */ final class MapMultibindingValidator extends ValidationBindingGraphPlugin { - private final BindingDeclarationFormatter bindingDeclarationFormatter; + private final DeclarationFormatter declarationFormatter; private final KeyFactory keyFactory; @Inject MapMultibindingValidator( - BindingDeclarationFormatter bindingDeclarationFormatter, KeyFactory keyFactory) { - this.bindingDeclarationFormatter = bindingDeclarationFormatter; + DeclarationFormatter declarationFormatter, KeyFactory keyFactory) { + this.declarationFormatter = declarationFormatter; this.keyFactory = keyFactory; } @@ -90,41 +90,19 @@ * </ol> */ private ImmutableSet<Binding> mapMultibindings(BindingGraph bindingGraph) { - ImmutableSetMultimap<Key, Binding> mapMultibindings = - bindingGraph.bindings().stream() - .filter(node -> node.kind().equals(MULTIBOUND_MAP)) - .collect(toImmutableSetMultimap(Binding::key, node -> node)); + Set<Key> visitedKeys = new HashSet<>(); + return bindingGraph.bindings().stream() + .filter(binding -> binding.kind().equals(MULTIBOUND_MAP)) + // Sort by the order of the value in the RequestKind: + // (Map<K, V>, then Map<K, Provider<V>>, then Map<K, Producer<V>>). + .sorted(Comparator.comparing(binding -> MapType.from(binding.key()).valueRequestKind())) + // Only take the first binding (post sorting) per unwrapped key. + .filter(binding -> visitedKeys.add(unwrappedKey(binding))) + .collect(toImmutableSet()); + } - // Mutlbindings for Map<K, V> - SetMultimap<Key, Binding> plainValueMapMultibindings = - filterKeys(mapMultibindings, key -> !MapType.from(key).valuesAreFrameworkType()); - - // Multibindings for Map<K, Provider<V>> where Map<K, V> isn't in plainValueMapMultibindings - SetMultimap<Key, Binding> providerValueMapMultibindings = - filterKeys( - mapMultibindings, - key -> - MapType.from(key).valuesAreTypeOf(TypeNames.PROVIDER) - && !plainValueMapMultibindings.containsKey(keyFactory.unwrapMapValueType(key))); - - // Multibindings for Map<K, Producer<V>> where Map<K, V> isn't in plainValueMapMultibindings and - // Map<K, Provider<V>> isn't in providerValueMapMultibindings - SetMultimap<Key, Binding> producerValueMapMultibindings = - filterKeys( - mapMultibindings, - key -> - MapType.from(key).valuesAreTypeOf(TypeNames.PRODUCER) - && !plainValueMapMultibindings.containsKey(keyFactory.unwrapMapValueType(key)) - && !providerValueMapMultibindings.containsKey( - keyFactory - .rewrapMapKey(key, TypeNames.PRODUCER, TypeNames.PROVIDER) - .get())); - - return new ImmutableSet.Builder<Binding>() - .addAll(plainValueMapMultibindings.values()) - .addAll(providerValueMapMultibindings.values()) - .addAll(producerValueMapMultibindings.values()) - .build(); + private Key unwrappedKey(Binding binding) { + return keyFactory.unwrapMapValueType(binding.key()); } private ImmutableSet<ContributionBinding> mapBindingContributions( @@ -141,7 +119,11 @@ ImmutableSet<ContributionBinding> contributions, DiagnosticReporter diagnosticReporter) { ImmutableSetMultimap<?, ContributionBinding> contributionsByMapKey = - ImmutableSetMultimap.copyOf(Multimaps.index(contributions, ContributionBinding::mapKey)); + ImmutableSetMultimap.copyOf( + Multimaps.index( + contributions, + // Note: We're wrapping in XAnnotations.equivalence() to get proper equals/hashcode. + binding -> binding.mapKey().map(XAnnotations.equivalence()::wrap))); for (Set<ContributionBinding> contributionsForOneMapKey : Multimaps.asMap(contributionsByMapKey).values()) { @@ -160,7 +142,7 @@ DiagnosticReporter diagnosticReporter) { ImmutableSetMultimap<ClassName, ContributionBinding> contributionsByMapKeyAnnotationType = ImmutableSetMultimap.copyOf( - Multimaps.index(contributions, mapBinding -> mapBinding.mapKey().get().className())); + Multimaps.index(contributions, mapBinding -> getClassName(mapBinding.mapKey().get()))); if (contributionsByMapKeyAnnotationType.keySet().size() > 1) { diagnosticReporter.reportBinding( @@ -181,7 +163,7 @@ .forEach( (annotationType, contributions) -> { message.append('\n').append(INDENT).append(annotationType).append(':'); - bindingDeclarationFormatter.formatIndentedList(message, contributions, 2); + declarationFormatter.formatIndentedList(message, contributions, 2); }); return message.toString(); } @@ -191,9 +173,9 @@ StringBuilder message = new StringBuilder("The same map key is bound more than once for ").append(mapBindingKey); - bindingDeclarationFormatter.formatIndentedList( + declarationFormatter.formatIndentedList( message, - ImmutableList.sortedCopyOf(BindingDeclaration.COMPARATOR, contributionsForOneMapKey), + ImmutableList.sortedCopyOf(Declaration.COMPARATOR, contributionsForOneMapKey), 1); return message.toString(); }
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java index fd9e42e..f211717 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java
@@ -18,13 +18,12 @@ import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; 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.base.RequestKinds.dependencyCanBeProduction; import static dagger.internal.codegen.binding.DependencyRequestFormatter.DOUBLE_INDENT; import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; @@ -40,16 +39,12 @@ 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; import dagger.internal.codegen.model.BindingGraph; -import dagger.internal.codegen.model.BindingGraph.ComponentNode; 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.DaggerAnnotation; +import dagger.internal.codegen.model.DaggerType; import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.validation.DiagnosticMessageGenerator; @@ -58,24 +53,19 @@ import java.util.ArrayDeque; import java.util.Deque; import java.util.Iterator; -import java.util.List; -import java.util.Optional; import javax.inject.Inject; /** Reports errors for missing bindings. */ final class MissingBindingValidator extends ValidationBindingGraphPlugin { private final InjectBindingRegistry injectBindingRegistry; - private final DependencyRequestFormatter dependencyRequestFormatter; private final DiagnosticMessageGenerator.Factory diagnosticMessageGeneratorFactory; @Inject MissingBindingValidator( InjectBindingRegistry injectBindingRegistry, - DependencyRequestFormatter dependencyRequestFormatter, DiagnosticMessageGenerator.Factory diagnosticMessageGeneratorFactory) { this.injectBindingRegistry = injectBindingRegistry; - this.dependencyRequestFormatter = dependencyRequestFormatter; this.diagnosticMessageGeneratorFactory = diagnosticMessageGeneratorFactory; } @@ -115,24 +105,28 @@ ERROR, graph.componentNode(missingBinding.componentPath()).get(), missingBindingErrorMessage(missingBinding, graph) - + missingBindingDependencyTraceMessage(missingBinding, graph) + + diagnosticMessageGeneratorFactory.create(graph).getMessage(missingBinding) + alternativeBindingsMessage(missingBinding, graph) + similarBindingsMessage(missingBinding, graph)); } private static ImmutableSet<Binding> getSimilarTypeBindings( BindingGraph graph, Key missingBindingKey) { - XType missingBindingType = missingBindingKey.type().xprocessing(); - Optional<DaggerAnnotation> missingBindingQualifier = missingBindingKey.qualifier(); - ImmutableList<TypeName> flatMissingBindingType = flattenBindingType(missingBindingType); + ImmutableList<TypeName> flatMissingBindingType = flattenBindingType(missingBindingKey.type()); if (flatMissingBindingType.size() <= 1) { return ImmutableSet.of(); } return graph.bindings().stream() - .filter( - binding -> - binding.key().qualifier().equals(missingBindingQualifier) - && isSimilarType(binding.key().type().xprocessing(), flatMissingBindingType)) + // Filter out multibinding contributions (users can't request these directly). + .filter(binding -> binding.key().multibindingContributionIdentifier().isEmpty()) + // Filter out keys with the exact same type (those are reported elsewhere). + .filter(binding -> !binding.key().type().equals(missingBindingKey.type())) + // Filter out keys with different qualifiers. + // TODO(bcorso): We should consider allowing keys with different qualifiers here, as that + // could actually be helpful when users forget a qualifier annotation on the request. + .filter(binding -> binding.key().qualifier().equals(missingBindingKey.qualifier())) + // Filter out keys that don't have a similar type (i.e. same type if ignoring wildcards). + .filter(binding -> isSimilarType(binding.key().type(), flatMissingBindingType)) .collect(toImmutableSet()); } @@ -140,11 +134,11 @@ * Unwraps a parameterized type to a list of TypeNames. e.g. {@code Map<Foo, List<Bar>>} to {@code * [Map, Foo, List, Bar]}. */ - private static ImmutableList<TypeName> flattenBindingType(XType type) { + private static ImmutableList<TypeName> flattenBindingType(DaggerType type) { return ImmutableList.copyOf(new TypeDfsIterator(type)); } - private static boolean isSimilarType(XType type, List<TypeName> flatTypeNames) { + private static boolean isSimilarType(DaggerType type, ImmutableList<TypeName> flatTypeNames) { return Iterators.elementsEqual(flatTypeNames.iterator(), new TypeDfsIterator(type)); } @@ -178,36 +172,7 @@ errorMessage.append( " This type supports members injection but cannot be implicitly provided."); } - return errorMessage.toString(); - } - - 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 = - new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */).append("\n"); - for (DependencyEdge edge : dependencyTrace) { - String line = dependencyRequestFormatter.format(edge.dependencyRequest()); - if (line.isEmpty()) { - continue; - } - // 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()) { - generator.appendComponentPathUnlessAtRoot(message, source(getLast(dependencyTrace), graph)); - } - message.append( - generator.getRequestsNotInTrace( - dependencyTrace, generator.requests(missingBinding), entryPoints)); - return message.toString(); + return errorMessage.append("\n").toString(); } private String alternativeBindingsMessage( @@ -282,20 +247,6 @@ .allMatch(edge -> dependencyCanBeProduction(edge, graph)); } - // TODO(ronshapiro): merge with - // ProvisionDependencyOnProduerBindingValidator.dependencyCanUseProduction - private boolean dependencyCanBeProduction(DependencyEdge edge, BindingGraph graph) { - Node source = graph.network().incidentNodes(edge).source(); - if (source instanceof ComponentNode) { - return canBeSatisfiedByProductionBinding(edge.dependencyRequest().kind()); - } - if (source instanceof Binding) { - return ((Binding) source).isProduction(); - } - throw new IllegalArgumentException( - "expected a dagger.internal.codegen.model.Binding or ComponentNode: " + source); - } - private boolean typeHasInjectionSites(Key key) { return injectBindingRegistry .getOrFindMembersInjectionBinding(key) @@ -303,14 +254,6 @@ .orElse(false); } - private static String getComponentFromDependencyEdge(DependencyEdge edge, BindingGraph graph) { - return source(edge, graph).componentPath().currentComponent().className().canonicalName(); - } - - private static Node source(Edge edge, BindingGraph graph) { - return graph.network().incidentNodes(edge).source(); - } - /** * An iterator over a list of TypeNames produced by flattening a parameterized type. e.g. {@code * Map<Foo, List<Bar>>} to {@code [Map, Foo, List, Bar]}. @@ -320,8 +263,8 @@ private static class TypeDfsIterator implements Iterator<TypeName> { final Deque<XType> stack = new ArrayDeque<>(); - TypeDfsIterator(XType root) { - stack.push(root); + TypeDfsIterator(DaggerType root) { + stack.push(root.xprocessing()); } @Override
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java index d8305df..90735ef 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Verify.verify; import static dagger.internal.codegen.base.RequestKinds.canBeSatisfiedByProductionBinding; +import static dagger.internal.codegen.base.RequestKinds.dependencyCanBeProduction; import static dagger.internal.codegen.extension.DaggerStreams.instancesOf; import static javax.tools.Diagnostic.Kind.ERROR; @@ -64,7 +65,7 @@ return bindingGraph.bindings().stream() .filter(binding -> binding.isProduction()) .flatMap(binding -> incomingDependencies(binding, bindingGraph)) - .filter(edge -> !dependencyCanUseProduction(edge, bindingGraph)); + .filter(edge -> !dependencyCanBeProduction(edge, bindingGraph)); } /** Returns the dependencies on {@code binding}. */ @@ -74,13 +75,6 @@ .flatMap(instancesOf(DependencyEdge.class)); } - // TODO(ronshapiro): merge with MissingBindingValidator.dependencyCanUseProduction - private boolean dependencyCanUseProduction(DependencyEdge edge, BindingGraph bindingGraph) { - return edge.isEntryPoint() - ? canBeSatisfiedByProductionBinding(edge.dependencyRequest().kind()) - : bindingRequestingDependency(edge, bindingGraph).isProduction(); - } - /** * Returns the binding that requests a dependency. * @@ -108,6 +102,12 @@ private String dependencyErrorMessage( DependencyEdge dependencyOnProduction, BindingGraph bindingGraph) { + if (!canBeSatisfiedByProductionBinding( + dependencyOnProduction.dependencyRequest().kind(), false)) { + return String.format( + "request kind %s cannot be satisfied by production binding.", + dependencyOnProduction.dependencyRequest().kind()); + } return String.format( "%s is a provision, which cannot depend on a production.", bindingRequestingDependency(dependencyOnProduction, bindingGraph).key());
diff --git a/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar b/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar index 6e4b0a9..5414d72 100644 --- a/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar +++ b/java/dagger/internal/codegen/bootstrap/bootstrap_compiler_deploy.jar Binary files differ
diff --git a/java/dagger/internal/codegen/compileroption/CompilerOptions.java b/java/dagger/internal/codegen/compileroption/CompilerOptions.java index 73f7736..0fb3635 100644 --- a/java/dagger/internal/codegen/compileroption/CompilerOptions.java +++ b/java/dagger/internal/codegen/compileroption/CompilerOptions.java
@@ -21,8 +21,6 @@ /** A collection of options that dictate how the compiler will run. */ public abstract class CompilerOptions { - public abstract boolean usesProducers(); - /** * Returns true if the fast initialization flag, {@code fastInit}, is enabled. * @@ -56,15 +54,6 @@ */ public abstract boolean includeStacktraceWithDeferredErrorMessages(); - /** - * If {@code true}, Dagger will generate factories and components even if some members-injected - * types have {@code private} or {@code static} {@code @Inject}-annotated members. - * - * <p>This should only ever be enabled by the TCK tests. Disabling this validation could lead to - * generating code that does not compile. - */ - public abstract boolean ignorePrivateAndStaticInjectionForComponent(); - public abstract ValidationType scopeCycleValidationType(); /** @@ -129,6 +118,25 @@ */ public abstract boolean generatedClassExtendsComponent(); + /** + * Returns {@code true} if Dagger should turn on the binding graph fix. + * + * <p>Note: This flag is only intended to give users time to migrate. This flag will be removed in + * a future release. + * + * <p>See https://dagger.dev/dev-guide/compiler-options#useBindingGraphFix for more details. + */ + public abstract boolean useBindingGraphFix(); + + /** + * Returns {@code true} if the key for map multibinding contributions contain a framework type. + * + * <p>This option is for migration purposes only, and will be removed in a future release. + * + * <p>The default value is {@code false}. + */ + public abstract boolean useFrameworkTypeInMapMultibindingContributionKey(); + /** Returns the number of bindings allowed per shard. */ public int keysPerComponentShard(XTypeElement component) { return 3500;
diff --git a/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java b/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java index 8138005..b94f8de 100644 --- a/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java +++ b/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java
@@ -29,12 +29,13 @@ import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.FLOATING_BINDS_METHODS; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.FORMAT_GENERATED_SOURCE; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.GENERATED_CLASS_EXTENDS_COMPONENT; -import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.IGNORE_PROVISION_KEY_WILDCARDS; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.INCLUDE_STACKTRACE_WITH_DEFERRED_ERROR_MESSAGES; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.PLUGINS_VISIT_FULL_BINDING_GRAPHS; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.STRICT_MULTIBINDING_VALIDATION; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.STRICT_SUPERFICIAL_VALIDATION; +import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.USE_BINDING_GRAPH_FIX; +import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.USE_FRAMEWORK_TYPE_IN_MAP_MULTIBINDING_CONTRIBUTION_KEY; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.VALIDATE_TRANSITIVE_COMPONENT_DEPENDENCIES; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.WARN_IF_INJECTION_FACTORY_NOT_GENERATED_UPSTREAM; import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.WRITE_PRODUCER_NAME_IN_TOKEN; @@ -61,7 +62,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import dagger.internal.codegen.javapoet.TypeNames; import java.util.Arrays; import java.util.EnumSet; import java.util.HashMap; @@ -96,11 +96,6 @@ } @Override - public boolean usesProducers() { - return processingEnv.findTypeElement(TypeNames.PRODUCES) != null; - } - - @Override public boolean headerCompilation() { return isEnabled(HEADER_COMPILATION); } @@ -145,11 +140,6 @@ } @Override - public boolean ignorePrivateAndStaticInjectionForComponent() { - return isEnabled(IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT); - } - - @Override public ValidationType scopeCycleValidationType() { return parseOption(DISABLE_INTER_COMPONENT_SCOPE_VALIDATION); } @@ -190,6 +180,11 @@ } @Override + public boolean useFrameworkTypeInMapMultibindingContributionKey() { + return isEnabled(USE_FRAMEWORK_TYPE_IN_MAP_MULTIBINDING_CONTRIBUTION_KEY); + } + + @Override public boolean ignoreProvisionKeyWildcards() { return isEnabled(IGNORE_PROVISION_KEY_WILDCARDS); } @@ -210,6 +205,11 @@ } @Override + public boolean useBindingGraphFix() { + return isEnabled(USE_BINDING_GRAPH_FIX); + } + + @Override public int keysPerComponentShard(XTypeElement component) { if (options.containsKey(KEYS_PER_COMPONENT_SHARD)) { checkArgument( @@ -244,15 +244,14 @@ 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")); - } + if (processingEnv.getBackend() == XProcessingEnv.Backend.KSP + && !isEnabled(IGNORE_PROVISION_KEY_WILDCARDS)) { + 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; } @@ -325,8 +324,6 @@ INCLUDE_STACKTRACE_WITH_DEFERRED_ERROR_MESSAGES, - IGNORE_PRIVATE_AND_STATIC_INJECTION_FOR_COMPONENT, - EXPERIMENTAL_AHEAD_OF_TIME_SUBCOMPONENTS, FORCE_USE_SERIALIZED_COMPONENT_IMPLEMENTATIONS, @@ -345,6 +342,10 @@ GENERATED_CLASS_EXTENDS_COMPONENT, + USE_BINDING_GRAPH_FIX, + + USE_FRAMEWORK_TYPE_IN_MAP_MULTIBINDING_CONTRIBUTION_KEY, + IGNORE_PROVISION_KEY_WILDCARDS(ENABLED), VALIDATE_TRANSITIVE_COMPONENT_DEPENDENCIES(ENABLED)
diff --git a/java/dagger/internal/codegen/componentgenerator/BUILD b/java/dagger/internal/codegen/componentgenerator/BUILD index af10a01..6ba7e45 100644 --- a/java/dagger/internal/codegen/componentgenerator/BUILD +++ b/java/dagger/internal/codegen/componentgenerator/BUILD
@@ -15,6 +15,8 @@ # Description: # A JSR-330 compliant dependency injection system for android and java +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java b/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java index 4214cbc..f2e2103 100644 --- a/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java +++ b/java/dagger/internal/codegen/componentgenerator/ComponentHjarGenerator.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.componentgenerator; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.Preconditions.checkArgument; @@ -90,7 +91,7 @@ @Override public ImmutableList<TypeSpec.Builder> topLevelTypes(ComponentDescriptor componentDescriptor) { - ClassName generatedTypeName = getTopLevelClassName(componentDescriptor); + ClassName generatedTypeName = toJavaPoet(getTopLevelClassName(componentDescriptor)); TypeSpec.Builder generatedComponent = TypeSpec.classBuilder(generatedTypeName) .addModifiers(FINAL)
diff --git a/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java b/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java index e7c5a44..284bc42 100644 --- a/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java +++ b/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java
@@ -32,11 +32,6 @@ JavacPluginCompilerOptions() {} @Override - public boolean usesProducers() { - return true; - } - - @Override public boolean fastInit(XTypeElement element) { return false; } @@ -72,11 +67,6 @@ } @Override - public boolean ignorePrivateAndStaticInjectionForComponent() { - return false; - } - - @Override public ValidationType scopeCycleValidationType() { return NONE; } @@ -122,6 +112,16 @@ } @Override + public boolean useBindingGraphFix() { + return false; + } + + @Override + public boolean useFrameworkTypeInMapMultibindingContributionKey() { + return false; + } + + @Override public boolean strictMultibindingValidation() { return false; }
diff --git a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java b/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java index 50ec8b1..bb090fc 100644 --- a/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java +++ b/java/dagger/internal/codegen/javapoet/AnnotationSpecs.java
@@ -31,8 +31,9 @@ UNCHECKED("unchecked"), FUTURE_RETURN_VALUE_IGNORED("FutureReturnValueIgnored"), KOTLIN_INTERNAL("KotlinInternal", "KotlinInternalInJava"), - CAST("cast") - ; + CAST("cast"), + DEPRECATION("deprecation"), + UNINITIALIZED("nullness:initialization.field.uninitialized"); private final ImmutableList<String> values;
diff --git a/java/dagger/internal/codegen/javapoet/TypeNames.java b/java/dagger/internal/codegen/javapoet/TypeNames.java index ea89fc0..52e8928 100644 --- a/java/dagger/internal/codegen/javapoet/TypeNames.java +++ b/java/dagger/internal/codegen/javapoet/TypeNames.java
@@ -61,7 +61,15 @@ 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"); + ClassName.get("dagger.internal", "LazyClassKeyMap", "MapFactory"); + public static final ClassName LAZY_CLASS_KEY_MAP_PROVIDER_FACTORY = + ClassName.get("dagger.internal", "LazyClassKeyMap", "MapProviderFactory"); + public static final ClassName LAZY_MAP_OF_PRODUCED_PRODUCER = + ClassName.get("dagger.producers.internal", "LazyMapOfProducedProducer"); + public static final ClassName LAZY_MAP_OF_PRODUCER_PRODUCER = + ClassName.get("dagger.producers.internal", "LazyMapOfProducerProducer"); + public static final ClassName LAZY_MAP_PRODUCER = + ClassName.get("dagger.producers.internal", "LazyMapProducer"); public static final ClassName DELEGATE_FACTORY = ClassName.get("dagger.internal", "DelegateFactory"); @@ -80,6 +88,7 @@ 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 JAKARTA_PROVIDER = ClassName.get("jakarta.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 =
diff --git a/java/dagger/internal/codegen/kotlin/BUILD b/java/dagger/internal/codegen/kotlin/BUILD index 054ec89..ed750cd 100644 --- a/java/dagger/internal/codegen/kotlin/BUILD +++ b/java/dagger/internal/codegen/kotlin/BUILD
@@ -15,13 +15,16 @@ # Description: # Sources related to Kotlin metadata. -load("@rules_java//java:defs.bzl", "java_library") +load("//tools:bazel_compat.bzl", "compat_kt_jvm_library") package(default_visibility = ["//:src"]) -java_library( +compat_kt_jvm_library( name = "kotlin", - srcs = glob(["*.java"]), + srcs = glob([ + "*.java", + "*.kt", + ]), plugins = ["//java/dagger/internal/codegen/bootstrap"], tags = ["maven:merged"], deps = [ @@ -36,7 +39,7 @@ "//third_party/java/javapoet", "//third_party/java/jsr305_annotations", "//third_party/java/jsr330_inject", + "//third_party/kotlin/kotlin_metadata_jvm", "@maven//:org_jetbrains_kotlin_kotlin_stdlib", - "@maven//:org_jetbrains_kotlinx_kotlinx_metadata_jvm", ], )
diff --git a/java/dagger/internal/codegen/kotlin/ClassMetadata.kt b/java/dagger/internal/codegen/kotlin/ClassMetadata.kt new file mode 100644 index 0000000..737057b --- /dev/null +++ b/java/dagger/internal/codegen/kotlin/ClassMetadata.kt
@@ -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.internal.codegen.kotlin + +import androidx.room.compiler.processing.XAnnotation +import androidx.room.compiler.processing.XFieldElement +import androidx.room.compiler.processing.XMethodElement +import androidx.room.compiler.processing.XTypeElement +import kotlin.Metadata +import kotlin.metadata.KmClass +import kotlin.metadata.KmConstructor +import kotlin.metadata.KmFunction +import kotlin.metadata.KmProperty +import kotlin.metadata.KmValueParameter +import kotlin.metadata.jvm.KotlinClassMetadata +import kotlin.metadata.jvm.signature +import kotlin.metadata.jvm.fieldSignature +import kotlin.metadata.jvm.getterSignature +import kotlin.metadata.jvm.syntheticMethodForAnnotations + +/** Container classes for kotlin metadata types. */ +class ClassMetadata private constructor(private val kmClass: KmClass) { + val functionsBySignature = buildList<FunctionMetadata> { + addAll(kmClass.constructors.map { ConstructorMetadata(it) }) + addAll(kmClass.functions.map { MethodMetadata(it) }) + }.associateBy { it.signature } + + val propertiesBySignature = + kmClass.properties + .filter { it.fieldSignature != null } + .map { PropertyMetadata(it) } + .associateBy { it.fieldSignature } + + companion object { + /** Parse Kotlin class metadata from a given type element. */ + @JvmStatic + fun of(typeElement: XTypeElement): ClassMetadata { + val metadataAnnotation = checkNotNull(typeElement.getAnnotation(Metadata::class)).value + return when (val classMetadata = KotlinClassMetadata.readStrict(metadataAnnotation)) { + is KotlinClassMetadata.Class -> ClassMetadata(classMetadata.kmClass) + else -> error("Unsupported metadata type: ${classMetadata}") + } + } + } +} + +class ConstructorMetadata(private val kmConstructor: KmConstructor) : FunctionMetadata { + override val name = "<init>" + override val signature = kmConstructor.signature!!.toString() + override val parameters = kmConstructor.valueParameters.map { ParameterMetadata(it) } +} + +class MethodMetadata(private val kmFunction: KmFunction) : FunctionMetadata { + override val name = kmFunction.name + override val signature = kmFunction.signature!!.toString() + override val parameters = kmFunction.valueParameters.map { ParameterMetadata(it) } +} + +interface FunctionMetadata { + val name: String + val signature: String + val parameters: List<ParameterMetadata> +} + +class PropertyMetadata(private val kmProperty: KmProperty) { + val name = kmProperty.name + + /** Returns the JVM field descriptor of the backing field of this property. */ + val fieldSignature = kmProperty.fieldSignature?.toString() + + val getterSignature = kmProperty.getterSignature?.toString() + + /** Returns JVM method descriptor of the synthetic method for property annotations. */ + val methodForAnnotationsSignature = kmProperty.syntheticMethodForAnnotations?.toString() +} + +class ParameterMetadata(private val kmValueParameter: KmValueParameter) { + val name = kmValueParameter.name +}
diff --git a/java/dagger/internal/codegen/kotlin/KotlinMetadata.java b/java/dagger/internal/codegen/kotlin/KotlinMetadata.java index b27ae91..b06fd72 100644 --- a/java/dagger/internal/codegen/kotlin/KotlinMetadata.java +++ b/java/dagger/internal/codegen/kotlin/KotlinMetadata.java
@@ -19,35 +19,18 @@ import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; -import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XFieldElement; import androidx.room.compiler.processing.XMethodElement; 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.Preconditions; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import dagger.internal.codegen.extension.DaggerCollectors; -import dagger.internal.codegen.javapoet.TypeNames; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.function.Function; import javax.annotation.Nullable; -import kotlin.Metadata; -import kotlinx.metadata.Flag; -import kotlinx.metadata.KmClass; -import kotlinx.metadata.KmConstructor; -import kotlinx.metadata.KmFunction; -import kotlinx.metadata.KmProperty; -import kotlinx.metadata.jvm.JvmExtensionsKt; -import kotlinx.metadata.jvm.JvmFieldSignature; -import kotlinx.metadata.jvm.JvmMetadataUtil; -import kotlinx.metadata.jvm.JvmMethodSignature; -import kotlinx.metadata.jvm.KotlinClassMetadata; /** Data class of a TypeElement and its Kotlin metadata. */ @AutoValue @@ -107,8 +90,7 @@ } private Optional<MethodForAnnotations> getAnnotationMethodUncached(XFieldElement fieldElement) { - return findProperty(fieldElement) - .methodForAnnotationsSignature() + return Optional.ofNullable(findProperty(fieldElement).getMethodForAnnotationsSignature()) .map( signature -> Optional.ofNullable(methodDescriptors().get(signature)) @@ -125,20 +107,19 @@ } private Optional<XMethodElement> getPropertyGetterUncached(XFieldElement fieldElement) { - return findProperty(fieldElement) - .getterSignature() + return Optional.ofNullable(findProperty(fieldElement).getGetterSignature()) .flatMap(signature -> Optional.ofNullable(methodDescriptors().get(signature))); } private PropertyMetadata findProperty(XFieldElement field) { String fieldDescriptor = field.getJvmDescriptor(); - if (classMetadata().propertiesByFieldSignature().containsKey(fieldDescriptor)) { - return classMetadata().propertiesByFieldSignature().get(fieldDescriptor); + if (classMetadata().getPropertiesBySignature().containsKey(fieldDescriptor)) { + return classMetadata().getPropertiesBySignature().get(fieldDescriptor); } else { // Fallback to finding property by name, see: https://youtrack.jetbrains.com/issue/KT-35124 final String propertyName = getPropertyNameFromField(field); - return classMetadata().propertiesByFieldSignature().values().stream() - .filter(property -> propertyName.contentEquals(property.name())) + return classMetadata().getPropertiesBySignature().values().stream() + .filter(property -> propertyName.contentEquals(property.getName())) // SUPPRESS_GET_NAME_CHECK .collect(DaggerCollectors.onlyElement()); } } @@ -154,217 +135,7 @@ /** Parse Kotlin class metadata from a given type element. */ static KotlinMetadata from(XTypeElement typeElement) { - return new AutoValue_KotlinMetadata(typeElement, ClassMetadata.create(metadataOf(typeElement))); - } - - private static KotlinClassMetadata.Class metadataOf(XTypeElement typeElement) { - XAnnotation annotationMirror = typeElement.getAnnotation(TypeNames.KOTLIN_METADATA); - Preconditions.checkNotNull(annotationMirror); - Metadata metadataAnnotation = - JvmMetadataUtil.Metadata( - annotationMirror.getAsInt("k"), - annotationMirror.getAsIntList("mv").stream().mapToInt(Integer::intValue).toArray(), - annotationMirror.getAsStringList("d1").toArray(new String[0]), - annotationMirror.getAsStringList("d2").toArray(new String[0]), - annotationMirror.getAsString("xs"), - annotationMirror.getAnnotationValue("pn").hasStringValue() - ? annotationMirror.getAsString("pn") - : null, - annotationMirror.getAnnotationValue("xi").hasIntValue() - ? annotationMirror.getAsInt("xi") - : null); - KotlinClassMetadata metadata = KotlinClassMetadata.read(metadataAnnotation); - if (metadata == null) { - // Can happen if Kotlin < 1.0 or if metadata version is not supported, i.e. - // kotlinx-metadata-jvm is outdated. - throw new IllegalStateException( - "Unable to read Kotlin metadata due to unsupported metadata version."); - } - if (metadata instanceof KotlinClassMetadata.Class) { - // TODO(danysantiago): If when we need other types of metadata then move to right method. - return (KotlinClassMetadata.Class) metadata; - } else { - throw new IllegalStateException("Unsupported metadata type: " + metadata); - } - } - - @AutoValue - abstract static class ClassMetadata extends BaseMetadata { - abstract Optional<String> companionObjectName(); - - abstract ImmutableSet<FunctionMetadata> constructors(); - - abstract ImmutableMap<String, FunctionMetadata> functionsBySignature(); - - abstract ImmutableMap<String, PropertyMetadata> propertiesByFieldSignature(); - - static ClassMetadata create(KotlinClassMetadata.Class metadata) { - KmClass kmClass = metadata.toKmClass(); - ClassMetadata.Builder builder = - ClassMetadata.builder( - kmClass.getFlags(), kmClass.getName()); // // SUPPRESS_GET_NAME_CHECK - builder.companionObjectName(Optional.ofNullable(kmClass.getCompanionObject())); - kmClass.getConstructors().forEach(it -> builder.addConstructor(FunctionMetadata.create(it))); - kmClass.getFunctions().forEach(it -> builder.addFunction(FunctionMetadata.create(it))); - kmClass.getProperties().forEach(it -> builder.addProperty(PropertyMetadata.create(it))); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_ClassMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - abstract static class Builder implements BaseMetadata.Builder<Builder> { - abstract Builder companionObjectName(Optional<String> companionObjectName); - - abstract ImmutableSet.Builder<FunctionMetadata> constructorsBuilder(); - - abstract ImmutableMap.Builder<String, FunctionMetadata> functionsBySignatureBuilder(); - - abstract ImmutableMap.Builder<String, PropertyMetadata> propertiesByFieldSignatureBuilder(); - - Builder addConstructor(FunctionMetadata constructor) { - constructorsBuilder().add(constructor); - functionsBySignatureBuilder().put(constructor.signature(), constructor); - return this; - } - - Builder addFunction(FunctionMetadata function) { - functionsBySignatureBuilder().put(function.signature(), function); - return this; - } - - Builder addProperty(PropertyMetadata property) { - if (property.fieldSignature().isPresent()) { - propertiesByFieldSignatureBuilder().put(property.fieldSignature().get(), property); - } - return this; - } - - abstract ClassMetadata build(); - } - } - - @AutoValue - abstract static class FunctionMetadata extends BaseMetadata { - abstract String signature(); - - abstract ImmutableList<ValueParameterMetadata> parameters(); - - static FunctionMetadata create(KmConstructor metadata) { - FunctionMetadata.Builder builder = FunctionMetadata.builder(metadata.getFlags(), "<init>"); - metadata - .getValueParameters() - .forEach( - it -> - builder.addParameter( - ValueParameterMetadata.create( - it.getFlags(), it.getName()))); // SUPPRESS_GET_NAME_CHECK - builder.signature(Objects.requireNonNull(JvmExtensionsKt.getSignature(metadata)).asString()); - return builder.build(); - } - - static FunctionMetadata create(KmFunction metadata) { - FunctionMetadata.Builder builder = - FunctionMetadata.builder( - metadata.getFlags(), metadata.getName()); // SUPPRESS_GET_NAME_CHECK - metadata - .getValueParameters() - .forEach( - it -> - builder.addParameter( - ValueParameterMetadata.create( - it.getFlags(), it.getName()))); // SUPPRESS_GET_NAME_CHECK - builder.signature(Objects.requireNonNull(JvmExtensionsKt.getSignature(metadata)).asString()); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_FunctionMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - abstract static class Builder implements BaseMetadata.Builder<Builder> { - abstract Builder signature(String signature); - - abstract ImmutableList.Builder<ValueParameterMetadata> parametersBuilder(); - - Builder addParameter(ValueParameterMetadata parameter) { - parametersBuilder().add(parameter); - return this; - } - - abstract FunctionMetadata build(); - } - } - - @AutoValue - abstract static class PropertyMetadata extends BaseMetadata { - /** Returns the JVM field descriptor of the backing field of this property. */ - abstract Optional<String> fieldSignature(); - - abstract Optional<String> getterSignature(); - - /** Returns JVM method descriptor of the synthetic method for property annotations. */ - abstract Optional<String> methodForAnnotationsSignature(); - - static PropertyMetadata create(KmProperty metadata) { - PropertyMetadata.Builder builder = - PropertyMetadata.builder( - metadata.getFlags(), metadata.getName()); // SUPPRESS_GET_NAME_CHECK - builder.fieldSignature( - Optional.ofNullable(JvmExtensionsKt.getFieldSignature(metadata)) - .map(JvmFieldSignature::asString)); - builder.getterSignature( - Optional.ofNullable(JvmExtensionsKt.getGetterSignature(metadata)) - .map(JvmMethodSignature::asString)); - builder.methodForAnnotationsSignature( - Optional.ofNullable(JvmExtensionsKt.getSyntheticMethodForAnnotations(metadata)) - .map(JvmMethodSignature::asString)); - return builder.build(); - } - - private static Builder builder(int flags, String name) { - return new AutoValue_KotlinMetadata_PropertyMetadata.Builder().flags(flags).name(name); - } - - @AutoValue.Builder - interface Builder extends BaseMetadata.Builder<Builder> { - Builder fieldSignature(Optional<String> signature); - - Builder getterSignature(Optional<String> signature); - - Builder methodForAnnotationsSignature(Optional<String> signature); - - PropertyMetadata build(); - } - } - - @AutoValue - abstract static class ValueParameterMetadata extends BaseMetadata { - private static ValueParameterMetadata create(int flags, String name) { - return new AutoValue_KotlinMetadata_ValueParameterMetadata(flags, name); - } - } - - abstract static class BaseMetadata { - /** Returns the Kotlin metadata flags for this property. */ - abstract int flags(); - - /** returns {@code true} if the given flag (e.g. {@link Flag.IS_PRIVATE}) applies. */ - boolean flags(Flag flag) { - return flag.invoke(flags()); - } - - /** Returns the simple name of this property. */ - abstract String name(); - - interface Builder<BuilderT> { - BuilderT flags(int flags); - - BuilderT name(String name); - } + return new AutoValue_KotlinMetadata(typeElement, ClassMetadata.of(typeElement)); } @AutoValue
diff --git a/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java b/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java index 991b81a..9f80b3b 100644 --- a/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java +++ b/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java
@@ -29,7 +29,6 @@ import com.google.common.collect.ImmutableSet; import com.squareup.javapoet.ClassName; import dagger.internal.codegen.javapoet.TypeNames; -import dagger.internal.codegen.kotlin.KotlinMetadata.FunctionMetadata; import java.util.Optional; import javax.inject.Inject; @@ -86,7 +85,12 @@ public ImmutableMap<String, String> getAllMethodNamesBySignature(XTypeElement element) { checkState( hasMetadata(element), "Can not call getAllMethodNamesBySignature for non-Kotlin class"); - return metadataFactory.create(element).classMetadata().functionsBySignature().values().stream() - .collect(toImmutableMap(FunctionMetadata::signature, FunctionMetadata::name)); + return metadataFactory.create(element) + .classMetadata() + .getFunctionsBySignature().values().stream() + .collect( + toImmutableMap( + FunctionMetadata::getSignature, + FunctionMetadata::getName)); // SUPPRESS_GET_NAME_CHECK } }
diff --git a/java/dagger/internal/codegen/kythe/BUILD b/java/dagger/internal/codegen/kythe/BUILD index 217627d..09bc5c3 100644 --- a/java/dagger/internal/codegen/kythe/BUILD +++ b/java/dagger/internal/codegen/kythe/BUILD
@@ -15,7 +15,7 @@ # Description: # A library for the kythe plugin. -load("@rules_java//java:defs.bzl", "java_library") +load("@rules_java//java:defs.bzl", "java_import", "java_library") package(default_visibility = ["//:src"]) @@ -41,8 +41,6 @@ ], ) -load("@rules_java//java:defs.bzl", "java_import") - # A _deploy.jar consisting of the java_librarys in https://github.com/kythe/kythe needed to build a # Kythe plugin # TODO(ronshapiro): replace this with a http_archive of the next release in
diff --git a/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java b/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java index 0b8a502..a558f94 100644 --- a/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java +++ b/java/dagger/internal/codegen/kythe/DaggerKythePlugin.java
@@ -37,10 +37,10 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import dagger.Component; 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.ComponentDescriptor; +import dagger.internal.codegen.binding.Declaration; import dagger.internal.codegen.binding.ModuleDescriptor; import dagger.internal.codegen.javac.JavacPluginModule; import dagger.internal.codegen.javapoet.TypeNames; @@ -99,7 +99,7 @@ /** * Add {@code /inject/satisfiedby} edges from {@code dependency}'s {@link - * DependencyRequest#requestElement()} to any {@link BindingDeclaration#bindingElement() binding + * DependencyRequest#requestElement()} to any {@link Declaration#bindingElement() binding * elements} that satisfy the request. * * <p>This collapses requests for synthetic bindings so that a request for a multibound key @@ -122,18 +122,18 @@ } } } - for (BindingDeclaration bindingDeclaration : + for (Declaration declaration : Iterables.concat( bindingNode.multibindingDeclarations(), bindingNode.optionalBindingDeclarations())) { - addDependencyEdge(dependency, bindingDeclaration); + addDependencyEdge(dependency, declaration); } } private void addDependencyEdge( - DependencyRequest dependency, BindingDeclaration bindingDeclaration) { + DependencyRequest dependency, Declaration declaration) { XElement requestElement = dependency.requestElement().get().xprocessing(); - XElement bindingElement = bindingDeclaration.bindingElement().get(); + XElement bindingElement = declaration.bindingElement().get(); Optional<VName> requestElementNode = jvmNode(requestElement, "request element"); Optional<VName> bindingElementNode = jvmNode(bindingElement, "binding element"); emitEdge(requestElementNode, "/inject/satisfiedby", bindingElementNode);
diff --git a/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java b/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java index ebd5d10..3d4c11b 100644 --- a/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/AssistedFactoryProcessingStep.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.processingstep; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedFactoryMethods; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedInjectedConstructors; @@ -57,14 +58,14 @@ import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; -import dagger.internal.codegen.base.SourceFileGenerationException; import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.binding.AssistedFactoryBinding; import dagger.internal.codegen.binding.AssistedInjectionAnnotations; import dagger.internal.codegen.binding.AssistedInjectionAnnotations.AssistedFactoryMetadata; import dagger.internal.codegen.binding.AssistedInjectionAnnotations.AssistedParameter; +import dagger.internal.codegen.binding.AssistedInjectionBinding; import dagger.internal.codegen.binding.BindingFactory; import dagger.internal.codegen.binding.MethodSignatureFormatter; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.validation.ValidationReport; import dagger.internal.codegen.xprocessing.XTypes; @@ -110,12 +111,8 @@ ValidationReport report = new AssistedFactoryValidator().validate(factory); report.printMessagesTo(messager); if (report.isClean()) { - try { - ProvisionBinding binding = bindingFactory.assistedFactoryBinding(factory, Optional.empty()); - new AssistedFactoryImplGenerator().generate(binding); - } catch (SourceFileGenerationException e) { - e.printMessageTo(messager); - } + new AssistedFactoryImplGenerator() + .generate(bindingFactory.assistedFactoryBinding(factory, Optional.empty())); } } @@ -230,13 +227,14 @@ } /** Generates an implementation of the {@link dagger.assisted.AssistedFactory}-annotated class. */ - private final class AssistedFactoryImplGenerator extends SourceFileGenerator<ProvisionBinding> { + private final class AssistedFactoryImplGenerator + extends SourceFileGenerator<AssistedFactoryBinding> { AssistedFactoryImplGenerator() { super(filer, processingEnv); } @Override - public XElement originatingElement(ProvisionBinding binding) { + public XElement originatingElement(AssistedFactoryBinding binding) { return binding.bindingElement().get(); } @@ -273,10 +271,10 @@ // } // } @Override - public ImmutableList<TypeSpec.Builder> topLevelTypes(ProvisionBinding binding) { + public ImmutableList<TypeSpec.Builder> topLevelTypes(AssistedFactoryBinding binding) { XTypeElement factory = asTypeElement(binding.bindingElement().get()); - ClassName name = generatedClassNameForBinding(binding); + ClassName name = toJavaPoet(generatedClassNameForBinding(binding)); TypeSpec.Builder builder = TypeSpec.classBuilder(name) .addModifiers(PUBLIC, FINAL) @@ -363,13 +361,14 @@ /** Returns the generated factory {@link TypeName type} for an @AssistedInject constructor. */ private TypeName delegateFactoryTypeName(XType assistedInjectType) { + AssistedInjectionBinding binding = + bindingFactory.assistedInjectionBinding( + getOnlyElement(assistedInjectedConstructors(assistedInjectType.getTypeElement())), + Optional.empty()); + // The name of the generated factory for the assisted inject type, // e.g. an @AssistedInject Foo(...) {...} constructor will generate a Foo_Factory class. - ClassName generatedFactoryClassName = - generatedClassNameForBinding( - bindingFactory.injectionBinding( - getOnlyElement(assistedInjectedConstructors(assistedInjectType.getTypeElement())), - Optional.empty())); + ClassName generatedFactoryClassName = toJavaPoet(generatedClassNameForBinding(binding)); // Return the factory type resolved with the same type parameters as the assisted inject type. return assistedInjectType.getTypeArguments().isEmpty()
diff --git a/java/dagger/internal/codegen/processingstep/LazyClassKeyProcessingStep.java b/java/dagger/internal/codegen/processingstep/LazyClassKeyProcessingStep.java new file mode 100644 index 0000000..1843c19 --- /dev/null +++ b/java/dagger/internal/codegen/processingstep/LazyClassKeyProcessingStep.java
@@ -0,0 +1,150 @@ +/* + * 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.processingstep; + +import static androidx.room.compiler.processing.XElementKt.isTypeElement; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.stream.Collectors.joining; + +import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XFiler; +import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XTypeElement; +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.SetMultimap; +import com.squareup.javapoet.ClassName; +import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.writing.LazyMapKeyProxyGenerator; +import dagger.internal.codegen.xprocessing.XElements; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.nio.file.Path; +import java.util.Map; +import java.util.Set; +import javax.inject.Inject; + +/** Generate keep rules for LazyClassKey referenced classes to prevent class merging. */ +final class LazyClassKeyProcessingStep extends TypeCheckingProcessingStep<XElement> { + private static final String PROGUARD_KEEP_RULE = "-keep,allowobfuscation,allowshrinking class "; + + // Note: We aggregate @LazyClassKey usages across processing rounds, so we use ClassName instead + // of XElement as the map key to avoid storing XElement instances across processing rounds. + private final SetMultimap<ClassName, ClassName> lazyMapKeysByModule = LinkedHashMultimap.create(); + private final LazyMapKeyProxyGenerator lazyMapKeyProxyGenerator; + + @Inject + LazyClassKeyProcessingStep(LazyMapKeyProxyGenerator lazyMapKeyProxyGenerator) { + this.lazyMapKeyProxyGenerator = lazyMapKeyProxyGenerator; + } + + @Override + public ImmutableSet<ClassName> annotationClassNames() { + return ImmutableSet.of(TypeNames.LAZY_CLASS_KEY); + } + + @Override + protected void process(XElement element, ImmutableSet<ClassName> annotations) { + ClassName lazyClassKey = + element + .getAnnotation(TypeNames.LAZY_CLASS_KEY) + .getAsType("value") + .getTypeElement() + .getClassName(); + // No need to fail, since we want to support customized usage of class key annotations. + // https://github.com/google/dagger/pull/2831 + if (!isMapBinding(element) || !isModuleOrProducerModule(element.getEnclosingElement())) { + return; + } + XTypeElement moduleElement = XElements.asTypeElement(element.getEnclosingElement()); + lazyMapKeysByModule.put(moduleElement.getClassName(), lazyClassKey); + XMethodElement method = XElements.asMethod(element); + lazyMapKeyProxyGenerator.generate(method); + } + + private static boolean isMapBinding(XElement element) { + return element.hasAnnotation(TypeNames.INTO_MAP) + && (element.hasAnnotation(TypeNames.BINDS) + || element.hasAnnotation(TypeNames.PROVIDES) + || element.hasAnnotation(TypeNames.PRODUCES)); + } + + private static boolean isModuleOrProducerModule(XElement element) { + return isTypeElement(element) + && (element.hasAnnotation(TypeNames.MODULE) + || element.hasAnnotation(TypeNames.PRODUCER_MODULE)); + } + + // TODO(b/386393062): Avoid generating proguard files in processOver. + @Override + public void processOver( + XProcessingEnv env, Map<String, ? extends Set<? extends XElement>> elementsByAnnotation) { + super.processOver(env, elementsByAnnotation); + lazyMapKeysByModule + .asMap() + .forEach( + (moduleClassName, lazyClassKeys) -> { + // Note: we could probably get better incremental performance by using the method + // element instead of the module element as the originating element. However, that + // would require appending the method name to each proguard file, which would probably + // cause issues with the filename length limit (256 characters) given it already must + // include the module's fully qualified name. + XTypeElement originatingElement = + env.requireTypeElement(moduleClassName.canonicalName()); + + Path proguardFile = + Path.of( + "META-INF/proguard", + getFullyQualifiedEnclosedClassName(moduleClassName) + "_LazyClassKeys.pro"); + + String proguardFileContents = + lazyClassKeys.stream() + .map(lazyClassKey -> PROGUARD_KEEP_RULE + lazyClassKey.canonicalName()) + .collect(joining("\n")); + + writeResource(env.getFiler(), originatingElement, proguardFile, proguardFileContents); + }); + // Processing is over so this shouldn't matter, but clear the map just incase. + lazyMapKeysByModule.clear(); + } + + private void writeResource( + XFiler filer, XElement originatingElement, Path path, String contents) { + try (OutputStream outputStream = + filer.writeResource(path, ImmutableList.of(originatingElement), XFiler.Mode.Isolating); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, UTF_8))) { + writer.write(contents); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + /** Returns the fully qualified class name, with _ instead of . */ + private static String getFullyQualifiedEnclosedClassName(ClassName className) { + return Joiner.on('_') + .join( + ImmutableList.<String>builder() + .add(className.packageName().replace('.', '_')) + .addAll(className.simpleNames()) + .build()); + } +}
diff --git a/java/dagger/internal/codegen/processingstep/ModuleProcessingStep.java b/java/dagger/internal/codegen/processingstep/ModuleProcessingStep.java index 1df14ec..72e2064 100644 --- a/java/dagger/internal/codegen/processingstep/ModuleProcessingStep.java +++ b/java/dagger/internal/codegen/processingstep/ModuleProcessingStep.java
@@ -33,7 +33,6 @@ import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.DelegateDeclaration; import dagger.internal.codegen.binding.ProductionBinding; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.validation.ModuleValidator; import dagger.internal.codegen.validation.ValidationReport; @@ -51,7 +50,7 @@ private final XMessager messager; private final ModuleValidator moduleValidator; private final BindingFactory bindingFactory; - private final SourceFileGenerator<ProvisionBinding> factoryGenerator; + private final SourceFileGenerator<ContributionBinding> factoryGenerator; private final SourceFileGenerator<ProductionBinding> producerFactoryGenerator; private final SourceFileGenerator<XTypeElement> moduleConstructorProxyGenerator; private final InaccessibleMapKeyProxyGenerator inaccessibleMapKeyProxyGenerator; @@ -63,7 +62,7 @@ XMessager messager, ModuleValidator moduleValidator, BindingFactory bindingFactory, - SourceFileGenerator<ProvisionBinding> factoryGenerator, + SourceFileGenerator<ContributionBinding> factoryGenerator, SourceFileGenerator<ProductionBinding> producerFactoryGenerator, @ModuleGenerator SourceFileGenerator<XTypeElement> moduleConstructorProxyGenerator, InaccessibleMapKeyProxyGenerator inaccessibleMapKeyProxyGenerator,
diff --git a/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java b/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java index 3692144..362992b 100644 --- a/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java +++ b/java/dagger/internal/codegen/processingstep/MonitoringModuleGenerator.java
@@ -16,9 +16,11 @@ package dagger.internal.codegen.processingstep; +import static androidx.room.compiler.codegen.compat.XConverters.toJavaPoet; 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.SourceFiles.generatedMonitoringModuleName; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCTION_COMPONENT_MONITOR_FACTORY; import static dagger.internal.codegen.javapoet.TypeNames.providerOf; import static dagger.internal.codegen.javapoet.TypeNames.setOf; @@ -31,12 +33,12 @@ import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XTypeElement; import com.google.common.collect.ImmutableList; +import com.squareup.javapoet.ClassName; 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; import javax.inject.Inject; @@ -61,9 +63,10 @@ @Override public ImmutableList<TypeSpec.Builder> topLevelTypes(XTypeElement componentElement) { - monitoringModules.add(SourceFiles.generatedMonitoringModuleName(componentElement)); + ClassName name = toJavaPoet(generatedMonitoringModuleName(componentElement)); + monitoringModules.add(name); return ImmutableList.of( - classBuilder(SourceFiles.generatedMonitoringModuleName(componentElement)) + classBuilder(name) .addAnnotation(Module.class) .addModifiers(ABSTRACT) .addMethod(privateConstructor())
diff --git a/java/dagger/internal/codegen/processingstep/ProcessingStepsModule.java b/java/dagger/internal/codegen/processingstep/ProcessingStepsModule.java index e24dddc..f180c3d 100644 --- a/java/dagger/internal/codegen/processingstep/ProcessingStepsModule.java +++ b/java/dagger/internal/codegen/processingstep/ProcessingStepsModule.java
@@ -39,6 +39,7 @@ MultibindingAnnotationsProcessingStep multibindingAnnotationsProcessingStep, BindsInstanceProcessingStep bindsInstanceProcessingStep, ModuleProcessingStep moduleProcessingStep, + LazyClassKeyProcessingStep lazyClassKeyProcessingStep, ComponentProcessingStep componentProcessingStep, ComponentHjarProcessingStep componentHjarProcessingStep, BindingMethodProcessingStep bindingMethodProcessingStep, @@ -53,9 +54,8 @@ multibindingAnnotationsProcessingStep, bindsInstanceProcessingStep, moduleProcessingStep, - compilerOptions.headerCompilation() - ? componentHjarProcessingStep - : componentProcessingStep, + lazyClassKeyProcessingStep, + compilerOptions.headerCompilation() ? componentHjarProcessingStep : componentProcessingStep, bindingMethodProcessingStep); }
diff --git a/java/dagger/internal/codegen/validation/BindingElementValidator.java b/java/dagger/internal/codegen/validation/BindingElementValidator.java index c7c9f76..93f4f07 100644 --- a/java/dagger/internal/codegen/validation/BindingElementValidator.java +++ b/java/dagger/internal/codegen/validation/BindingElementValidator.java
@@ -42,6 +42,7 @@ import dagger.internal.codegen.model.Key; import dagger.internal.codegen.model.Scope; import dagger.internal.codegen.xprocessing.XElements; +import dagger.internal.codegen.xprocessing.XTypes; import java.util.Formatter; import java.util.HashMap; import java.util.Map; @@ -144,7 +145,7 @@ checkType(); checkQualifiers(); checkMapKeys(); - checkMultibindings(); + checkMultibindingAnnotations(); checkScopes(); checkAdditionalProperties(); return report.build(); @@ -176,6 +177,9 @@ protected void checkType() { switch (ContributionType.fromBindingElement(element)) { case UNIQUE: + // Basic checks on the types + bindingElementType().ifPresent(this::checkKeyType); + // Validate that a unique binding is not attempting to bind a framework type. This // validation is only appropriate for unique bindings because multibindings may collect // framework types. E.g. Set<Provider<Foo>> is perfectly reasonable. @@ -185,15 +189,22 @@ // This validation is only appropriate for unique bindings because multibindings may // collect assisted types. checkAssistedType(); - // fall through + + // Check for any specifically disallowed types + bindingElementType().ifPresent(this::checkDisallowedType); + break; case SET: + bindingElementType().ifPresent(this::checkSetValueFrameworkType); + break; + case MAP: - bindingElementType().ifPresent(this::checkKeyType); + bindingElementType().ifPresent(this::checkMapValueFrameworkType); break; case SET_VALUES: checkSetValuesType(); + break; } } @@ -245,7 +256,7 @@ if (setType.isRawType()) { report.addError(elementsIntoSetRawSetMessage()); } else { - checkKeyType(setType.elementType()); + checkSetValueFrameworkType(setType.elementType()); } } } @@ -301,7 +312,7 @@ * dagger.producers.Produces} annotation has a {@code type} parameter. * </ul> */ - private void checkMultibindings() { + private void checkMultibindingAnnotations() { ImmutableSet<XAnnotation> multibindingAnnotations = XElements.getAllAnnotations(element, MULTIBINDING_ANNOTATIONS); @@ -358,7 +369,37 @@ */ private void checkFrameworkType() { if (bindingElementType().filter(FrameworkTypes::isFrameworkType).isPresent()) { - report.addError(bindingElements("must not %s framework types", bindingElementTypeVerb())); + report.addError(bindingElements("must not %s framework types: %s", + bindingElementTypeVerb(), XTypes.toStableString(bindingElementType().get()))); + } + } + + private void checkSetValueFrameworkType(XType bindingType) { + checkKeyType(bindingType); + if (FrameworkTypes.isSetValueFrameworkType(bindingType)) { + report.addError(bindingElements( + "with @IntoSet/@ElementsIntoSet must not %s framework types: %s", + bindingElementTypeVerb(), XTypes.toStableString(bindingType))); + } + checkDisallowedType(bindingType); + } + + private void checkMapValueFrameworkType(XType bindingType) { + checkKeyType(bindingType); + if (FrameworkTypes.isMapValueFrameworkType(bindingType)) { + report.addError( + bindingElements("with @IntoMap must not %s framework types: %s", + bindingElementTypeVerb(), XTypes.toStableString(bindingType))); + } + checkDisallowedType(bindingType); + } + + private void checkDisallowedType(XType bindingType) { + // TODO(erichang): Consider if we want to go inside complex types to ban + // dagger.internal.Provider as well? E.g. List<dagger.internal.Provider<Foo>> + if (FrameworkTypes.isDisallowedType(bindingType)) { + report.addError(bindingElements("must not %s disallowed types: %s", + bindingElementTypeVerb(), XTypes.toStableString(bindingElementType().get()))); } } }
diff --git a/java/dagger/internal/codegen/validation/BindsMethodValidator.java b/java/dagger/internal/codegen/validation/BindsMethodValidator.java index c3ad90a..1af35ce 100644 --- a/java/dagger/internal/codegen/validation/BindsMethodValidator.java +++ b/java/dagger/internal/codegen/validation/BindsMethodValidator.java
@@ -33,6 +33,7 @@ import dagger.internal.codegen.binding.BindsTypeChecker; import dagger.internal.codegen.binding.InjectionAnnotations; import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.xprocessing.Nullability; import javax.inject.Inject; /** A validator for {@link dagger.Binds} methods. */ @@ -45,7 +46,6 @@ BindsTypeChecker bindsTypeChecker, DaggerSuperficialValidation superficialValidation, XProcessingEnv processingEnv, - DependencyRequestValidator dependencyRequestValidator, InjectionAnnotations injectionAnnotations) { super( @@ -110,6 +110,12 @@ // Set.addAll(Collection<? extends E>) report.addError("@Binds methods' parameter type must be assignable to the return type"); } + + Nullability parameterNullability = Nullability.of(parameter); + Nullability methodNullability = Nullability.of(method); + if (parameterNullability.isNullable() != methodNullability.isNullable()) { + report.addError("@Binds methods' nullability must match the nullability of its parameter"); + } } private XType boxIfNecessary(XType maybePrimitive) {
diff --git a/java/dagger/internal/codegen/validation/DependencyRequestValidator.java b/java/dagger/internal/codegen/validation/DependencyRequestValidator.java index 5510048..87bcad0 100644 --- a/java/dagger/internal/codegen/validation/DependencyRequestValidator.java +++ b/java/dagger/internal/codegen/validation/DependencyRequestValidator.java
@@ -18,7 +18,9 @@ import static androidx.room.compiler.processing.XElementKt.isField; import static androidx.room.compiler.processing.XElementKt.isTypeElement; +import static dagger.internal.codegen.base.FrameworkTypes.isDisallowedType; import static dagger.internal.codegen.base.FrameworkTypes.isFrameworkType; +import static dagger.internal.codegen.base.FrameworkTypes.isMapValueFrameworkType; import static dagger.internal.codegen.base.RequestKinds.extractKeyType; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedFactoryType; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedInjectionType; @@ -40,6 +42,7 @@ import androidx.room.compiler.processing.XVariableElement; import com.google.common.collect.ImmutableSet; import dagger.internal.codegen.base.FrameworkTypes; +import dagger.internal.codegen.base.MapType; import dagger.internal.codegen.base.RequestKinds; import dagger.internal.codegen.binding.InjectionAnnotations; import dagger.internal.codegen.javapoet.TypeNames; @@ -154,6 +157,14 @@ // will just be noise. return; } + if (isDisallowedType(requestType)) { + report.addError( + "Dagger disallows injecting the type: " + XTypes.toStableString(requestType), + requestElement); + // If the requested type is a disallowed type then skip the remaining checks as they + // will just be noise. + return; + } XType keyType = extractKeyType(requestType); if (qualifiers.isEmpty() && isDeclared(keyType)) { XTypeElement typeElement = keyType.getTypeElement(); @@ -191,6 +202,24 @@ requestElement, keyType.getTypeArguments().get(0))); } } + if (MapType.isMap(keyType)) { + MapType mapType = MapType.from(keyType); + if (!mapType.isRawType()) { + XType valueType = mapType.valueType(); + if (isMapValueFrameworkType(valueType) && isRawParameterizedType(valueType)) { + report.addError( + "Dagger does not support injecting maps of raw framework types: " + + XTypes.toStableString(requestType), + requestElement); + } + if (isDisallowedType(valueType)) { + report.addError( + "Dagger does not support injecting maps of disallowed types: " + + XTypes.toStableString(requestType), + requestElement); + } + } + } } }
diff --git a/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java b/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java index 24ad676..3f63d25 100644 --- a/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java +++ b/java/dagger/internal/codegen/validation/DiagnosticMessageGenerator.java
@@ -165,9 +165,9 @@ ImmutableSet<DependencyEdge> requests, ImmutableSet<DependencyEdge> entryPoints) { StringBuilder message = new StringBuilder(dependencyTrace.size() * 100 /* a guess heuristic */); - dependencyTrace.forEach( - edge -> dependencyRequestFormatter.appendFormatLine(message, edge.dependencyRequest())); + message.append("\n"); if (!dependencyTrace.isEmpty()) { + message.append(dependencyRequestFormatter.formatEdges(dependencyTrace, graph)); appendComponentPathUnlessAtRoot(message, source(getLast(dependencyTrace))); } message.append(getRequestsNotInTrace(dependencyTrace, requests, entryPoints)); @@ -257,7 +257,7 @@ // TODO(ronshapiro): Adding a DependencyPath type to dagger.internal.codegen.model could be // useful, i.e. // bindingGraph.shortestPathFromEntryPoint(DependencyEdge, MaybeBindingNode) - public ImmutableList<DependencyEdge> dependencyTrace( + private ImmutableList<DependencyEdge> dependencyTrace( MaybeBinding binding, ImmutableSet<DependencyEdge> entryPoints) { // Module binding graphs may have bindings unreachable from any entry points. If there are // no entry points for this DiagnosticInfo, don't try to print a dependency trace.
diff --git a/java/dagger/internal/codegen/validation/ExternalBindingGraphPlugins.java b/java/dagger/internal/codegen/validation/ExternalBindingGraphPlugins.java index ba8e6a0..c11457c 100644 --- a/java/dagger/internal/codegen/validation/ExternalBindingGraphPlugins.java +++ b/java/dagger/internal/codegen/validation/ExternalBindingGraphPlugins.java
@@ -84,6 +84,10 @@ plugin.init(SpiModelBindingGraphConverter.toSpiModel(processingEnv), filteredOptions); } + public void onProcessingRoundBegin() { + plugins.forEach(BindingGraphPlugin::onProcessingRoundBegin); + } + private void initializeLegacyPlugin(dagger.spi.BindingGraphPlugin plugin) { plugin.initFiler(toJavac(filer)); plugin.initTypes(toJavac(processingEnv).getTypeUtils()); // ALLOW_TYPES_ELEMENTS
diff --git a/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java b/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java index 16344d3..ab2a571 100644 --- a/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java +++ b/java/dagger/internal/codegen/validation/InjectBindingRegistryImpl.java
@@ -24,6 +24,7 @@ import static dagger.internal.codegen.base.Keys.isValidImplicitProvisionKey; import static dagger.internal.codegen.base.Keys.isValidMembersInjectionKey; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedInjectedConstructors; +import static dagger.internal.codegen.binding.InjectionAnnotations.hasInjectAnnotation; import static dagger.internal.codegen.binding.InjectionAnnotations.injectedConstructors; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; @@ -50,12 +51,15 @@ import dagger.Provides; import dagger.internal.codegen.base.SourceFileGenerationException; import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.binding.AssistedInjectionBinding; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingFactory; +import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.InjectBindingRegistry; +import dagger.internal.codegen.binding.InjectionBinding; import dagger.internal.codegen.binding.KeyFactory; import dagger.internal.codegen.binding.MembersInjectionBinding; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.MembersInjectorBinding; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.Key; @@ -80,7 +84,6 @@ private final XProcessingEnv processingEnv; private final XMessager messager; private final InjectValidator injectValidator; - private final InjectValidator injectValidatorWhenGeneratingCode; private final KeyFactory keyFactory; private final BindingFactory bindingFactory; private final CompilerOptions compilerOptions; @@ -102,7 +105,7 @@ checkState(!binding.unresolved().isPresent()); XType type = binding.key().type().xprocessing(); if (!isDeclared(type) - || injectValidatorWhenGeneratingCode.validate(type.getTypeElement()).isClean()) { + || injectValidator.validateWhenGeneratingCode(type.getTypeElement()).isClean()) { generator.generate(binding); } materializedBindingKeys.add(binding.key()); @@ -203,7 +206,7 @@ } } - private final BindingsCollection<ProvisionBinding> provisionBindings = + private final BindingsCollection<ContributionBinding> injectionBindings = new BindingsCollection<>(TypeNames.PROVIDER); private final BindingsCollection<MembersInjectionBinding> membersInjectionBindings = new BindingsCollection<>(TypeNames.MEMBERS_INJECTOR); @@ -219,7 +222,6 @@ this.processingEnv = processingEnv; this.messager = messager; this.injectValidator = injectValidator; - this.injectValidatorWhenGeneratingCode = injectValidator.whenGeneratingCode(); this.keyFactory = keyFactory; this.bindingFactory = bindingFactory; this.compilerOptions = compilerOptions; @@ -228,15 +230,15 @@ // TODO(dpb): make the SourceFileGenerators fields so they don't have to be passed in @Override public void generateSourcesForRequiredBindings( - SourceFileGenerator<ProvisionBinding> factoryGenerator, + SourceFileGenerator<ContributionBinding> factoryGenerator, SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator) throws SourceFileGenerationException { - provisionBindings.generateBindings(factoryGenerator); + injectionBindings.generateBindings(factoryGenerator); membersInjectionBindings.generateBindings(membersInjectorGenerator); } @Override - public Optional<ProvisionBinding> tryRegisterInjectConstructor( + public Optional<ContributionBinding> tryRegisterInjectConstructor( XConstructorElement constructorElement) { return tryRegisterConstructor( constructorElement, @@ -245,7 +247,7 @@ } @CanIgnoreReturnValue - private Optional<ProvisionBinding> tryRegisterConstructor( + private Optional<ContributionBinding> tryRegisterConstructor( XConstructorElement constructorElement, Optional<XType> resolvedType, boolean isCalledFromInjectProcessor) { @@ -260,17 +262,30 @@ XType type = typeElement.getType(); Key key = keyFactory.forInjectConstructorWithResolvedType(type); - ProvisionBinding cachedBinding = provisionBindings.getBinding(key); + ContributionBinding cachedBinding = injectionBindings.getBinding(key); if (cachedBinding != null) { return Optional.of(cachedBinding); } - ProvisionBinding binding = bindingFactory.injectionBinding(constructorElement, resolvedType); - provisionBindings.tryRegisterBinding(binding, isCalledFromInjectProcessor); - if (!binding.injectionSites().isEmpty()) { - tryRegisterMembersInjectedType(typeElement, resolvedType, isCalledFromInjectProcessor); + if (hasInjectAnnotation(constructorElement)) { + InjectionBinding binding = bindingFactory.injectionBinding(constructorElement, resolvedType); + injectionBindings.tryRegisterBinding(binding, isCalledFromInjectProcessor); + if (!binding.injectionSites().isEmpty()) { + tryRegisterMembersInjectedType(typeElement, resolvedType, isCalledFromInjectProcessor); + } + return Optional.of(binding); + } else if (constructorElement.hasAnnotation(TypeNames.ASSISTED_INJECT)) { + AssistedInjectionBinding binding = + bindingFactory.assistedInjectionBinding(constructorElement, resolvedType); + injectionBindings.tryRegisterBinding(binding, isCalledFromInjectProcessor); + if (!binding.injectionSites().isEmpty()) { + tryRegisterMembersInjectedType(typeElement, resolvedType, isCalledFromInjectProcessor); + } + return Optional.of(binding); } - return Optional.of(binding); + throw new AssertionError( + "Expected either an @Inject or @AssistedInject annotated constructor: " + + constructorElement.getEnclosingElement().getQualifiedName()); } @Override @@ -336,12 +351,12 @@ @CanIgnoreReturnValue @Override - public Optional<ProvisionBinding> getOrFindProvisionBinding(Key key) { + public Optional<ContributionBinding> getOrFindInjectionBinding(Key key) { checkNotNull(key); if (!isValidImplicitProvisionKey(key)) { return Optional.empty(); } - ProvisionBinding binding = provisionBindings.getBinding(key); + ContributionBinding binding = injectionBindings.getBinding(key); if (binding != null) { return Optional.of(binding); } @@ -385,7 +400,7 @@ } @Override - public Optional<ProvisionBinding> getOrFindMembersInjectorProvisionBinding(Key key) { + public Optional<MembersInjectorBinding> getOrFindMembersInjectorBinding(Key key) { if (!isValidMembersInjectionKey(key)) { return Optional.empty(); }
diff --git a/java/dagger/internal/codegen/validation/InjectValidator.java b/java/dagger/internal/codegen/validation/InjectValidator.java index ac434d7..135839d 100644 --- a/java/dagger/internal/codegen/validation/InjectValidator.java +++ b/java/dagger/internal/codegen/validation/InjectValidator.java
@@ -56,7 +56,6 @@ import javax.inject.Inject; import javax.inject.Singleton; import javax.tools.Diagnostic; -import javax.tools.Diagnostic.Kind; /** * A {@linkplain ValidationReport validator} for {@link Inject}-annotated elements and the types @@ -66,14 +65,12 @@ public final class InjectValidator implements ClearableCache { private final XProcessingEnv processingEnv; - private final CompilerOptions compilerOptions; private final DependencyRequestValidator dependencyRequestValidator; - private final Optional<Diagnostic.Kind> privateAndStaticInjectionDiagnosticKind; private final InjectionAnnotations injectionAnnotations; private final DaggerSuperficialValidation superficialValidation; - private final Map<XTypeElement, ValidationReport> provisionReports = new HashMap<>(); - private final Map<XTypeElement, ValidationReport> membersInjectionReports = new HashMap<>(); private final MethodSignatureFormatter methodSignatureFormatter; + private final InternalValidator validator; + private final InternalValidator validatorWhenGeneratingCode; @Inject InjectValidator( @@ -83,378 +80,390 @@ InjectionAnnotations injectionAnnotations, DaggerSuperficialValidation superficialValidation, MethodSignatureFormatter methodSignatureFormatter) { - this( - processingEnv, - compilerOptions, - dependencyRequestValidator, - Optional.empty(), - injectionAnnotations, - superficialValidation, - methodSignatureFormatter); - } - - private InjectValidator( - XProcessingEnv processingEnv, - CompilerOptions compilerOptions, - DependencyRequestValidator dependencyRequestValidator, - Optional<Kind> privateAndStaticInjectionDiagnosticKind, - InjectionAnnotations injectionAnnotations, - DaggerSuperficialValidation superficialValidation, - MethodSignatureFormatter methodSignatureFormatter) { this.processingEnv = processingEnv; - this.compilerOptions = compilerOptions; this.dependencyRequestValidator = dependencyRequestValidator; - this.privateAndStaticInjectionDiagnosticKind = privateAndStaticInjectionDiagnosticKind; this.injectionAnnotations = injectionAnnotations; this.superficialValidation = superficialValidation; this.methodSignatureFormatter = methodSignatureFormatter; + + // When validating types that require a generated factory class we need to error on private and + // static inject members even if the compiler options are set to not error. + this.validatorWhenGeneratingCode = + new InternalValidator(Diagnostic.Kind.ERROR, Diagnostic.Kind.ERROR); + + // When validating types that might not require a generated factory we can take the user flags + // for private and static inject members into account, but try to reuse the existing one if the + // diagnostic kinds are the same. + this.validator = + (compilerOptions.privateMemberValidationKind() == Diagnostic.Kind.ERROR + && compilerOptions.staticMemberValidationKind() == Diagnostic.Kind.ERROR) + ? validatorWhenGeneratingCode + : new InternalValidator( + compilerOptions.privateMemberValidationKind(), + compilerOptions.staticMemberValidationKind()); } @Override public void clearCache() { - provisionReports.clear(); - membersInjectionReports.clear(); - } - - /** - * Returns a new validator that performs the same validation as this one, but is strict about - * rejecting optionally-specified JSR 330 behavior that Dagger doesn't support (unless {@code - * -Adagger.ignorePrivateAndStaticInjectionForComponent=enabled} was set in the javac options). - */ - public InjectValidator whenGeneratingCode() { - return compilerOptions.ignorePrivateAndStaticInjectionForComponent() - ? this - : new InjectValidator( - processingEnv, - compilerOptions, - dependencyRequestValidator, - Optional.of(Diagnostic.Kind.ERROR), - injectionAnnotations, - superficialValidation, - methodSignatureFormatter); + validator.clearCache(); + validatorWhenGeneratingCode.clearCache(); } public ValidationReport validate(XTypeElement typeElement) { - return reentrantComputeIfAbsent(provisionReports, typeElement, this::validateUncached); - } - - private ValidationReport validateUncached(XTypeElement typeElement) { - ValidationReport.Builder builder = ValidationReport.about(typeElement); - builder.addSubreport(validateForMembersInjectionInternal(typeElement)); - - ImmutableSet<XConstructorElement> injectConstructors = - ImmutableSet.<XConstructorElement>builder() - .addAll(injectedConstructors(typeElement)) - .addAll(assistedInjectedConstructors(typeElement)) - .build(); - - switch (injectConstructors.size()) { - case 0: - break; // Nothing to validate. - case 1: - builder.addSubreport(validateConstructor(getOnlyElement(injectConstructors))); - break; - default: - builder.addError( - String.format( - "Type %s may only contain one injected constructor. Found: %s", - typeElement.getQualifiedName(), - injectConstructors.stream() - .map(methodSignatureFormatter::format) - .collect(toImmutableList())), - typeElement); - } - - return builder.build(); - } - - private ValidationReport validateConstructor(XConstructorElement constructorElement) { - superficialValidation.validateTypeOf(constructorElement); - ValidationReport.Builder builder = - ValidationReport.about(constructorElement.getEnclosingElement()); - - if (InjectionAnnotations.hasInjectAnnotation(constructorElement) - && constructorElement.hasAnnotation(TypeNames.ASSISTED_INJECT)) { - builder.addError("Constructors cannot be annotated with both @Inject and @AssistedInject"); - } - - ClassName injectAnnotation = - getAnyAnnotation( - constructorElement, - TypeNames.INJECT, - TypeNames.INJECT_JAVAX, - TypeNames.ASSISTED_INJECT) - .map(XAnnotations::getClassName) - .get(); - - if (constructorElement.isPrivate()) { - builder.addError( - "Dagger does not support injection into private constructors", constructorElement); - } - - // If this type has already been processed in a previous round or compilation unit then there - // is no reason to recheck for invalid scope annotations since it's already been checked. - // This allows us to skip superficial validation of constructor annotations in subsequent - // compilations where the annotation types may no longer be on the classpath. - if (!processedInPreviousRoundOrCompilationUnit(constructorElement)) { - superficialValidation.validateAnnotationsOf(constructorElement); - for (XAnnotation qualifier : injectionAnnotations.getQualifiers(constructorElement)) { - builder.addError( - String.format( - "@Qualifier annotations are not allowed on @%s constructors", - injectAnnotation.simpleName()), - constructorElement, - qualifier); - } - - String scopeErrorMsg = - String.format( - "@Scope annotations are not allowed on @%s constructors", - injectAnnotation.simpleName()); - - if (injectAnnotation.equals(TypeNames.INJECT) - || injectAnnotation.equals(TypeNames.INJECT_JAVAX)) { - scopeErrorMsg += "; annotate the class instead"; - } - - for (Scope scope : injectionAnnotations.getScopes(constructorElement)) { - builder.addError(scopeErrorMsg, constructorElement, scope.scopeAnnotation().xprocessing()); - } - } - - for (XExecutableParameterElement parameter : constructorElement.getParameters()) { - superficialValidation.validateTypeOf(parameter); - validateDependencyRequest(builder, parameter); - } - - if (throwsCheckedExceptions(constructorElement)) { - builder.addItem( - String.format( - "Dagger does not support checked exceptions on @%s constructors", - injectAnnotation.simpleName()), - privateMemberDiagnosticKind(), - constructorElement); - } - - checkInjectIntoPrivateClass(constructorElement, builder); - - XTypeElement enclosingElement = constructorElement.getEnclosingElement(); - if (enclosingElement.isAbstract()) { - builder.addError( - String.format( - "@%s is nonsense on the constructor of an abstract class", - injectAnnotation.simpleName()), - constructorElement); - } - - if (enclosingElement.isNested() && !enclosingElement.isStatic()) { - builder.addError( - String.format( - "@%s constructors are invalid on inner classes. " - + "Did you mean to make the class static?", - injectAnnotation.simpleName()), - constructorElement); - } - - // Note: superficial validation of the annotations is done as part of getting the scopes. - ImmutableSet<Scope> scopes = - injectionAnnotations.getScopes(constructorElement.getEnclosingElement()); - if (injectAnnotation.equals(TypeNames.ASSISTED_INJECT)) { - for (Scope scope : scopes) { - builder.addError( - "A type with an @AssistedInject-annotated constructor cannot be scoped", - enclosingElement, - scope.scopeAnnotation().xprocessing()); - } - } else if (scopes.size() > 1) { - for (Scope scope : scopes) { - builder.addError( - "A single binding may not declare more than one @Scope", - enclosingElement, - scope.scopeAnnotation().xprocessing()); - } - } - - return builder.build(); - } - - private ValidationReport validateField(XFieldElement fieldElement) { - superficialValidation.validateTypeOf(fieldElement); - ValidationReport.Builder builder = ValidationReport.about(fieldElement); - if (fieldElement.isFinal()) { - builder.addError("@Inject fields may not be final", fieldElement); - } - - if (fieldElement.isPrivate()) { - builder.addItem( - "Dagger does not support injection into private fields", - privateMemberDiagnosticKind(), - fieldElement); - } - - if (fieldElement.isStatic()) { - builder.addItem( - "Dagger does not support injection into static fields", - staticMemberDiagnosticKind(), - 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(); - } - - private ValidationReport validateMethod(XMethodElement methodElement) { - superficialValidation.validateTypeOf(methodElement); - ValidationReport.Builder builder = ValidationReport.about(methodElement); - if (methodElement.isAbstract()) { - builder.addError("Methods with @Inject may not be abstract", methodElement); - } - - if (methodElement.isPrivate()) { - builder.addItem( - "Dagger does not support injection into private methods", - privateMemberDiagnosticKind(), - methodElement); - } - - if (methodElement.isStatic()) { - builder.addItem( - "Dagger does not support injection into static methods", - staticMemberDiagnosticKind(), - methodElement); - } - - // No need to resolve type parameters since we're only checking existence. - if (hasTypeParameters(methodElement)) { - builder.addError("Methods with @Inject may not declare type parameters", methodElement); - } - - // No need to resolve thrown types since we're only checking existence. - if (!methodElement.getThrownTypes().isEmpty()) { - builder.addError( - "Methods with @Inject may not throw checked exceptions. " - + "Please wrap your exceptions in a RuntimeException instead.", - methodElement); - } - - for (XExecutableParameterElement parameter : methodElement.getParameters()) { - superficialValidation.validateTypeOf(parameter); - validateDependencyRequest(builder, parameter); - } - - return builder.build(); - } - - private void validateDependencyRequest( - ValidationReport.Builder builder, XVariableElement parameter) { - dependencyRequestValidator.validateDependencyRequest(builder, parameter, parameter.getType()); - dependencyRequestValidator.checkNotProducer(builder, parameter); + return validator.validate(typeElement); } public ValidationReport validateForMembersInjection(XTypeElement typeElement) { - return !processedInPreviousRoundOrCompilationUnit(typeElement) - ? validate(typeElement) // validate everything - : validateForMembersInjectionInternal(typeElement); // validate only inject members + return validator.validateForMembersInjection(typeElement); } - private ValidationReport validateForMembersInjectionInternal(XTypeElement typeElement) { - return reentrantComputeIfAbsent( - membersInjectionReports, typeElement, this::validateForMembersInjectionInternalUncached); + /** + * Validates {@code typeElement} that requires a factory to be generated. + * + * <p>In this case, the validator will have stricter validation for private and static injection + * since the generated factory doesn't support those types. + */ + public ValidationReport validateWhenGeneratingCode(XTypeElement typeElement) { + if (typeElement.getPackageName().startsWith("org.atinject.tck")) { + // The Technology Compatibility Kit (TCK) package is a special package for testing the JSR330 + // spec, which includes optional features like supporting static/private inject members. Even + // though Dagger doesn't support this, we allow it for this one case for the test coverage + // purposes. Use the normal validator which takes the user's compiler flags into account. + return validator.validate(typeElement); + } + return validatorWhenGeneratingCode.validate(typeElement); } - private ValidationReport validateForMembersInjectionInternalUncached(XTypeElement typeElement) { - superficialValidation.validateTypeOf(typeElement); - // TODO(beder): This element might not be currently compiled, so this error message could be - // left in limbo. Find an appropriate way to display the error message in that case. - ValidationReport.Builder builder = ValidationReport.about(typeElement); - boolean hasInjectedMembers = false; - for (XFieldElement field : typeElement.getDeclaredFields()) { - if (InjectionAnnotations.hasInjectAnnotation(field)) { - hasInjectedMembers = true; - ValidationReport report = validateField(field); - if (!report.isClean()) { - builder.addSubreport(report); + private final class InternalValidator { + private final Diagnostic.Kind privateMemberDiagnosticKind; + private final Diagnostic.Kind staticMemberDiagnosticKind; + private final Map<XTypeElement, ValidationReport> provisionReports = new HashMap<>(); + private final Map<XTypeElement, ValidationReport> membersInjectionReports = new HashMap<>(); + + InternalValidator( + Diagnostic.Kind privateMemberDiagnosticKind, Diagnostic.Kind staticMemberDiagnosticKind) { + this.privateMemberDiagnosticKind = privateMemberDiagnosticKind; + this.staticMemberDiagnosticKind = staticMemberDiagnosticKind; + } + + void clearCache() { + provisionReports.clear(); + membersInjectionReports.clear(); + } + + ValidationReport validate(XTypeElement typeElement) { + return reentrantComputeIfAbsent(provisionReports, typeElement, this::validateUncached); + } + + private ValidationReport validateUncached(XTypeElement typeElement) { + ValidationReport.Builder builder = ValidationReport.about(typeElement); + builder.addSubreport(validateForMembersInjectionInternal(typeElement)); + + ImmutableSet<XConstructorElement> injectConstructors = + ImmutableSet.<XConstructorElement>builder() + .addAll(injectedConstructors(typeElement)) + .addAll(assistedInjectedConstructors(typeElement)) + .build(); + + switch (injectConstructors.size()) { + case 0: + break; // Nothing to validate. + case 1: + builder.addSubreport(validateConstructor(getOnlyElement(injectConstructors))); + break; + default: + builder.addError( + String.format( + "Type %s may only contain one injected constructor. Found: %s", + typeElement.getQualifiedName(), + injectConstructors.stream() + .map(methodSignatureFormatter::format) + .collect(toImmutableList())), + typeElement); + } + + return builder.build(); + } + + private ValidationReport validateConstructor(XConstructorElement constructorElement) { + superficialValidation.validateTypeOf(constructorElement); + ValidationReport.Builder builder = + ValidationReport.about(constructorElement.getEnclosingElement()); + + if (InjectionAnnotations.hasInjectAnnotation(constructorElement) + && constructorElement.hasAnnotation(TypeNames.ASSISTED_INJECT)) { + builder.addError("Constructors cannot be annotated with both @Inject and @AssistedInject"); + } + + ClassName injectAnnotation = + getAnyAnnotation( + constructorElement, + TypeNames.INJECT, + TypeNames.INJECT_JAVAX, + TypeNames.ASSISTED_INJECT) + .map(XAnnotations::getClassName) + .get(); + + if (constructorElement.isPrivate()) { + builder.addError( + "Dagger does not support injection into private constructors", constructorElement); + } + + // If this type has already been processed in a previous round or compilation unit then there + // is no reason to recheck for invalid scope annotations since it's already been checked. + // This allows us to skip superficial validation of constructor annotations in subsequent + // compilations where the annotation types may no longer be on the classpath. + if (!processedInPreviousRoundOrCompilationUnit(constructorElement)) { + superficialValidation.validateAnnotationsOf(constructorElement); + for (XAnnotation qualifier : injectionAnnotations.getQualifiers(constructorElement)) { + builder.addError( + String.format( + "@Qualifier annotations are not allowed on @%s constructors", + injectAnnotation.simpleName()), + constructorElement, + qualifier); + } + + String scopeErrorMsg = + String.format( + "@Scope annotations are not allowed on @%s constructors", + injectAnnotation.simpleName()); + + if (injectAnnotation.equals(TypeNames.INJECT) + || injectAnnotation.equals(TypeNames.INJECT_JAVAX)) { + scopeErrorMsg += "; annotate the class instead"; + } + + for (Scope scope : injectionAnnotations.getScopes(constructorElement)) { + builder.addError( + scopeErrorMsg, constructorElement, scope.scopeAnnotation().xprocessing()); } } - } - for (XMethodElement method : typeElement.getDeclaredMethods()) { - if (InjectionAnnotations.hasInjectAnnotation(method)) { - hasInjectedMembers = true; - ValidationReport report = validateMethod(method); - if (!report.isClean()) { - builder.addSubreport(report); + + for (XExecutableParameterElement parameter : constructorElement.getParameters()) { + superficialValidation.validateTypeOf(parameter); + validateDependencyRequest(builder, parameter); + } + + if (throwsCheckedExceptions(constructorElement)) { + builder.addItem( + String.format( + "Dagger does not support checked exceptions on @%s constructors", + injectAnnotation.simpleName()), + privateMemberDiagnosticKind, + constructorElement); + } + + checkInjectIntoPrivateClass(constructorElement, builder); + + XTypeElement enclosingElement = constructorElement.getEnclosingElement(); + if (enclosingElement.isAbstract()) { + builder.addError( + String.format( + "@%s is nonsense on the constructor of an abstract class", + injectAnnotation.simpleName()), + constructorElement); + } + + if (enclosingElement.isNested() && !enclosingElement.isStatic()) { + builder.addError( + String.format( + "@%s constructors are invalid on inner classes. " + + "Did you mean to make the class static?", + injectAnnotation.simpleName()), + constructorElement); + } + + // Note: superficial validation of the annotations is done as part of getting the scopes. + ImmutableSet<Scope> scopes = + injectionAnnotations.getScopes(constructorElement.getEnclosingElement()); + if (injectAnnotation.equals(TypeNames.ASSISTED_INJECT)) { + for (Scope scope : scopes) { + builder.addError( + "A type with an @AssistedInject-annotated constructor cannot be scoped", + enclosingElement, + scope.scopeAnnotation().xprocessing()); } + } else if (scopes.size() > 1) { + for (Scope scope : scopes) { + builder.addError( + "A single binding may not declare more than one @Scope", + enclosingElement, + scope.scopeAnnotation().xprocessing()); + } + } + + return builder.build(); + } + + private ValidationReport validateField(XFieldElement fieldElement) { + superficialValidation.validateTypeOf(fieldElement); + ValidationReport.Builder builder = ValidationReport.about(fieldElement); + if (fieldElement.isFinal()) { + builder.addError("@Inject fields may not be final", fieldElement); + } + + if (fieldElement.isPrivate()) { + builder.addItem( + "Dagger does not support injection into private fields", + privateMemberDiagnosticKind, + fieldElement); + } + + if (fieldElement.isStatic()) { + builder.addItem( + "Dagger does not support injection into static fields", + staticMemberDiagnosticKind, + fieldElement); + } + + if (fieldElement.isProtected() + && fieldElement.getEnclosingElement().isFromKotlin() + ) { + builder.addError( + "Dagger injector does not have access to kotlin protected fields", fieldElement); + } + + validateDependencyRequest(builder, fieldElement); + + return builder.build(); + } + + private ValidationReport validateMethod(XMethodElement methodElement) { + superficialValidation.validateTypeOf(methodElement); + ValidationReport.Builder builder = ValidationReport.about(methodElement); + if (methodElement.isAbstract()) { + builder.addError("Methods with @Inject may not be abstract", methodElement); + } + + if (methodElement.isPrivate()) { + builder.addItem( + "Dagger does not support injection into private methods", + privateMemberDiagnosticKind, + methodElement); + } + + if (methodElement.isStatic()) { + builder.addItem( + "Dagger does not support injection into static methods", + staticMemberDiagnosticKind, + methodElement); + } + + // No need to resolve type parameters since we're only checking existence. + if (hasTypeParameters(methodElement)) { + builder.addError("Methods with @Inject may not declare type parameters", methodElement); + } + + // No need to resolve thrown types since we're only checking existence. + if (!methodElement.getThrownTypes().isEmpty()) { + builder.addError( + "Methods with @Inject may not throw checked exceptions. " + + "Please wrap your exceptions in a RuntimeException instead.", + methodElement); + } + + for (XExecutableParameterElement parameter : methodElement.getParameters()) { + superficialValidation.validateTypeOf(parameter); + validateDependencyRequest(builder, parameter); + } + + return builder.build(); + } + + private void validateDependencyRequest( + ValidationReport.Builder builder, XVariableElement parameter) { + dependencyRequestValidator.validateDependencyRequest(builder, parameter, parameter.getType()); + dependencyRequestValidator.checkNotProducer(builder, parameter); + } + + public ValidationReport validateForMembersInjection(XTypeElement typeElement) { + return !processedInPreviousRoundOrCompilationUnit(typeElement) + ? validate(typeElement) // validate everything + : validateForMembersInjectionInternal(typeElement); // validate only inject members + } + + private ValidationReport validateForMembersInjectionInternal(XTypeElement typeElement) { + return reentrantComputeIfAbsent( + membersInjectionReports, typeElement, this::validateForMembersInjectionInternalUncached); + } + + private ValidationReport validateForMembersInjectionInternalUncached(XTypeElement typeElement) { + superficialValidation.validateTypeOf(typeElement); + // TODO(beder): This element might not be currently compiled, so this error message could be + // left in limbo. Find an appropriate way to display the error message in that case. + ValidationReport.Builder builder = ValidationReport.about(typeElement); + boolean hasInjectedMembers = false; + for (XFieldElement field : typeElement.getDeclaredFields()) { + if (InjectionAnnotations.hasInjectAnnotation(field)) { + hasInjectedMembers = true; + ValidationReport report = validateField(field); + if (!report.isClean()) { + builder.addSubreport(report); + } + } + } + for (XMethodElement method : typeElement.getDeclaredMethods()) { + if (InjectionAnnotations.hasInjectAnnotation(method)) { + hasInjectedMembers = true; + ValidationReport report = validateMethod(method); + if (!report.isClean()) { + builder.addSubreport(report); + } + } + } + + if (hasInjectedMembers) { + checkInjectIntoPrivateClass(typeElement, builder); + checkInjectIntoKotlinObject(typeElement, builder); + } + + Optional.ofNullable(typeElement.getSuperType()) + .filter(supertype -> !supertype.getTypeName().equals(TypeName.OBJECT)) + .ifPresent( + supertype -> { + superficialValidation.validateSuperTypeOf(typeElement); + ValidationReport report = validateForMembersInjection(supertype.getTypeElement()); + if (!report.isClean()) { + builder.addSubreport(report); + } + }); + + return builder.build(); + } + + /** Returns true if the given method element declares a checked exception. */ + private boolean throwsCheckedExceptions(XConstructorElement constructorElement) { + XType runtimeException = processingEnv.findType(TypeNames.RUNTIME_EXCEPTION); + XType error = processingEnv.findType(TypeNames.ERROR); + superficialValidation.validateThrownTypesOf(constructorElement); + return !constructorElement.getThrownTypes().stream() + .allMatch(type -> isSubtype(type, runtimeException) || isSubtype(type, error)); + } + + private void checkInjectIntoPrivateClass(XElement element, ValidationReport.Builder builder) { + if (!Accessibility.isElementAccessibleFromOwnPackage(closestEnclosingTypeElement(element))) { + builder.addItem( + "Dagger does not support injection into private classes", + privateMemberDiagnosticKind, + element); } } - if (hasInjectedMembers) { - checkInjectIntoPrivateClass(typeElement, builder); - checkInjectIntoKotlinObject(typeElement, builder); + private void checkInjectIntoKotlinObject( + XTypeElement element, ValidationReport.Builder builder) { + if (element.isKotlinObject() || element.isCompanionObject()) { + builder.addError("Dagger does not support injection into Kotlin objects", element); + } } - Optional.ofNullable(typeElement.getSuperType()) - .filter(supertype -> !supertype.getTypeName().equals(TypeName.OBJECT)) - .ifPresent( - supertype -> { - superficialValidation.validateSuperTypeOf(typeElement); - ValidationReport report = validateForMembersInjection(supertype.getTypeElement()); - if (!report.isClean()) { - builder.addSubreport(report); - } - }); - - return builder.build(); - } - - /** Returns true if the given method element declares a checked exception. */ - private boolean throwsCheckedExceptions(XConstructorElement constructorElement) { - XType runtimeException = processingEnv.findType(TypeNames.RUNTIME_EXCEPTION); - XType error = processingEnv.findType(TypeNames.ERROR); - superficialValidation.validateThrownTypesOf(constructorElement); - return !constructorElement.getThrownTypes().stream() - .allMatch(type -> isSubtype(type, runtimeException) || isSubtype(type, error)); - } - - private void checkInjectIntoPrivateClass(XElement element, ValidationReport.Builder builder) { - if (!Accessibility.isElementAccessibleFromOwnPackage(closestEnclosingTypeElement(element))) { - builder.addItem( - "Dagger does not support injection into private classes", - privateMemberDiagnosticKind(), - element); + private boolean processedInPreviousRoundOrCompilationUnit( + XConstructorElement injectConstructor) { + return processingEnv.findTypeElement(factoryNameForElement(injectConstructor)) != null; } - } - private void checkInjectIntoKotlinObject(XTypeElement element, ValidationReport.Builder builder) { - if (element.isKotlinObject() || element.isCompanionObject()) { - builder.addError("Dagger does not support injection into Kotlin objects", element); + private boolean processedInPreviousRoundOrCompilationUnit(XTypeElement membersInjectedType) { + return processingEnv.findTypeElement(membersInjectorNameForType(membersInjectedType)) != null; } } - - private Diagnostic.Kind privateMemberDiagnosticKind() { - return privateAndStaticInjectionDiagnosticKind.orElse( - compilerOptions.privateMemberValidationKind()); - } - - private Diagnostic.Kind staticMemberDiagnosticKind() { - return privateAndStaticInjectionDiagnosticKind.orElse( - compilerOptions.staticMemberValidationKind()); - } - - private boolean processedInPreviousRoundOrCompilationUnit(XConstructorElement injectConstructor) { - return processingEnv.findTypeElement(factoryNameForElement(injectConstructor)) != null; - } - - private boolean processedInPreviousRoundOrCompilationUnit(XTypeElement membersInjectedType) { - return processingEnv.findTypeElement(membersInjectorNameForType(membersInjectedType)) != null; - } }
diff --git a/java/dagger/internal/codegen/validation/MultibindsMethodValidator.java b/java/dagger/internal/codegen/validation/MultibindsMethodValidator.java index a63d974..8638614 100644 --- a/java/dagger/internal/codegen/validation/MultibindsMethodValidator.java +++ b/java/dagger/internal/codegen/validation/MultibindsMethodValidator.java
@@ -16,7 +16,8 @@ package dagger.internal.codegen.validation; -import static dagger.internal.codegen.base.FrameworkTypes.isFrameworkType; +import static dagger.internal.codegen.base.FrameworkTypes.isMapValueFrameworkType; +import static dagger.internal.codegen.base.FrameworkTypes.isSetValueFrameworkType; import static dagger.internal.codegen.validation.BindingElementValidator.AllowsMultibindings.NO_MULTIBINDINGS; import static dagger.internal.codegen.validation.BindingElementValidator.AllowsScoping.NO_SCOPING; import static dagger.internal.codegen.validation.BindingMethodValidator.Abstractness.MUST_BE_ABSTRACT; @@ -95,7 +96,7 @@ } else if (isWildcard(mapType.valueType())) { report.addError( bindingMethods("return type cannot use a wildcard as the Map value type.")); - } else if (isFrameworkType(mapType.valueType())) { + } else if (isMapValueFrameworkType(mapType.valueType())) { String frameworkTypeName = getSimpleName(mapType.valueType().getTypeElement()); report.addError( bindingMethods( @@ -108,7 +109,7 @@ report.addError(bindingMethods("return type cannot be a raw Set type")); } else if (isWildcard(setType.elementType())) { report.addError(bindingMethods("return type cannot use a wildcard as the Set value type.")); - } else if (isFrameworkType(setType.elementType())) { + } else if (isSetValueFrameworkType(setType.elementType())) { String frameworkTypeName = getSimpleName(setType.elementType().getTypeElement()); report.addError( bindingMethods(
diff --git a/java/dagger/internal/codegen/validation/ProducesMethodValidator.java b/java/dagger/internal/codegen/validation/ProducesMethodValidator.java index 9b4c16c..35b223a 100644 --- a/java/dagger/internal/codegen/validation/ProducesMethodValidator.java +++ b/java/dagger/internal/codegen/validation/ProducesMethodValidator.java
@@ -28,8 +28,8 @@ import androidx.room.compiler.processing.XType; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.codegen.binding.InjectionAnnotations; -import dagger.internal.codegen.binding.Nullability; import dagger.internal.codegen.javapoet.TypeNames; +import dagger.internal.codegen.xprocessing.Nullability; import dagger.internal.codegen.xprocessing.XTypes; import java.util.Optional; import java.util.Set;
diff --git a/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java b/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java index 42e1adf..ef9e24b 100644 --- a/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java +++ b/java/dagger/internal/codegen/validation/SpiModelBindingGraphConverter.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.validation; +import static androidx.room.compiler.processing.XElementKt.isMethod; 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; @@ -46,7 +47,8 @@ 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.KSDeclaration; +import com.google.devtools.ksp.symbol.KSPropertyDeclaration; import com.google.devtools.ksp.symbol.KSType; import dagger.internal.codegen.xprocessing.XAnnotations; import dagger.internal.codegen.xprocessing.XElements; @@ -575,9 +577,12 @@ } @Override - public KSFunctionDeclaration ksp() { + public KSDeclaration ksp() { checkIsKsp(backend()); - return toKS(executableElement()); + return isMethod(executableElement()) + && XElements.asMethod(executableElement()).isKotlinPropertyMethod() + ? (KSPropertyDeclaration) toKS((XElement) executableElement()) + : toKS(executableElement()); } @Override
diff --git a/java/dagger/internal/codegen/writing/AnnotationCreatorGenerator.java b/java/dagger/internal/codegen/writing/AnnotationCreatorGenerator.java index 23faf75..08f6153 100644 --- a/java/dagger/internal/codegen/writing/AnnotationCreatorGenerator.java +++ b/java/dagger/internal/codegen/writing/AnnotationCreatorGenerator.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static androidx.room.compiler.processing.XTypeKt.isArray; import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv; import static com.squareup.javapoet.MethodSpec.constructorBuilder; @@ -95,7 +96,7 @@ @Override public ImmutableList<TypeSpec.Builder> topLevelTypes(XTypeElement annotationType) { - ClassName generatedTypeName = getAnnotationCreatorClassName(annotationType); + ClassName generatedTypeName = toJavaPoet(getAnnotationCreatorClassName(annotationType)); TypeSpec.Builder annotationCreatorBuilder = classBuilder(generatedTypeName) .addModifiers(PUBLIC, FINAL) @@ -146,11 +147,15 @@ XTypeElement annotationElement, Set<XTypeElement> annotationElements) { if (annotationElements.add(annotationElement)) { for (XMethodElement method : annotationElement.getDeclaredMethods()) { - XTypeElement returnType = method.getReturnType().getTypeElement(); + XType returnType = method.getReturnType(); + XTypeElement maybeAnnotationType = + isArray(returnType) + ? asArray(returnType).getComponentType().getTypeElement() + : returnType.getTypeElement(); // Return type may be null if it doesn't return a type or type is not known - if (returnType != null && returnType.isAnnotationClass()) { + if (maybeAnnotationType != null && maybeAnnotationType.isAnnotationClass()) { // Ignore the return value since this method is just an accumulator method. - nestedAnnotationElements(returnType, annotationElements); + nestedAnnotationElements(maybeAnnotationType, annotationElements); } } }
diff --git a/java/dagger/internal/codegen/writing/AssistedFactoryRequestRepresentation.java b/java/dagger/internal/codegen/writing/AssistedFactoryRequestRepresentation.java index 93a8ce5..4735447 100644 --- a/java/dagger/internal/codegen/writing/AssistedFactoryRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/AssistedFactoryRequestRepresentation.java
@@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedFactoryMethod; import static dagger.internal.codegen.writing.AssistedInjectionParameters.assistedFactoryParameterSpecs; import static dagger.internal.codegen.xprocessing.MethodSpecs.overriding; @@ -34,11 +33,11 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; +import dagger.internal.codegen.binding.AssistedFactoryBinding; +import dagger.internal.codegen.binding.AssistedInjectionBinding; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.Expression; -import dagger.internal.codegen.model.DependencyRequest; import java.util.Optional; /** @@ -46,14 +45,14 @@ * dagger.assisted.AssistedFactory} methods. */ final class AssistedFactoryRequestRepresentation extends RequestRepresentation { - private final ProvisionBinding binding; + private final AssistedFactoryBinding binding; private final BindingGraph graph; private final SimpleMethodRequestRepresentation.Factory simpleMethodRequestRepresentationFactory; private final ComponentImplementation componentImplementation; @AssistedInject AssistedFactoryRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted AssistedFactoryBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, SimpleMethodRequestRepresentation.Factory simpleMethodRequestRepresentationFactory) { @@ -65,16 +64,14 @@ @Override Expression getDependencyExpression(ClassName requestingClass) { - // An assisted factory binding should have a single request for an assisted injection type. - DependencyRequest assistedInjectionRequest = getOnlyElement(binding.provisionDependencies()); // Get corresponding assisted injection binding. - Optional<Binding> localBinding = graph.localContributionBinding(assistedInjectionRequest.key()); + Optional<Binding> localBinding = graph.localContributionBinding(binding.assistedInjectKey()); checkArgument( localBinding.isPresent(), "assisted factory should have a dependency on an assisted injection binding"); Expression assistedInjectionExpression = simpleMethodRequestRepresentationFactory - .create((ProvisionBinding) localBinding.get()) + .create((AssistedInjectionBinding) localBinding.get()) .getDependencyExpression(requestingClass.peerClass("")); return Expression.create( assistedInjectionExpression.type(), @@ -116,6 +113,6 @@ @AssistedFactory static interface Factory { - AssistedFactoryRequestRepresentation create(ProvisionBinding binding); + AssistedFactoryRequestRepresentation create(AssistedFactoryBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java b/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java index f74b50a..df55b93 100644 --- a/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java +++ b/java/dagger/internal/codegen/writing/ComponentCreatorImplementationFactory.java
@@ -320,7 +320,7 @@ "$T.checkBuilderRequirement($N, $T.class)", Preconditions.class, field, - TypeNames.rawTypeName(field.type)); + TypeNames.rawTypeName(field.type.withoutAnnotations())); break; case ALLOW: break; @@ -498,7 +498,7 @@ @Override protected MethodSpec.Builder setterMethodBuilder(ComponentRequirement requirement) { - String name = simpleVariableName(requirement.typeElement().getClassName()); + String name = simpleVariableName(requirement.typeElement().asClassName()); return methodBuilder(name) .addModifiers(PUBLIC) .addParameter(requirement.type().getTypeName(), name)
diff --git a/java/dagger/internal/codegen/writing/ComponentImplementation.java b/java/dagger/internal/codegen/writing/ComponentImplementation.java index a41b1c7..4583396 100644 --- a/java/dagger/internal/codegen/writing/ComponentImplementation.java +++ b/java/dagger/internal/codegen/writing/ComponentImplementation.java
@@ -16,6 +16,8 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; +import static androidx.room.compiler.codegen.compat.XConverters.toXPoet; import static com.google.common.base.CaseFormat.LOWER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; @@ -42,6 +44,7 @@ import static javax.lang.model.element.Modifier.STATIC; import static javax.tools.Diagnostic.Kind.ERROR; +import androidx.room.compiler.processing.JavaPoetExtKt; import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMessager; import androidx.room.compiler.processing.XMethodElement; @@ -58,7 +61,7 @@ import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.MultimapBuilder; -import com.google.common.collect.Sets; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; @@ -80,6 +83,7 @@ import dagger.internal.codegen.binding.ComponentRequirement; import dagger.internal.codegen.binding.KeyVariableNamer; import dagger.internal.codegen.binding.MethodSignature; +import dagger.internal.codegen.binding.ModuleDescriptor; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.CodeBlocks; import dagger.internal.codegen.javapoet.TypeNames; @@ -91,6 +95,7 @@ import dagger.internal.codegen.xprocessing.XTypeElements; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -244,8 +249,12 @@ /** * How many statements per {@code initialize()} or {@code onProducerFutureCancelled()} method * before they get partitioned. + * + * <p>This value has been set based on empirical performance analysis. If this number is too + * large, some Android runtimes will not ahead-of-time compile the generated code. See + * b/316617683. */ - private static final int STATEMENTS_PER_METHOD = 100; + private static final int STATEMENTS_PER_METHOD = 25; private final ShardImplementation componentShard; private final Supplier<ImmutableMap<Binding, ShardImplementation>> shardsByBinding; @@ -291,7 +300,8 @@ this.processingEnv = processingEnv; // The first group of keys belong to the component itself. We call this the componentShard. - this.componentShard = new ShardImplementation(componentNames.get(graph.componentPath())); + this.componentShard = + new ShardImplementation(toJavaPoet(componentNames.get(graph.componentPath()))); // Claim the method names for all local and inherited methods on the component type. XTypeElements.getAllNonPrivateInstanceMethods(graph.componentTypeElement()).stream() @@ -376,8 +386,8 @@ ClassName fieldType = componentImpl.name(); String fieldName = componentImpl.isNested() - ? simpleVariableName(componentImpl.name()) - : simpleVariableName(component); + ? simpleVariableName(toXPoet(componentImpl.name())) + : simpleVariableName(toXPoet(component)); FieldSpec.Builder field = FieldSpec.builder( fieldType, @@ -426,7 +436,7 @@ * generated class unless this is a top-level component, in which case it will be nested. */ public ClassName getCreatorName() { - return componentNames.getCreatorName(graph.componentPath()); + return toJavaPoet(componentNames.getCreatorName(graph.componentPath())); } /** Generates the component and returns the resulting {@link TypeSpec}. */ @@ -437,7 +447,7 @@ /** * The implementation of a shard. * - * <p>The purpose of a shard is to allow a component implemenation to be split into multiple + * <p>The purpose of a shard is to allow a component implementation to be split into multiple * classes, where each class owns the creation logic for a set of keys. Sharding is useful for * large component implementations, where a single component implementation class can reach size * limitations, such as the constant pool size. @@ -456,7 +466,6 @@ private final UniqueNameSet assistedParamNames = new UniqueNameSet(); private final List<CodeBlock> initializations = new ArrayList<>(); private final SwitchingProviders switchingProviders; - 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<>(); @@ -473,7 +482,6 @@ private ShardImplementation(ClassName name) { this.name = name; this.switchingProviders = new SwitchingProviders(this, processingEnv); - this.lazyClassKeyProviders = new LazyClassKeyProviders(this); if (graph.componentDescriptor().isProduction()) { claimMethodName(CANCELLATION_LISTENER_METHOD_NAME); } @@ -487,8 +495,26 @@ requirement -> requirement, requirement -> ParameterSpec.builder( - requirement.type().getTypeName(), + requirement + .type() + .getTypeName() + .annotated( + requirement + .getNullability() + .typeUseNullableAnnotations() + .stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList())), getUniqueFieldName(requirement.variableName() + "Param")) + .addAnnotations( + requirement + .getNullability() + .nonTypeUseNullableAnnotations() + .stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList())) .build())); } @@ -507,10 +533,6 @@ return switchingProviders; } - public LazyClassKeyProviders getLazyClassKeyProviders() { - return lazyClassKeyProviders; - } - /** Returns the {@link ComponentImplementation} that owns this shard. */ public ComponentImplementation getComponentImplementation() { return ComponentImplementation.this; @@ -569,7 +591,8 @@ * {@link Key}. */ ClassName getSubcomponentCreatorSimpleName(Key creatorKey) { - return componentNames.getSubcomponentCreatorName(graph.componentPath(), creatorKey); + return toJavaPoet( + componentNames.getSubcomponentCreatorName(graph.componentPath(), creatorKey)); } /** @@ -612,7 +635,8 @@ } /** Adds a {@link Supplier} for the SwitchingProvider for the component. */ - void addTypeSupplier(Supplier<TypeSpec> typeSpecSupplier) { + @Override + public void addTypeSupplier(Supplier<TypeSpec> typeSpecSupplier) { typeSuppliers.add(typeSpecSupplier); } @@ -706,6 +730,15 @@ public TypeSpec generate() { TypeSpec.Builder builder = classBuilder(name); + // Ksp requires explicitly associating input classes that are generated with the output class, + // otherwise, the cached generated classes won't be discoverable in an incremental build. + if (processingEnv.getBackend() == XProcessingEnv.Backend.KSP) { + graph.componentDescriptor().modules().stream() + .filter(ModuleDescriptor::isImplicitlyIncluded) + .forEach( + module -> JavaPoetExtKt.addOriginatingElement(builder, module.moduleElement())); + } + if (isComponentShard()) { TypeSpecs.addSupertype(builder, graph.componentTypeElement()); addCreator(); @@ -871,10 +904,11 @@ // Each component method may have been declared by several supertypes. We want to implement // only one method for each distinct signature. XType componentType = graph.componentTypeElement().getType(); - Set<MethodSignature> signatures = Sets.newHashSet(); - for (ComponentMethodDescriptor method : graph.componentDescriptor().entryPointMethods()) { - if (signatures.add( - MethodSignature.forComponentMethod(method, componentType, processingEnv))) { + Set<MethodSignature> methodDescriptors = new HashSet<>(); + for (ComponentMethodDescriptor method : graph.entryPointMethods()) { + MethodSignature signature = + MethodSignature.forComponentMethod(method, componentType, processingEnv); + if (methodDescriptors.add(signature)) { addMethod( COMPONENT_METHOD, componentRequestRepresentationsProvider.get().getComponentMethod(method));
diff --git a/java/dagger/internal/codegen/writing/ComponentInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/ComponentInstanceRequestRepresentation.java index b5bed2f..f5d2e52 100644 --- a/java/dagger/internal/codegen/writing/ComponentInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ComponentInstanceRequestRepresentation.java
@@ -21,17 +21,17 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.ComponentBinding; import dagger.internal.codegen.javapoet.Expression; /** A binding expression for the instance of the component itself, i.e. {@code this}. */ final class ComponentInstanceRequestRepresentation extends RequestRepresentation { private final ComponentImplementation componentImplementation; - private final ContributionBinding binding; + private final ComponentBinding binding; @AssistedInject ComponentInstanceRequestRepresentation( - @Assisted ContributionBinding binding, ComponentImplementation componentImplementation) { + @Assisted ComponentBinding binding, ComponentImplementation componentImplementation) { this.componentImplementation = componentImplementation; this.binding = binding; } @@ -47,6 +47,6 @@ @AssistedFactory static interface Factory { - ComponentInstanceRequestRepresentation create(ContributionBinding binding); + ComponentInstanceRequestRepresentation create(ComponentBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ComponentNames.java b/java/dagger/internal/codegen/writing/ComponentNames.java index b5f2f2f..79344c7 100644 --- a/java/dagger/internal/codegen/writing/ComponentNames.java +++ b/java/dagger/internal/codegen/writing/ComponentNames.java
@@ -22,6 +22,7 @@ import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; import static java.lang.String.format; +import androidx.room.compiler.codegen.XClassName; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; @@ -50,16 +51,16 @@ */ public final class ComponentNames { /** Returns the class name for the top-level generated class. */ - public static ClassName getTopLevelClassName(ComponentDescriptor componentDescriptor) { + public static XClassName getTopLevelClassName(ComponentDescriptor componentDescriptor) { checkState(!componentDescriptor.isSubcomponent()); - ClassName componentName = componentDescriptor.typeElement().getClassName(); - return ClassName.get(componentName.packageName(), "Dagger" + classFileName(componentName)); + XClassName componentName = componentDescriptor.typeElement().asClassName(); + return XClassName.Companion.get(componentName.getPackageName(), "Dagger" + classFileName(componentName)); } private static final Splitter QUALIFIED_NAME_SPLITTER = Splitter.on('.'); private final CompilerOptions compilerOptions; - private final ClassName topLevelClassName; + private final XClassName topLevelClassName; private final ImmutableMap<ComponentPath, String> namesByPath; private final ImmutableMap<ComponentPath, String> creatorNamesByPath; private final ImmutableMultimap<Key, ComponentPath> pathsByCreatorKey; @@ -75,7 +76,7 @@ } /** Returns the simple component name for the given {@link ComponentDescriptor}. */ - ClassName get(ComponentPath componentPath) { + XClassName get(ComponentPath componentPath) { return compilerOptions.generatedClassExtendsComponent() && componentPath.atRoot() ? topLevelClassName : topLevelClassName.nestedClass(namesByPath.get(componentPath) + "Impl"); @@ -85,7 +86,7 @@ * Returns the component descriptor for the component with the given subcomponent creator {@link * Key}. */ - ClassName getSubcomponentCreatorName(ComponentPath componentPath, Key creatorKey) { + XClassName getSubcomponentCreatorName(ComponentPath componentPath, Key creatorKey) { checkArgument(pathsByCreatorKey.containsKey(creatorKey)); // First, find the subcomponent path corresponding to the subcomponent creator key. // The key may correspond to multiple paths, so we need to find the one under this component. @@ -100,7 +101,7 @@ * Returns the simple name for the subcomponent creator implementation for the given {@link * ComponentDescriptor}. */ - ClassName getCreatorName(ComponentPath componentPath) { + XClassName getCreatorName(ComponentPath componentPath) { checkArgument(creatorNamesByPath.containsKey(componentPath)); return topLevelClassName.nestedClass(creatorNamesByPath.get(componentPath)); }
diff --git a/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java b/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java index 41c3c46..367fd45 100644 --- a/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ComponentProvisionRequestRepresentation.java
@@ -25,21 +25,21 @@ import dagger.assisted.AssistedInject; import dagger.internal.Preconditions; import dagger.internal.codegen.binding.BindingGraph; +import dagger.internal.codegen.binding.ComponentDependencyProvisionBinding; import dagger.internal.codegen.binding.ComponentRequirement; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.Expression; /** A binding expression for component provision methods. */ final class ComponentProvisionRequestRepresentation extends RequestRepresentation { - private final ProvisionBinding binding; + private final ComponentDependencyProvisionBinding binding; private final BindingGraph bindingGraph; private final ComponentRequirementExpressions componentRequirementExpressions; private final CompilerOptions compilerOptions; @AssistedInject ComponentProvisionRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted ComponentDependencyProvisionBinding binding, BindingGraph bindingGraph, ComponentImplementation componentImplementation, ComponentRequirementExpressions componentRequirementExpressions, @@ -72,7 +72,9 @@ } static CodeBlock maybeCheckForNull( - ProvisionBinding binding, CompilerOptions compilerOptions, CodeBlock invocation) { + ComponentDependencyProvisionBinding binding, + CompilerOptions compilerOptions, + CodeBlock invocation) { return binding.shouldCheckForNull(compilerOptions) ? CodeBlock.of("$T.checkNotNullFromComponent($L)", Preconditions.class, invocation) : invocation; @@ -80,6 +82,6 @@ @AssistedFactory static interface Factory { - ComponentProvisionRequestRepresentation create(ProvisionBinding binding); + ComponentProvisionRequestRepresentation create(ComponentDependencyProvisionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java b/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java index dd34316..0f2a40f 100644 --- a/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java +++ b/java/dagger/internal/codegen/writing/ComponentRequestRepresentations.java
@@ -19,17 +19,14 @@ 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.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.base.Util.reentrantComputeIfAbsent; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible; 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; @@ -47,8 +44,6 @@ import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.binding.FrameworkTypeMapper; import dagger.internal.codegen.binding.MembersInjectionBinding; -import dagger.internal.codegen.binding.ProductionBinding; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.RequestKind; @@ -187,47 +182,26 @@ /** Returns the implementation of a component method. */ public MethodSpec getComponentMethod(ComponentMethodDescriptor componentMethod) { - checkArgument(componentMethod.dependencyRequest().isPresent()); - BindingRequest request = bindingRequest(componentMethod.dependencyRequest().get()); return overriding(componentMethod.methodElement(), graph.componentTypeElement().getType()) - .addCode( - request.isRequestKind(RequestKind.MEMBERS_INJECTION) - ? getMembersInjectionComponentMethodImplementation(request, componentMethod) - : getContributionComponentMethodImplementation(request, componentMethod)) + .addCode(getComponentMethodCodeBlock(componentMethod)) .build(); } - private CodeBlock getMembersInjectionComponentMethodImplementation( - BindingRequest request, ComponentMethodDescriptor componentMethod) { - checkArgument(request.isRequestKind(RequestKind.MEMBERS_INJECTION)); - XMethodElement methodElement = componentMethod.methodElement(); - RequestRepresentation requestRepresentation = getRequestRepresentation(request); - MembersInjectionBinding binding = - ((MembersInjectionRequestRepresentation) requestRepresentation).binding(); - if (binding.injectionSites().isEmpty()) { - // If there are no injection sites either do nothing (if the return type is void) or return - // the input instance as-is. - return isVoid(methodElement.getReturnType()) - ? CodeBlock.of("") - : CodeBlock.of( - "return $L;", getSimpleName(getOnlyElement(methodElement.getParameters()))); + private CodeBlock getComponentMethodCodeBlock(ComponentMethodDescriptor componentMethod) { + Expression expression = getComponentMethodExpression(componentMethod); + if (isVoid(componentMethod.methodElement().getReturnType())) { + return expression.codeBlock().isEmpty() + ? expression.codeBlock() + : CodeBlock.of("$L;", expression.codeBlock()); } - Expression expression = getComponentMethodExpression(requestRepresentation, componentMethod); - return isVoid(methodElement.getReturnType()) - ? CodeBlock.of("$L;", expression.codeBlock()) - : CodeBlock.of("return $L;", expression.codeBlock()); - } - - private CodeBlock getContributionComponentMethodImplementation( - BindingRequest request, ComponentMethodDescriptor componentMethod) { - checkArgument(!request.isRequestKind(RequestKind.MEMBERS_INJECTION)); - Expression expression = - getComponentMethodExpression(getRequestRepresentation(request), componentMethod); return CodeBlock.of("return $L;", expression.codeBlock()); } - private Expression getComponentMethodExpression( - RequestRepresentation requestRepresentation, ComponentMethodDescriptor componentMethod) { + private Expression getComponentMethodExpression(ComponentMethodDescriptor componentMethod) { + checkArgument(componentMethod.dependencyRequest().isPresent()); + BindingRequest request = bindingRequest(componentMethod.dependencyRequest().get()); + RequestRepresentation requestRepresentation = getRequestRepresentation(request); + Expression expression = requestRepresentation.getDependencyExpressionForComponentMethod( componentMethod, componentImplementation); @@ -279,9 +253,9 @@ return membersInjectionBindingRepresentationFactory.create( (MembersInjectionBinding) binding); case PROVISION: - return provisionBindingRepresentationFactory.create((ProvisionBinding) binding); + return provisionBindingRepresentationFactory.create((ContributionBinding) binding); case PRODUCTION: - return productionBindingRepresentationFactory.create((ProductionBinding) binding); + return productionBindingRepresentationFactory.create((ContributionBinding) binding); } throw new AssertionError(); }
diff --git a/java/dagger/internal/codegen/writing/ComponentRequirementExpressions.java b/java/dagger/internal/codegen/writing/ComponentRequirementExpressions.java index ea82f32..ea03683 100644 --- a/java/dagger/internal/codegen/writing/ComponentRequirementExpressions.java +++ b/java/dagger/internal/codegen/writing/ComponentRequirementExpressions.java
@@ -19,12 +19,14 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Suppliers.memoize; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.writing.ComponentImplementation.FieldSpecKind.COMPONENT_REQUIREMENT_FIELD; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import androidx.room.compiler.processing.XTypeElement; import com.google.common.base.Supplier; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; @@ -129,7 +131,22 @@ private MemberSelect createField() { String fieldName = componentShard.getUniqueFieldName(componentRequirement.variableName()); TypeName fieldType = componentRequirement.type().getTypeName(); - FieldSpec field = FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL).build(); + FieldSpec field = + FieldSpec.builder( + fieldType.annotated( + componentRequirement.getNullability().typeUseNullableAnnotations().stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList())), + fieldName, + PRIVATE, + FINAL) + .addAnnotations( + componentRequirement.getNullability().nonTypeUseNullableAnnotations().stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList())) + .build(); componentShard.addField(COMPONENT_REQUIREMENT_FIELD, field); componentShard.addComponentRequirementInitialization(fieldInitialization(field)); return MemberSelect.localField(componentShard, fieldName);
diff --git a/java/dagger/internal/codegen/writing/ComponentRequirementRequestRepresentation.java b/java/dagger/internal/codegen/writing/ComponentRequirementRequestRepresentation.java index f9e8f14..6867ded 100644 --- a/java/dagger/internal/codegen/writing/ComponentRequirementRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ComponentRequirementRequestRepresentation.java
@@ -22,6 +22,8 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; +import dagger.internal.codegen.binding.BoundInstanceBinding; +import dagger.internal.codegen.binding.ComponentDependencyBinding; import dagger.internal.codegen.binding.ComponentRequirement; import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.javapoet.Expression; @@ -52,8 +54,16 @@ } @AssistedFactory - static interface Factory { - ComponentRequirementRequestRepresentation create( + abstract static class Factory { + abstract ComponentRequirementRequestRepresentation create( ContributionBinding binding, ComponentRequirement componentRequirement); + + final ComponentRequirementRequestRepresentation create(BoundInstanceBinding binding) { + return create(binding, ComponentRequirement.forBoundInstance(binding)); + } + + final ComponentRequirementRequestRepresentation create(ComponentDependencyBinding binding) { + return create(binding, ComponentRequirement.forDependency(binding)); + } } }
diff --git a/java/dagger/internal/codegen/writing/ComponentWrapperImplementation.java b/java/dagger/internal/codegen/writing/ComponentWrapperImplementation.java index 96a042c..3f8894d 100644 --- a/java/dagger/internal/codegen/writing/ComponentWrapperImplementation.java +++ b/java/dagger/internal/codegen/writing/ComponentWrapperImplementation.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder; import static dagger.internal.codegen.writing.ComponentNames.getTopLevelClassName; @@ -23,6 +24,7 @@ import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PUBLIC; +import com.google.common.base.Supplier; import com.google.common.collect.ListMultimap; import com.google.common.collect.MultimapBuilder; import com.squareup.javapoet.ClassName; @@ -34,6 +36,8 @@ import dagger.internal.codegen.writing.ComponentImplementation.FieldSpecKind; import dagger.internal.codegen.writing.ComponentImplementation.MethodSpecKind; import dagger.internal.codegen.writing.ComponentImplementation.TypeSpecKind; +import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; /** Represents the implementation of the generated holder for the components. */ @@ -48,11 +52,12 @@ MultimapBuilder.enumKeys(MethodSpecKind.class).arrayListValues().build(); private final ListMultimap<TypeSpecKind, TypeSpec> typeSpecsMap = MultimapBuilder.enumKeys(TypeSpecKind.class).arrayListValues().build(); + private final List<Supplier<TypeSpec>> typeSuppliers = new ArrayList<>(); @Inject ComponentWrapperImplementation(@TopLevel BindingGraph graph) { this.graph = graph; - this.name = ComponentNames.getTopLevelClassName(graph.componentDescriptor()); + this.name = toJavaPoet(ComponentNames.getTopLevelClassName(graph.componentDescriptor())); } @Override @@ -81,9 +86,15 @@ } @Override + public void addTypeSupplier(Supplier<TypeSpec> typeSpecSupplier) { + typeSuppliers.add(typeSpecSupplier); + } + + @Override public TypeSpec generate() { TypeSpec.Builder builder = - classBuilder(getTopLevelClassName(graph.componentDescriptor())).addModifiers(FINAL); + classBuilder(toJavaPoet(getTopLevelClassName(graph.componentDescriptor()))) + .addModifiers(FINAL); if (graph.componentTypeElement().isPublic()) { builder.addModifiers(PUBLIC); @@ -92,6 +103,7 @@ fieldSpecsMap.asMap().values().forEach(builder::addFields); methodSpecsMap.asMap().values().forEach(builder::addMethods); typeSpecsMap.asMap().values().forEach(builder::addTypes); + typeSuppliers.stream().map(Supplier::get).forEach(builder::addType); return builder.addMethod(constructorBuilder().addModifiers(PRIVATE).build()).build(); }
diff --git a/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java b/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java index 82c01cf..29b510f 100644 --- a/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/DelegateRequestRepresentation.java
@@ -16,13 +16,11 @@ package dagger.internal.codegen.writing; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.base.RequestKinds.requestType; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; -import static dagger.internal.codegen.model.BindingKind.DELEGATE; import androidx.room.compiler.processing.XProcessingEnv; import androidx.room.compiler.processing.XType; @@ -34,7 +32,7 @@ import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindsTypeChecker; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.DelegateBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; @@ -42,7 +40,7 @@ /** A {@link dagger.internal.codegen.writing.RequestRepresentation} for {@code @Binds} methods. */ final class DelegateRequestRepresentation extends RequestRepresentation { - private final ContributionBinding binding; + private final DelegateBinding binding; private final RequestKind requestKind; private final ComponentRequestRepresentations componentRequestRepresentations; private final XProcessingEnv processingEnv; @@ -50,7 +48,7 @@ @AssistedInject DelegateRequestRepresentation( - @Assisted ContributionBinding binding, + @Assisted DelegateBinding binding, @Assisted RequestKind requestKind, ComponentRequestRepresentations componentRequestRepresentations, BindsTypeChecker bindsTypeChecker, @@ -67,8 +65,7 @@ * binding it depends on. */ static boolean isBindsScopeStrongerThanDependencyScope( - ContributionBinding bindsBinding, BindingGraph graph) { - checkArgument(bindsBinding.kind().equals(DELEGATE)); + DelegateBinding bindsBinding, BindingGraph graph) { Binding dependencyBinding = graph.contributionBinding(getOnlyElement(bindsBinding.dependencies()).key()); ScopeKind bindsScope = ScopeKind.get(bindsBinding); @@ -102,7 +99,7 @@ } static boolean instanceRequiresCast( - ContributionBinding binding, + DelegateBinding binding, Expression delegateExpression, ClassName requestingClass, BindsTypeChecker bindsTypeChecker) { @@ -130,7 +127,7 @@ // Casted raw type provider expression has to be wrapped parentheses, otherwise there // will be an error when DerivedFromFrameworkInstanceRequestRepresentation appends a `get()` to // it. - // TODO(wanyingd): change the logic to only add parenthesis when necessary. + // TODO(bcorso): change the logic to only add parenthesis when necessary. return Expression.create( castedExpression.type(), CodeBlock.of("($L)", castedExpression.codeBlock())); } @@ -155,6 +152,6 @@ @AssistedFactory static interface Factory { - DelegateRequestRepresentation create(ContributionBinding binding, RequestKind requestKind); + DelegateRequestRepresentation create(DelegateBinding binding, RequestKind requestKind); } }
diff --git a/java/dagger/internal/codegen/writing/DelegatingFrameworkInstanceCreationExpression.java b/java/dagger/internal/codegen/writing/DelegatingFrameworkInstanceCreationExpression.java index 1fbb2cb..7554b7e 100644 --- a/java/dagger/internal/codegen/writing/DelegatingFrameworkInstanceCreationExpression.java +++ b/java/dagger/internal/codegen/writing/DelegatingFrameworkInstanceCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; @@ -24,7 +25,7 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.DelegateBinding; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.CodeBlocks; import dagger.internal.codegen.model.DependencyRequest; @@ -34,13 +35,13 @@ final class DelegatingFrameworkInstanceCreationExpression implements FrameworkInstanceCreationExpression { - private final ContributionBinding binding; + private final DelegateBinding binding; private final ComponentImplementation componentImplementation; private final ComponentRequestRepresentations componentRequestRepresentations; @AssistedInject DelegatingFrameworkInstanceCreationExpression( - @Assisted ContributionBinding binding, + @Assisted DelegateBinding binding, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, CompilerOptions compilerOptions) { @@ -58,11 +59,11 @@ bindingRequest(dependency.key(), binding.frameworkType()), componentImplementation.shardImplementation(binding).name()) .codeBlock(), - binding.frameworkType().frameworkClassName()); + toJavaPoet(binding.frameworkType().frameworkClassName())); } @AssistedFactory static interface Factory { - DelegatingFrameworkInstanceCreationExpression create(ContributionBinding binding); + DelegatingFrameworkInstanceCreationExpression create(DelegateBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/DependencyMethodProducerCreationExpression.java b/java/dagger/internal/codegen/writing/DependencyMethodProducerCreationExpression.java index d83e19d..64c221d 100644 --- a/java/dagger/internal/codegen/writing/DependencyMethodProducerCreationExpression.java +++ b/java/dagger/internal/codegen/writing/DependencyMethodProducerCreationExpression.java
@@ -33,8 +33,8 @@ import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.BindingGraph; +import dagger.internal.codegen.binding.ComponentDependencyProductionBinding; import dagger.internal.codegen.binding.ComponentRequirement; -import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; /** @@ -45,14 +45,14 @@ // TODO(dpb): Resolve with DependencyMethodProviderCreationExpression. final class DependencyMethodProducerCreationExpression implements FrameworkInstanceCreationExpression { - private final ContributionBinding binding; + private final ComponentDependencyProductionBinding binding; private final ComponentImplementation componentImplementation; private final ComponentRequirementExpressions componentRequirementExpressions; private final BindingGraph graph; @AssistedInject DependencyMethodProducerCreationExpression( - @Assisted ContributionBinding binding, + @Assisted ComponentDependencyProductionBinding binding, ComponentImplementation componentImplementation, ComponentRequirementExpressions componentRequirementExpressions, BindingGraph graph) { @@ -104,6 +104,6 @@ @AssistedFactory static interface Factory { - DependencyMethodProducerCreationExpression create(ContributionBinding binding); + DependencyMethodProducerCreationExpression create(ComponentDependencyProductionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java b/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java index c54b03c..3a8ff50 100644 --- a/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/DependencyMethodProviderCreationExpression.java
@@ -24,6 +24,7 @@ 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.javapoet.TypeNames.daggerProviderOf; import static dagger.internal.codegen.writing.ComponentImplementation.TypeSpecKind.COMPONENT_PROVISION_FACTORY; import static dagger.internal.codegen.xprocessing.XElements.asMethod; @@ -34,6 +35,7 @@ import static javax.lang.model.element.Modifier.STATIC; import androidx.room.compiler.processing.XMethodElement; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.MethodSpec; @@ -42,8 +44,8 @@ import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.BindingGraph; +import dagger.internal.codegen.binding.ComponentDependencyProvisionBinding; import dagger.internal.codegen.binding.ComponentRequirement; -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; @@ -60,12 +62,12 @@ private final ComponentRequirementExpressions componentRequirementExpressions; private final CompilerOptions compilerOptions; private final BindingGraph graph; - private final ProvisionBinding binding; + private final ComponentDependencyProvisionBinding binding; private final XMethodElement provisionMethod; @AssistedInject DependencyMethodProviderCreationExpression( - @Assisted ProvisionBinding binding, + @Assisted ComponentDependencyProvisionBinding binding, ComponentImplementation componentImplementation, ComponentRequirementExpressions componentRequirementExpressions, CompilerOptions compilerOptions, @@ -100,12 +102,16 @@ methodBuilder("get") .addAnnotation(Override.class) .addModifiers(PUBLIC) - .returns(keyType) + .returns( + keyType.annotated( + binding.nullability().typeUseNullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableList()))) .addStatement("return $L", invocation); binding .nullability() - .nullableAnnotations() + .nonTypeUseNullableAnnotations() .forEach(getMethod::addAnnotation); // We need to use the componentShard here since the generated type is static and shards are @@ -144,6 +150,6 @@ @AssistedFactory static interface Factory { - DependencyMethodProviderCreationExpression create(ProvisionBinding binding); + DependencyMethodProviderCreationExpression create(ComponentDependencyProvisionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java index f054e6a..3c437a5 100644 --- a/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/DerivedFromFrameworkInstanceRequestRepresentation.java
@@ -28,6 +28,7 @@ import dagger.internal.codegen.binding.BindsTypeChecker; import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.DelegateBinding; import dagger.internal.codegen.binding.FrameworkType; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; @@ -119,7 +120,8 @@ private boolean requiresTypeCast(Expression expression, ClassName requestingClass) { return binding.kind().equals(BindingKind.DELEGATE) && requestKind.equals(RequestKind.INSTANCE) - && instanceRequiresCast(binding, expression, requestingClass, bindsTypeChecker); + && instanceRequiresCast( + (DelegateBinding) binding, expression, requestingClass, bindsTypeChecker); } @AssistedFactory
diff --git a/java/dagger/internal/codegen/writing/DirectInstanceBindingRepresentation.java b/java/dagger/internal/codegen/writing/DirectInstanceBindingRepresentation.java index 1eb4249..058ea5f 100644 --- a/java/dagger/internal/codegen/writing/DirectInstanceBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/DirectInstanceBindingRepresentation.java
@@ -25,7 +25,7 @@ import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingRequest; import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import java.util.HashMap; @@ -34,7 +34,7 @@ /** Returns request representation based on a direct instance expression. */ final class DirectInstanceBindingRepresentation { - private final ProvisionBinding binding; + private final ContributionBinding binding; private final BindingGraph graph; private final ComponentImplementation componentImplementation; private final ComponentMethodRequestRepresentation.Factory @@ -49,7 +49,7 @@ @AssistedInject DirectInstanceBindingRepresentation( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, ComponentMethodRequestRepresentation.Factory componentMethodRequestRepresentationFactory, @@ -105,7 +105,7 @@ BindingRequest request = bindingRequest(binding.key(), RequestKind.INSTANCE); Optional<ComponentMethodDescriptor> matchingComponentMethod = - graph.componentDescriptor().firstMatchingComponentMethod(request); + graph.findFirstMatchingComponentMethod(request); ShardImplementation shardImplementation = componentImplementation.shardImplementation(binding); @@ -133,7 +133,7 @@ } } - private static boolean requiresMethodEncapsulation(ProvisionBinding binding) { + private static boolean requiresMethodEncapsulation(ContributionBinding binding) { switch (binding.kind()) { case COMPONENT: case COMPONENT_PROVISION: @@ -165,6 +165,6 @@ @AssistedFactory static interface Factory { - DirectInstanceBindingRepresentation create(ProvisionBinding binding); + DirectInstanceBindingRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/FactoryGenerator.java b/java/dagger/internal/codegen/writing/FactoryGenerator.java index 32195ba..a6a4a71 100644 --- a/java/dagger/internal/codegen/writing/FactoryGenerator.java +++ b/java/dagger/internal/codegen/writing/FactoryGenerator.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkArgument; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; @@ -24,28 +25,43 @@ import static dagger.internal.codegen.binding.SourceFiles.bindingTypeElementTypeVariableNames; import static dagger.internal.codegen.binding.SourceFiles.generateBindingFieldsForDependencies; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; +import static dagger.internal.codegen.binding.SourceFiles.generatedProxyMethodName; import static dagger.internal.codegen.binding.SourceFiles.parameterizedGeneratedTypeNameForBinding; import static dagger.internal.codegen.extension.DaggerStreams.presentValues; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; +import static dagger.internal.codegen.javapoet.CodeBlocks.parameterNames; 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.writing.InjectionMethods.copyParameter; +import static dagger.internal.codegen.writing.InjectionMethods.copyParameters; +import static dagger.internal.codegen.xprocessing.XElements.asConstructor; +import static dagger.internal.codegen.xprocessing.XElements.asMethod; +import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; +import static dagger.internal.codegen.xprocessing.XTypeElements.typeVariableNames; 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.XConstructorElement; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableElement; 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.XType; +import androidx.room.compiler.processing.XTypeElement; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ClassName; @@ -53,12 +69,16 @@ import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; -import dagger.internal.Factory; +import dagger.internal.Preconditions; import dagger.internal.codegen.base.SourceFileGenerator; import dagger.internal.codegen.base.UniqueNameSet; -import dagger.internal.codegen.binding.Binding; +import dagger.internal.codegen.binding.AssistedInjectionBinding; +import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.InjectionBinding; +import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.binding.SourceFiles; import dagger.internal.codegen.compileroption.CompilerOptions; @@ -70,16 +90,17 @@ 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.Nullability; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import javax.inject.Inject; -/** - * Generates {@link Factory} implementations from {@link ProvisionBinding} instances for {@link - * Inject} constructors. - */ -public final class FactoryGenerator extends SourceFileGenerator<ProvisionBinding> { +/** Generates factory implementation for injection, assisted injection, and provision bindings. */ +public final class FactoryGenerator extends SourceFileGenerator<ContributionBinding> { + private static final ImmutableSet<BindingKind> VALID_BINDING_KINDS = + ImmutableSet.of(BindingKind.INJECTION, BindingKind.ASSISTED_INJECTION, BindingKind.PROVISION); + private final CompilerOptions compilerOptions; private final SourceFiles sourceFiles; @@ -95,145 +116,174 @@ } @Override - public XElement originatingElement(ProvisionBinding binding) { + public XElement originatingElement(ContributionBinding binding) { // we only create factories for bindings that have a binding element return binding.bindingElement().get(); } @Override - public ImmutableList<TypeSpec.Builder> topLevelTypes(ProvisionBinding binding) { + public ImmutableList<TypeSpec.Builder> topLevelTypes(ContributionBinding binding) { // We don't want to write out resolved bindings -- we want to write out the generic version. checkArgument(!binding.unresolved().isPresent()); checkArgument(binding.bindingElement().isPresent()); - - if (binding.kind() == BindingKind.DELEGATE) { - return ImmutableList.of(); - } + checkArgument(VALID_BINDING_KINDS.contains(binding.kind())); return ImmutableList.of(factoryBuilder(binding)); } - private TypeSpec.Builder factoryBuilder(ProvisionBinding binding) { + private TypeSpec.Builder factoryBuilder(ContributionBinding binding) { TypeSpec.Builder factoryBuilder = - classBuilder(generatedClassNameForBinding(binding)) + classBuilder(toJavaPoet(generatedClassNameForBinding(binding))) .addModifiers(PUBLIC, FINAL) - .addTypeVariables(bindingTypeElementTypeVariableNames(binding)); - - if (binding.kind() == BindingKind.INJECTION - || binding.kind() == BindingKind.ASSISTED_INJECTION - || binding.kind() == BindingKind.PROVISION) { - factoryBuilder.addAnnotation(scopeMetadataAnnotation(binding)); - factoryBuilder.addAnnotation(qualifierMetadataAnnotation(binding)); - } + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .addAnnotation(scopeMetadataAnnotation(binding)) + .addAnnotation(qualifierMetadataAnnotation(binding)); factoryTypeName(binding).ifPresent(factoryBuilder::addSuperinterface); - addConstructorAndFields(binding, factoryBuilder); - factoryBuilder.addMethod(getMethod(binding)); - addCreateMethod(binding, factoryBuilder); - - factoryBuilder.addMethod(ProvisionMethod.create(binding, compilerOptions)); + FactoryFields factoryFields = FactoryFields.create(binding); + // If the factory has no input fields we can use a static instance holder to create a + // singleton instance of the factory. Otherwise, we create a new instance via the constructor. + if (factoryFields.isEmpty()) { + factoryBuilder.addType(staticInstanceHolderType(binding)); + } else { + factoryBuilder + .addFields(factoryFields.getAll()) + .addMethod(constructorMethod(factoryFields)); + } gwtIncompatibleAnnotation(binding).ifPresent(factoryBuilder::addAnnotation); - return factoryBuilder; + return factoryBuilder + .addMethod(getMethod(binding, factoryFields)) + .addMethods(staticCreateMethod(binding, factoryFields)) + .addMethod(staticProxyMethod(binding)); } - private void addConstructorAndFields(ProvisionBinding binding, TypeSpec.Builder factoryBuilder) { - if (FactoryCreationStrategy.of(binding) == FactoryCreationStrategy.SINGLETON_INSTANCE) { - return; + // private static final class InstanceHolder { + // static final FooModule_ProvidesFooFactory INSTANCE = + // new FooModule_ProvidesFooFactory(); + // } + private TypeSpec staticInstanceHolderType(ContributionBinding binding) { + ClassName generatedClassName = toJavaPoet(generatedClassNameForBinding(binding)); + FieldSpec.Builder instanceHolderFieldBuilder = + FieldSpec.builder(generatedClassName, "INSTANCE", STATIC, FINAL) + .initializer("new $T()", generatedClassName); + if (!bindingTypeElementTypeVariableNames(binding).isEmpty()) { + // If the factory has type parameters, ignore them in the field declaration & initializer + instanceHolderFieldBuilder.addAnnotation(suppressWarnings(RAWTYPES)); } + return TypeSpec.classBuilder(instanceHolderClassName(binding)) + .addModifiers(PRIVATE, STATIC, FINAL) + .addField(instanceHolderFieldBuilder.build()) + .build(); + } + + private static ClassName instanceHolderClassName(ContributionBinding binding) { + return toJavaPoet(generatedClassNameForBinding(binding).nestedClass("InstanceHolder")); + } + + // public FooModule_ProvidesFooFactory( + // FooModule module, + // Provider<Bar> barProvider, + // Provider<Baz> bazProvider) { + // this.module = module; + // this.barProvider = barProvider; + // this.bazProvider = bazProvider; + // } + private MethodSpec constructorMethod(FactoryFields factoryFields) { // TODO(bcorso): Make the constructor private? MethodSpec.Builder constructor = constructorBuilder().addModifiers(PUBLIC); - constructorParams(binding).forEach( - param -> { - constructor.addParameter(param).addStatement("this.$1N = $1N", param); - factoryBuilder.addField( - FieldSpec.builder(param.type, param.name, PRIVATE, FINAL).build()); - }); - factoryBuilder.addMethod(constructor.build()); + factoryFields.getAll().forEach( + field -> + constructor + .addParameter(field.type, field.name) + .addStatement("this.$1N = $1N", field)); + return constructor.build(); } - private ImmutableList<ParameterSpec> constructorParams(ProvisionBinding binding) { - ImmutableList.Builder<ParameterSpec> params = ImmutableList.builder(); - moduleParameter(binding).ifPresent(params::add); - frameworkFields(binding).values().forEach(field -> params.add(toParameter(field))); - return params.build(); - } - - private Optional<ParameterSpec> moduleParameter(ProvisionBinding binding) { - if (binding.requiresModuleInstance()) { - // TODO(bcorso, dpb): Should this use contributingModule()? - TypeName type = binding.bindingTypeElement().get().getType().getTypeName(); - return Optional.of(ParameterSpec.builder(type, "module").build()); - } - return Optional.empty(); - } - - private ImmutableMap<DependencyRequest, FieldSpec> frameworkFields(ProvisionBinding binding) { - UniqueNameSet uniqueFieldNames = new UniqueNameSet(); - // TODO(bcorso, dpb): Add a test for the case when a Factory parameter is named "module". - moduleParameter(binding).ifPresent(module -> uniqueFieldNames.claim(module.name)); - // We avoid Maps.transformValues here because it would implicitly depend on the order in which - // the transform function is evaluated on each entry in the map. - ImmutableMap.Builder<DependencyRequest, FieldSpec> builder = ImmutableMap.builder(); - generateBindingFieldsForDependencies(binding).forEach( - (dependency, field) -> - builder.put(dependency, - FieldSpec.builder( - field.type(), uniqueFieldNames.getUniqueName(field.name()), PRIVATE, FINAL) - .build())); - return builder.build(); - } - - private void addCreateMethod(ProvisionBinding binding, TypeSpec.Builder factoryBuilder) { - // If constructing a factory for @Inject or @Provides bindings, we use a static create method - // so that generated components can avoid having to refer to the generic types - // of the factory. (Otherwise they may have visibility problems referring to the types.) + // Example 1: no dependencies. + // public static FooModule_ProvidesFooFactory create() { + // return InstanceHolder.INSTANCE; + // } + // + // Example 2: with dependencies. + // public static FooModule_ProvidesFooFactory create( + // FooModule module, + // Provider<Bar> barProvider, + // Provider<Baz> bazProvider) { + // return new FooModule_ProvidesFooFactory(module, barProvider, bazProvider); + // } + private ImmutableList<MethodSpec> staticCreateMethod( + ContributionBinding binding, FactoryFields factoryFields) { + // We use a static create method so that generated components can avoid having to refer to the + // generic types of the factory. (Otherwise they may have visibility problems referring to the + // types.) + ImmutableList.Builder<MethodSpec> methodsBuilder = ImmutableList.builder(); MethodSpec.Builder createMethodBuilder = methodBuilder("create") .addModifiers(PUBLIC, STATIC) .returns(parameterizedGeneratedTypeNameForBinding(binding)) .addTypeVariables(bindingTypeElementTypeVariableNames(binding)); - switch (FactoryCreationStrategy.of(binding)) { - case SINGLETON_INSTANCE: - FieldSpec.Builder instanceFieldBuilder = - FieldSpec.builder( - generatedClassNameForBinding(binding), "INSTANCE", PRIVATE, STATIC, FINAL) - .initializer("new $T()", generatedClassNameForBinding(binding)); - - if (!bindingTypeElementTypeVariableNames(binding).isEmpty()) { - // If the factory has type parameters, ignore them in the field declaration & initializer - instanceFieldBuilder.addAnnotation(suppressWarnings(RAWTYPES)); - createMethodBuilder.addAnnotation(suppressWarnings(UNCHECKED)); - } - - ClassName instanceHolderName = - generatedClassNameForBinding(binding).nestedClass("InstanceHolder"); - createMethodBuilder.addStatement("return $T.INSTANCE", instanceHolderName); - factoryBuilder.addType( - TypeSpec.classBuilder(instanceHolderName) - .addModifiers(PRIVATE, STATIC, FINAL) - .addField(instanceFieldBuilder.build()) - .build()); - break; - case CLASS_CONSTRUCTOR: - List<ParameterSpec> params = constructorParams(binding); - createMethodBuilder.addParameters(params); - createMethodBuilder.addStatement( - "return new $T($L)", - parameterizedGeneratedTypeNameForBinding(binding), - makeParametersCodeBlock(Lists.transform(params, input -> CodeBlock.of("$N", input)))); - break; - default: - throw new AssertionError(); + if (factoryFields.isEmpty()) { + if (!bindingTypeElementTypeVariableNames(binding).isEmpty()) { + createMethodBuilder.addAnnotation(suppressWarnings(UNCHECKED)); + } + createMethodBuilder.addStatement("return $T.INSTANCE", instanceHolderClassName(binding)); + } else { + ImmutableList<ParameterSpec> parameters = + factoryFields.getAll().stream() + .map(field -> ParameterSpec.builder(field.type, field.name).build()) + .collect(toImmutableList()); + createMethodBuilder + .addParameters(parameters) + .addStatement( + "return new $T($L)", + parameterizedGeneratedTypeNameForBinding(binding), + parameterNames(parameters)); + // If any of the parameters take a Dagger Provider type, we also need to make a + // Javax Provider type for backwards compatibility with components generated at + // an older version. + // Eventually, we will need to remove this and break backwards compatibility + // in order to fully cut the Javax dependency. + if (hasDaggerProviderParams(parameters)) { + methodsBuilder.add(javaxCreateMethod(binding, parameters)); + } } - factoryBuilder.addMethod(createMethodBuilder.build()); + methodsBuilder.add(createMethodBuilder.build()); + return methodsBuilder.build(); } - private MethodSpec getMethod(ProvisionBinding binding) { + private MethodSpec javaxCreateMethod( + ContributionBinding binding, ImmutableList<ParameterSpec> parameters) { + ImmutableList<ParameterSpec> remappedParams = remapParamsToJavaxProvider(parameters); + return methodBuilder("create") + .addModifiers(PUBLIC, STATIC) + .returns(parameterizedGeneratedTypeNameForBinding(binding)) + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .addParameters(remappedParams) + .addStatement( + "return new $T($L)", + parameterizedGeneratedTypeNameForBinding(binding), + wrappedParametersCodeBlock(remappedParams)) + .build(); + } + + // Example 1: Provision binding. + // @Override + // public Foo get() { + // return provideFoo(module, barProvider.get(), bazProvider.get()); + // } + // + // Example 2: Injection binding with some inject field. + // @Override + // public Foo get() { + // Foo instance = newInstance(barProvider.get(), bazProvider.get()); + // Foo_MembersInjector.injectSomeField(instance, someFieldProvider.get()); + // return instance; + // } + private MethodSpec getMethod(ContributionBinding binding, FactoryFields factoryFields) { UniqueNameSet uniqueFieldNames = new UniqueNameSet(); - ImmutableMap<DependencyRequest, FieldSpec> frameworkFields = frameworkFields(binding); - frameworkFields.values().forEach(field -> uniqueFieldNames.claim(field.name)); + factoryFields.getAll().forEach(field -> uniqueFieldNames.claim(field.name)); ImmutableMap<XExecutableParameterElement, ParameterSpec> assistedParameters = assistedParameters(binding).stream() .collect( @@ -258,31 +308,31 @@ binding, request -> sourceFiles.frameworkTypeUsageStatement( - CodeBlock.of("$N", frameworkFields.get(request)), request.kind()), + CodeBlock.of("$N", factoryFields.get(request)), request.kind()), param -> assistedParameters.get(param).name, - generatedClassNameForBinding(binding), - moduleParameter(binding).map(module -> CodeBlock.of("$N", module)), + toJavaPoet(generatedClassNameForBinding(binding)), + factoryFields.moduleField.map(module -> CodeBlock.of("$N", module)), compilerOptions); if (binding.kind().equals(PROVISION)) { binding .nullability() - .nullableAnnotations() + .nonTypeUseNullableAnnotations() .forEach(getMethod::addAnnotation); - getMethod.returns(providedTypeName); - getMethod.addStatement("return $L", invokeNewInstance); - } else if (!binding.injectionSites().isEmpty()) { + getMethod.addStatement("return $L", invokeNewInstance).returns(providedTypeName); + } else if (!injectionSites(binding).isEmpty()) { CodeBlock instance = CodeBlock.of("instance"); getMethod .returns(providedTypeName) .addStatement("$T $L = $L", providedTypeName, instance, invokeNewInstance) .addCode( InjectionSiteMethod.invokeAll( - binding.injectionSites(), - generatedClassNameForBinding(binding), + injectionSites(binding), + toJavaPoet(generatedClassNameForBinding(binding)), instance, binding.key().type().xprocessing(), - sourceFiles.frameworkFieldUsages(binding.dependencies(), frameworkFields)::get)) + sourceFiles.frameworkFieldUsages( + binding.dependencies(), factoryFields.frameworkFields)::get)) .addStatement("return $L", instance); } else { @@ -293,7 +343,104 @@ return getMethod.build(); } - private AnnotationSpec scopeMetadataAnnotation(ProvisionBinding binding) { + private MethodSpec staticProxyMethod(ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + case ASSISTED_INJECTION: + return staticProxyMethodForInjection(binding); + case PROVISION: + return staticProxyMethodForProvision((ProvisionBinding) binding); + default: + throw new AssertionError("Unexpected binding kind: " + binding); + } + } + + // Example: + // + // public static Foo newInstance(Bar bar, Baz baz) { + // return new Foo(bar, baz); + // } + private static MethodSpec staticProxyMethodForInjection(ContributionBinding binding) { + XConstructorElement constructor = asConstructor(binding.bindingElement().get()); + XTypeElement enclosingType = constructor.getEnclosingElement(); + MethodSpec.Builder builder = + methodBuilder(generatedProxyMethodName(binding)) + .addModifiers(PUBLIC, STATIC) + .varargs(constructor.isVarArgs()) + .returns(enclosingType.getType().getTypeName()) + .addTypeVariables(typeVariableNames(enclosingType)) + .addExceptions(getThrownTypes(constructor)); + CodeBlock arguments = copyParameters(builder, new UniqueNameSet(), constructor.getParameters()); + return builder + .addStatement("return new $T($L)", enclosingType.getType().getTypeName(), arguments) + .build(); + } + + // Example: + // + // public static Foo provideFoo(FooModule module, Bar bar, Baz baz) { + // return Preconditions.checkNotNullFromProvides(module.provideFoo(bar, baz)); + // } + private MethodSpec staticProxyMethodForProvision(ProvisionBinding binding) { + XMethodElement method = asMethod(binding.bindingElement().get()); + MethodSpec.Builder builder = + methodBuilder(generatedProxyMethodName(binding)) + .addModifiers(PUBLIC, STATIC) + .varargs(method.isVarArgs()) + .addExceptions(getThrownTypes(method)); + + XTypeElement enclosingType = asTypeElement(method.getEnclosingElement()); + UniqueNameSet parameterNameSet = new UniqueNameSet(); + CodeBlock module; + if (method.isStatic() || enclosingType.isCompanionObject()) { + module = CodeBlock.of("$T", enclosingType.getClassName()); + } else if (enclosingType.isKotlinObject()) { + // Call through the singleton instance. + // See: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-methods + module = CodeBlock.of("$T.INSTANCE", enclosingType.getClassName()); + } else { + builder.addTypeVariables(typeVariableNames(enclosingType)); + module = copyInstance(builder, parameterNameSet, enclosingType.getType()); + } + CodeBlock arguments = copyParameters(builder, parameterNameSet, method.getParameters()); + CodeBlock invocation = CodeBlock.of("$L.$L($L)", module, method.getJvmName(), arguments); + + Nullability nullability = Nullability.of(method); + nullability + .nonTypeUseNullableAnnotations() + .forEach(builder::addAnnotation); + return builder + .returns( + method.getReturnType().getTypeName() + .annotated( + nullability.typeUseNullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableList()))) + .addStatement("return $L", maybeWrapInCheckForNull(binding, invocation)) + .build(); + } + + private CodeBlock maybeWrapInCheckForNull(ProvisionBinding binding, CodeBlock codeBlock) { + return binding.shouldCheckForNull(compilerOptions) + ? CodeBlock.of("$T.checkNotNullFromProvides($L)", Preconditions.class, codeBlock) + : codeBlock; + } + + private static CodeBlock copyInstance( + MethodSpec.Builder methodBuilder, UniqueNameSet parameterNameSet, XType type) { + return copyParameter( + methodBuilder, + type, + parameterNameSet.getUniqueName("instance"), + /* useObject= */ false, + Nullability.NOT_NULLABLE); + } + + private static ImmutableList<TypeName> getThrownTypes(XExecutableElement executable) { + return executable.getThrownTypes().stream().map(XType::getTypeName).collect(toImmutableList()); + } + + private AnnotationSpec scopeMetadataAnnotation(ContributionBinding binding) { AnnotationSpec.Builder builder = AnnotationSpec.builder(TypeNames.SCOPE_METADATA); binding.scope() .map(Scope::scopeAnnotation) @@ -303,12 +450,13 @@ return builder.build(); } - private AnnotationSpec qualifierMetadataAnnotation(ProvisionBinding binding) { + private AnnotationSpec qualifierMetadataAnnotation(ContributionBinding binding) { AnnotationSpec.Builder builder = AnnotationSpec.builder(TypeNames.QUALIFIER_METADATA); - // Collect all qualifiers on the binding itself or its dependencies + // Collect all qualifiers on the binding itself or its dependencies. For injection bindings, we + // don't include the injection sites, as that is handled by MembersInjectorFactory. Stream.concat( Stream.of(binding.key()), - binding.provisionDependencies().stream().map(DependencyRequest::key)) + provisionDependencies(binding).stream().map(DependencyRequest::key)) .map(Key::qualifier) .flatMap(presentValues()) .map(DaggerAnnotation::className) @@ -318,44 +466,148 @@ return builder.build(); } - private static TypeName providedTypeName(ProvisionBinding binding) { - return binding.contributedType().getTypeName(); + private ImmutableSet<DependencyRequest> provisionDependencies(ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + return ((InjectionBinding) binding).constructorDependencies(); + case ASSISTED_INJECTION: + return ((AssistedInjectionBinding) binding).constructorDependencies(); + case PROVISION: + return ((ProvisionBinding) binding).dependencies(); + default: + throw new AssertionError("Unexpected binding kind: " + binding.kind()); + } } - private static Optional<TypeName> factoryTypeName(ProvisionBinding binding) { + private ImmutableSet<InjectionSite> injectionSites(ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + return ((InjectionBinding) binding).injectionSites(); + case ASSISTED_INJECTION: + return ((AssistedInjectionBinding) binding).injectionSites(); + case PROVISION: + return ImmutableSet.of(); + default: + throw new AssertionError("Unexpected binding kind: " + binding.kind()); + } + } + + private static TypeName providedTypeName(ContributionBinding binding) { + return binding + .contributedType() + .getTypeName() + .annotated( + binding.nullability().typeUseNullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableList())); + } + + private static Optional<TypeName> factoryTypeName(ContributionBinding binding) { return binding.kind() == BindingKind.ASSISTED_INJECTION ? Optional.empty() : Optional.of(factoryOf(providedTypeName(binding))); } - private static ParameterSpec toParameter(FieldSpec field) { - return ParameterSpec.builder(field.type, field.name).build(); + // Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator + static boolean hasDaggerProviderParams(List<ParameterSpec> params) { + return params.stream().anyMatch(param -> isDaggerProviderType(param.type)); } - /** The strategy for getting an instance of a factory for a {@link Binding}. */ - private enum FactoryCreationStrategy { - /** The factory class is a single instance. */ - SINGLETON_INSTANCE, - /** The factory must be created by calling the constructor. */ - CLASS_CONSTRUCTOR; + // Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator + // Returns a code block that represents a parameter list where any javax Provider + // types are wrapped in an asDaggerProvider call + static CodeBlock wrappedParametersCodeBlock(List<ParameterSpec> params) { + return makeParametersCodeBlock( + Lists.transform( + params, + input -> + isProviderType(input.type) + ? CodeBlock.of( + "$T.asDaggerProvider($N)", TypeNames.DAGGER_PROVIDERS, input) + : CodeBlock.of("$N", input))); + } - static FactoryCreationStrategy of(Binding binding) { - switch (binding.kind()) { - case DELEGATE: - throw new AssertionError("Delegate bindings don't have a factory."); - case PROVISION: - return binding.dependencies().isEmpty() && !binding.requiresModuleInstance() - ? SINGLETON_INSTANCE - : CLASS_CONSTRUCTOR; - case INJECTION: - case MULTIBOUND_SET: - case MULTIBOUND_MAP: - return binding.dependencies().isEmpty() - ? SINGLETON_INSTANCE - : CLASS_CONSTRUCTOR; - default: - return CLASS_CONSTRUCTOR; + // Open for sharing with ProducerFactoryGenerator and MembersInjectorGenerator + static ImmutableList<ParameterSpec> remapParamsToJavaxProvider(List<ParameterSpec> params) { + return params.stream() + .map(param -> ParameterSpec.builder( + remapDaggerProviderToProvider(param.type), param.name).build()) + .collect(toImmutableList()); + } + + private static boolean isDaggerProviderType(TypeName type) { + return type instanceof ParameterizedTypeName + && ((ParameterizedTypeName) type).rawType.equals(TypeNames.DAGGER_PROVIDER); + } + + private static boolean isProviderType(TypeName type) { + return type instanceof ParameterizedTypeName + && ((ParameterizedTypeName) type).rawType.equals(TypeNames.PROVIDER); + } + + private static TypeName remapDaggerProviderToProvider(TypeName type) { + if (type instanceof ParameterizedTypeName) { + ParameterizedTypeName parameterizedTypeName = (ParameterizedTypeName) type; + if (parameterizedTypeName.rawType.equals(TypeNames.DAGGER_PROVIDER)) { + return ParameterizedTypeName.get( + TypeNames.PROVIDER, parameterizedTypeName.typeArguments.toArray(new TypeName[0])); } } + return type; + } + + /** Represents the available fields in the generated factory class. */ + private static final class FactoryFields { + static FactoryFields create(ContributionBinding binding) { + UniqueNameSet nameSet = new UniqueNameSet(); + // TODO(bcorso, dpb): Add a test for the case when a Factory parameter is named "module". + Optional<FieldSpec> moduleField = + binding.requiresModuleInstance() + ? Optional.of( + createField( + binding.bindingTypeElement().get().getType().getTypeName(), + nameSet.getUniqueName("module"))) + : Optional.empty(); + + ImmutableMap.Builder<DependencyRequest, FieldSpec> frameworkFields = ImmutableMap.builder(); + generateBindingFieldsForDependencies(binding).forEach( + (dependency, field) -> + frameworkFields.put( + dependency, + createField(toJavaPoet(field.type()), nameSet.getUniqueName(field.name())))); + + return new FactoryFields(moduleField, frameworkFields.buildOrThrow()); + } + + private static FieldSpec createField(TypeName type, String name) { + return FieldSpec.builder(type, name, PRIVATE, FINAL).build(); + } + + private final Optional<FieldSpec> moduleField; + private final ImmutableMap<DependencyRequest, FieldSpec> frameworkFields; + + private FactoryFields( + Optional<FieldSpec> moduleField, + ImmutableMap<DependencyRequest, FieldSpec> frameworkFields) { + this.moduleField = moduleField; + this.frameworkFields = frameworkFields; + } + + FieldSpec get(DependencyRequest request) { + return frameworkFields.get(request); + } + + ImmutableList<FieldSpec> getAll() { + return moduleField.isPresent() + ? ImmutableList.<FieldSpec>builder() + .add(moduleField.get()) + .addAll(frameworkFields.values()) + .build() + : frameworkFields.values().asList(); + } + + boolean isEmpty() { + return getAll().isEmpty(); + } } }
diff --git a/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java b/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java index 32f0dde..28dbaba 100644 --- a/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java +++ b/java/dagger/internal/codegen/writing/FrameworkFieldInitializer.java
@@ -16,18 +16,19 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES; import static dagger.internal.codegen.writing.ComponentImplementation.FieldSpecKind.FRAMEWORK_FIELD; import static javax.lang.model.element.Modifier.PRIVATE; +import androidx.room.compiler.codegen.XClassName; +import androidx.room.compiler.codegen.XTypeName; import androidx.room.compiler.processing.XType; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import com.squareup.javapoet.FieldSpec; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; import dagger.internal.DelegateFactory; import dagger.internal.codegen.binding.BindingType; import dagger.internal.codegen.binding.ContributionBinding; @@ -36,6 +37,7 @@ import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; +import dagger.internal.codegen.xprocessing.XTypeNames; import java.util.Optional; /** @@ -56,7 +58,7 @@ * Returns the framework class to use for the field, if different from the one implied by the * binding. This implementation returns {@link Optional#empty()}. */ - default Optional<ClassName> alternativeFrameworkClass() { + default Optional<XClassName> alternativeFrameworkClass() { return Optional.empty(); } } @@ -142,26 +144,27 @@ FrameworkField.forBinding( binding, frameworkInstanceCreationExpression.alternativeFrameworkClass()); - TypeName fieldType = useRawType - ? TypeNames.rawTypeName(contributionBindingField.type()) + XTypeName fieldType = useRawType + ? contributionBindingField.type().getRawTypeName() : contributionBindingField.type(); if (binding.kind() == BindingKind.ASSISTED_INJECTION) { // An assisted injection factory doesn't extend Provider, so we reference the generated // factory type directly (i.e. Foo_Factory<T> instead of Provider<Foo<T>>). - TypeName[] typeParameters = + XTypeName[] typeParameters = binding.key().type().xprocessing().getTypeArguments().stream() - .map(XType::getTypeName) - .toArray(TypeName[]::new); + .map(XType::asTypeName) + .toArray(XTypeName[]::new); fieldType = typeParameters.length == 0 ? generatedClassNameForBinding(binding) - : ParameterizedTypeName.get(generatedClassNameForBinding(binding), typeParameters); + : generatedClassNameForBinding(binding).parametrizedBy(typeParameters); } FieldSpec.Builder contributionField = FieldSpec.builder( - fieldType, shardImplementation.getUniqueFieldName(contributionBindingField.name())); + toJavaPoet(fieldType), + shardImplementation.getUniqueFieldName(contributionBindingField.name())); contributionField.addModifiers(PRIVATE); if (useRawType) { contributionField.addAnnotation(AnnotationSpecs.suppressWarnings(RAWTYPES)); @@ -181,7 +184,7 @@ return binding.bindingType().equals(BindingType.PROVISION) && frameworkInstanceCreationExpression .alternativeFrameworkClass() - .map(TypeNames.PROVIDER::equals) + .map(XTypeNames.PROVIDER::equals) .orElse(true); }
diff --git a/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java b/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java index 037df56..0132a1f 100644 --- a/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/FrameworkInstanceBindingRepresentation.java
@@ -26,15 +26,16 @@ import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingRequest; +import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.DelegateBinding; import dagger.internal.codegen.binding.FrameworkType; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.model.RequestKind; import java.util.HashMap; import java.util.Map; /** Returns request representation that wraps a framework instance expression */ final class FrameworkInstanceBindingRepresentation { - private final ProvisionBinding binding; + private final ContributionBinding binding; private final DerivedFromFrameworkInstanceRequestRepresentation.Factory derivedFromFrameworkInstanceRequestRepresentationFactory; private final ImmediateFutureRequestRepresentation.Factory @@ -45,7 +46,7 @@ @AssistedInject FrameworkInstanceBindingRepresentation( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, DelegateRequestRepresentation.Factory delegateRequestRepresentationFactory, @@ -63,7 +64,8 @@ this.immediateFutureRequestRepresentationFactory = immediateFutureRequestRepresentationFactory; this.providerRequestRepresentation = binding.kind().equals(DELEGATE) && !needsCaching(binding, graph) - ? delegateRequestRepresentationFactory.create(binding, RequestKind.PROVIDER) + ? delegateRequestRepresentationFactory.create( + (DelegateBinding) binding, RequestKind.PROVIDER) : providerInstanceRequestRepresentationFactory.create(binding); this.producerFromProviderRepresentation = producerNodeInstanceRequestRepresentationFactory.create( @@ -107,6 +109,6 @@ @AssistedFactory static interface Factory { - FrameworkInstanceBindingRepresentation create(ProvisionBinding binding); + FrameworkInstanceBindingRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/FrameworkInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/FrameworkInstanceRequestRepresentation.java index cb64b02..04ac362 100644 --- a/java/dagger/internal/codegen/writing/FrameworkInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/FrameworkInstanceRequestRepresentation.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; import static dagger.internal.codegen.xprocessing.XProcessingEnvs.wrapType; @@ -51,7 +52,10 @@ Expression getDependencyExpression(ClassName requestingClass) { MemberSelect memberSelect = frameworkInstanceSupplier.memberSelect(); XType expressionType = - wrapType(frameworkType().frameworkClassName(), binding.contributedType(), processingEnv); + wrapType( + toJavaPoet(frameworkType().frameworkClassName()), + binding.contributedType(), + processingEnv); return Expression.create( isTypeAccessibleFrom(binding.contributedType(), requestingClass.packageName()) || isInlinedFactoryCreation(memberSelect)
diff --git a/java/dagger/internal/codegen/writing/GeneratedImplementation.java b/java/dagger/internal/codegen/writing/GeneratedImplementation.java index 032a3c4..cea01f7 100644 --- a/java/dagger/internal/codegen/writing/GeneratedImplementation.java +++ b/java/dagger/internal/codegen/writing/GeneratedImplementation.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import com.google.common.base.Supplier; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.MethodSpec; @@ -41,6 +42,9 @@ /** Adds the given type to the generated implementation. */ void addType(TypeSpecKind typeKind, TypeSpec typeSpec); + /** Adds a {@link Supplier} for a {@link TypeSpec} to the generated implementation. */ + void addTypeSupplier(Supplier<TypeSpec> typeSupplier); + /** Returns the {@link TypeSpec} for this generated implementation. */ public TypeSpec generate(); }
diff --git a/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java b/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java index 3eaf92d..2c855cc 100644 --- a/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java +++ b/java/dagger/internal/codegen/writing/InaccessibleMapKeyProxyGenerator.java
@@ -32,7 +32,6 @@ 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; /** @@ -72,7 +71,6 @@ // 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))
diff --git a/java/dagger/internal/codegen/writing/InjectionMethods.java b/java/dagger/internal/codegen/writing/InjectionMethods.java index 39c03dd..360adf1 100644 --- a/java/dagger/internal/codegen/writing/InjectionMethods.java +++ b/java/dagger/internal/codegen/writing/InjectionMethods.java
@@ -16,47 +16,28 @@ 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.codegen.XTypeNameKt.toJavaPoet; 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; -import static com.google.common.base.Preconditions.checkArgument; -import static com.squareup.javapoet.MethodSpec.methodBuilder; import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.isAssistedParameter; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; -import static dagger.internal.codegen.binding.SourceFiles.memberInjectedFieldSignatureForVariable; +import static dagger.internal.codegen.binding.SourceFiles.generatedProxyMethodName; +import static dagger.internal.codegen.binding.SourceFiles.membersInjectorMethodName; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.extension.DaggerStreams.toImmutableMap; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; import static dagger.internal.codegen.javapoet.CodeBlocks.toConcatenatedCodeBlock; import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; -import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName; -import static dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom; import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible; import static dagger.internal.codegen.langmodel.Accessibility.isRawTypePubliclyAccessible; -import static dagger.internal.codegen.xprocessing.XElements.asConstructor; import static dagger.internal.codegen.xprocessing.XElements.asExecutable; -import static dagger.internal.codegen.xprocessing.XElements.asField; -import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.asMethodParameter; -import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; -import static dagger.internal.codegen.xprocessing.XTypeElements.typeVariableNames; import static dagger.internal.codegen.xprocessing.XTypes.erasedTypeName; -import static javax.lang.model.element.Modifier.PUBLIC; -import static javax.lang.model.element.Modifier.STATIC; -import androidx.room.compiler.processing.XAnnotation; -import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XExecutableElement; import androidx.room.compiler.processing.XExecutableParameterElement; -import androidx.room.compiler.processing.XFieldElement; -import androidx.room.compiler.processing.XMethodElement; 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.ImmutableMap; @@ -67,17 +48,15 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeName; -import dagger.internal.Preconditions; import dagger.internal.codegen.base.UniqueNameSet; +import dagger.internal.codegen.binding.AssistedInjectionBinding; +import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.InjectionBinding; import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; -import dagger.internal.codegen.binding.Nullability; import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.compileroption.CompilerOptions; -import dagger.internal.codegen.extension.DaggerCollectors; -import dagger.internal.codegen.javapoet.TypeNames; -import dagger.internal.codegen.model.DaggerAnnotation; import dagger.internal.codegen.model.DependencyRequest; -import dagger.internal.codegen.xprocessing.XAnnotations; +import dagger.internal.codegen.xprocessing.Nullability; import java.util.List; import java.util.Optional; import java.util.function.Function; @@ -111,38 +90,13 @@ * </code></pre> */ static final class ProvisionMethod { - // These names are already defined in factories and shouldn't be used for the proxy method name. - private static final ImmutableSet<String> BANNED_PROXY_NAMES = ImmutableSet.of("get", "create"); - - /** - * Returns a method that invokes the binding's {@linkplain ProvisionBinding#bindingElement() - * constructor} and injects the instance's members. - */ - static MethodSpec create(ProvisionBinding binding, CompilerOptions compilerOptions) { - XExecutableElement executableElement = asExecutable(binding.bindingElement().get()); - if (isConstructor(executableElement)) { - return constructorProxy(asConstructor(executableElement)); - } else if (isMethod(executableElement)) { - XMethodElement method = asMethod(executableElement); - String methodName = - BANNED_PROXY_NAMES.contains(getSimpleName(method)) - ? "proxy" + LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(method)) - : getSimpleName(method); - return methodProxy( - method, - methodName, - InstanceCastPolicy.IGNORE, - CheckNotNullPolicy.get(binding, compilerOptions)); - } - throw new AssertionError(executableElement); - } /** * Invokes the injection method for {@code binding}, with the dependencies transformed with the * {@code dependencyUsage} function. */ static CodeBlock invoke( - ProvisionBinding binding, + ContributionBinding binding, Function<DependencyRequest, CodeBlock> dependencyUsage, Function<XExecutableParameterElement, String> uniqueAssistedParameterName, ClassName requestingClass, @@ -153,17 +107,17 @@ invokeArguments(binding, dependencyUsage, uniqueAssistedParameterName) .forEach(arguments::add); - ClassName enclosingClass = generatedClassNameForBinding(binding); - MethodSpec methodSpec = create(binding, compilerOptions); - return invokeMethod(methodSpec, arguments.build(), enclosingClass, requestingClass); + ClassName enclosingClass = toJavaPoet(generatedClassNameForBinding(binding)); + String methodName = generatedProxyMethodName(binding); + return invokeMethod(methodName, arguments.build(), enclosingClass, requestingClass); } static ImmutableList<CodeBlock> invokeArguments( - ProvisionBinding binding, + ContributionBinding binding, Function<DependencyRequest, CodeBlock> dependencyUsage, Function<XExecutableParameterElement, String> uniqueAssistedParameterName) { ImmutableMap<XExecutableParameterElement, DependencyRequest> dependencyRequestMap = - binding.provisionDependencies().stream() + provisionDependencies(binding).stream() .collect( toImmutableMap( request -> asMethodParameter(request.requestElement().get().xprocessing()), @@ -185,38 +139,18 @@ return arguments.build(); } - private static MethodSpec constructorProxy(XConstructorElement constructor) { - XTypeElement enclosingType = constructor.getEnclosingElement(); - MethodSpec.Builder builder = - methodBuilder("newInstance") - .addModifiers(PUBLIC, STATIC) - .varargs(constructor.isVarArgs()) - .returns(enclosingType.getType().getTypeName()) - .addTypeVariables(typeVariableNames(enclosingType)); - - copyThrows(builder, constructor); - - CodeBlock arguments = - copyParameters(builder, new UniqueNameSet(), constructor.getParameters()); - return builder - .addStatement("return new $T($L)", enclosingType.getType().getTypeName(), arguments) - .build(); - } - - /** - * Returns {@code true} if injecting an instance of {@code binding} from {@code callingPackage} - * requires the use of an injection method. - */ - static boolean requiresInjectionMethod( - ProvisionBinding binding, CompilerOptions compilerOptions, ClassName requestingClass) { - XExecutableElement executableElement = asExecutable(binding.bindingElement().get()); - return !binding.injectionSites().isEmpty() - || binding.shouldCheckForNull(compilerOptions) - || !isElementAccessibleFrom(executableElement, requestingClass.packageName()) - // This check should be removable once we drop support for -source 7 - || executableElement.getParameters().stream() - .map(XExecutableParameterElement::getType) - .anyMatch(type -> !isRawTypeAccessible(type, requestingClass.packageName())); + private static ImmutableSet<DependencyRequest> provisionDependencies( + ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + return ((InjectionBinding) binding).constructorDependencies(); + case ASSISTED_INJECTION: + return ((AssistedInjectionBinding) binding).constructorDependencies(); + case PROVISION: + return ((ProvisionBinding) binding).dependencies(); + default: + throw new AssertionError("Unexpected binding kind: " + binding.kind()); + } } } @@ -239,35 +173,6 @@ */ static final class InjectionSiteMethod { /** - * When a type has an inaccessible member from a supertype (e.g. an @Inject field in a parent - * that's in a different package), a method in the supertype's package must be generated to give - * the subclass's members injector a way to inject it. Each potentially inaccessible member - * receives its own method, as the subclass may need to inject them in a different order from - * the parent class. - */ - static MethodSpec create(InjectionSite injectionSite) { - String methodName = methodName(injectionSite); - switch (injectionSite.kind()) { - case METHOD: - return methodProxy( - asMethod(injectionSite.element()), - methodName, - InstanceCastPolicy.CAST_IF_NOT_PUBLIC, - CheckNotNullPolicy.IGNORE); - case FIELD: - Optional<XAnnotation> qualifier = - injectionSite.dependencies().stream() - // methods for fields have a single dependency request - .collect(DaggerCollectors.onlyElement()) - .key() - .qualifier() - .map(DaggerAnnotation::xprocessing); - return fieldProxy(asField(injectionSite.element()), methodName, qualifier); - } - throw new AssertionError(injectionSite); - } - - /** * Invokes each of the injection methods for {@code injectionSites}, with the dependencies * transformed using the {@code dependencyUsage} function. * @@ -318,144 +223,25 @@ .map(dependencyUsage) .collect(toImmutableList())) .build(); - ClassName enclosingClass = membersInjectorNameForType(injectionSite.enclosingTypeElement()); - MethodSpec methodSpec = create(injectionSite); - return invokeMethod(methodSpec, arguments, enclosingClass, generatedTypeName); + ClassName enclosingClass = + toJavaPoet(membersInjectorNameForType(injectionSite.enclosingTypeElement())); + String methodName = membersInjectorMethodName(injectionSite); + return invokeMethod(methodName, arguments, enclosingClass, generatedTypeName); } - - /* - * TODO(ronshapiro): this isn't perfect, as collisions could still exist. Some examples: - * - * - @Inject void members() {} will generate a method that conflicts with the instance - * method `injectMembers(T)` - * - Adding the index could conflict with another member: - * @Inject void a(Object o) {} - * @Inject void a(String s) {} - * @Inject void a1(String s) {} - * - * Here, Method a(String) will add the suffix "1", which will conflict with the method - * generated for a1(String) - * - Members named "members" or "methods" could also conflict with the {@code static} injection - * method. - */ - private static String methodName(InjectionSite injectionSite) { - int index = injectionSite.indexAmongAtInjectMembersWithSameSimpleName(); - String indexString = index == 0 ? "" : String.valueOf(index + 1); - return "inject" - + LOWER_CAMEL.to(UPPER_CAMEL, getSimpleName(injectionSite.element())) - + indexString; - } - } - - private enum InstanceCastPolicy { - CAST_IF_NOT_PUBLIC, IGNORE; - - boolean useObjectType(XType instanceType) { - return this == CAST_IF_NOT_PUBLIC && !isRawTypePubliclyAccessible(instanceType); - } - } - - private enum CheckNotNullPolicy { - IGNORE, CHECK_FOR_NULL; - - CodeBlock checkForNull(CodeBlock maybeNull) { - return this.equals(IGNORE) - ? maybeNull - : CodeBlock.of("$T.checkNotNullFromProvides($L)", Preconditions.class, maybeNull); - } - - static CheckNotNullPolicy get(ProvisionBinding binding, CompilerOptions compilerOptions) { - return binding.shouldCheckForNull(compilerOptions) ? CHECK_FOR_NULL : IGNORE; - } - } - - private static MethodSpec methodProxy( - XMethodElement method, - String methodName, - InstanceCastPolicy instanceCastPolicy, - CheckNotNullPolicy checkNotNullPolicy) { - XTypeElement enclosingType = asTypeElement(method.getEnclosingElement()); - - MethodSpec.Builder builder = - methodBuilder(methodName) - .addModifiers(PUBLIC, STATIC) - .varargs(method.isVarArgs()) - .addTypeVariables(method.getExecutableType().getTypeVariableNames()); - - UniqueNameSet parameterNameSet = new UniqueNameSet(); - CodeBlock instance; - if (method.isStatic() || enclosingType.isCompanionObject()) { - instance = CodeBlock.of("$T", rawTypeName(enclosingType.getType().getTypeName())); - } else if (enclosingType.isKotlinObject()) { - // Call through the singleton instance. - // See: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-methods - instance = CodeBlock.of("$T.INSTANCE", rawTypeName(enclosingType.getType().getTypeName())); - } else { - builder.addTypeVariables(typeVariableNames(enclosingType)); - boolean useObject = instanceCastPolicy.useObjectType(enclosingType.getType()); - instance = copyInstance(builder, parameterNameSet, enclosingType.getType(), useObject); - } - CodeBlock arguments = copyParameters(builder, parameterNameSet, method.getParameters()); - CodeBlock invocation = - checkNotNullPolicy.checkForNull( - CodeBlock.of("$L.$L($L)", instance, method.getJvmName(), arguments)); - - copyThrows(builder, method); - - if (isVoid(method.getReturnType())) { - return builder.addStatement("$L", invocation).build(); - } else { - Nullability nullability = Nullability.of(method); - nullability - .nullableAnnotations() - .forEach(builder::addAnnotation); - return builder - .returns(method.getReturnType().getTypeName()) - .addStatement("return $L", invocation) - .build(); - } - } - - private static MethodSpec fieldProxy( - XFieldElement field, String methodName, Optional<XAnnotation> qualifier) { - XTypeElement enclosingType = asTypeElement(field.getEnclosingElement()); - - MethodSpec.Builder builder = - methodBuilder(methodName) - .addModifiers(PUBLIC, STATIC) - .addAnnotation( - AnnotationSpec.builder(TypeNames.INJECTED_FIELD_SIGNATURE) - .addMember("value", "$S", memberInjectedFieldSignatureForVariable(field)) - .build()) - .addTypeVariables(typeVariableNames(enclosingType)); - - qualifier.map(XAnnotations::getAnnotationSpec).ifPresent(builder::addAnnotation); - - boolean useObject = !isRawTypePubliclyAccessible(enclosingType.getType()); - UniqueNameSet parameterNameSet = new UniqueNameSet(); - CodeBlock instance = - copyInstance(builder, parameterNameSet, enclosingType.getType(), useObject); - CodeBlock argument = copyParameters(builder, parameterNameSet, ImmutableList.of(field)); - return builder.addStatement("$L.$L = $L", instance, getSimpleName(field), argument).build(); } private static CodeBlock invokeMethod( - MethodSpec methodSpec, + String methodName, ImmutableList<CodeBlock> parameters, ClassName enclosingClass, ClassName requestingClass) { - checkArgument(methodSpec.parameters.size() == parameters.size()); CodeBlock parameterBlock = makeParametersCodeBlock(parameters); return enclosingClass.equals(requestingClass) - ? CodeBlock.of("$L($L)", methodSpec.name, parameterBlock) - : CodeBlock.of("$T.$L($L)", enclosingClass, methodSpec.name, parameterBlock); + ? CodeBlock.of("$L($L)", methodName, parameterBlock) + : CodeBlock.of("$T.$L($L)", enclosingClass, methodName, parameterBlock); } - private static void copyThrows(MethodSpec.Builder methodBuilder, XExecutableElement method) { - method.getThrownTypes().stream().map(XType::getTypeName).forEach(methodBuilder::addException); - } - - private static CodeBlock copyParameters( + static CodeBlock copyParameters( MethodSpec.Builder methodBuilder, UniqueNameSet parameterNameSet, List<? extends XVariableElement> parameters) { @@ -468,26 +254,29 @@ ? asMethodParameter(parameter).getJvmName() : getSimpleName(parameter)); boolean useObject = !isRawTypePubliclyAccessible(parameter.getType()); - return copyParameter(methodBuilder, parameter.getType(), name, useObject); + return copyParameter( + methodBuilder, parameter.getType(), name, useObject, Nullability.of(parameter)); }) .collect(toParametersCodeBlock()); } - private static CodeBlock copyParameter( - MethodSpec.Builder methodBuilder, XType type, String name, boolean useObject) { - TypeName typeName = useObject ? TypeName.OBJECT : type.getTypeName(); - methodBuilder.addParameter(ParameterSpec.builder(typeName, name).build()); - return useObject ? CodeBlock.of("($T) $L", type.getTypeName(), name) : CodeBlock.of("$L", name); - } - - private static CodeBlock copyInstance( + static CodeBlock copyParameter( MethodSpec.Builder methodBuilder, - UniqueNameSet parameterNameSet, XType type, - boolean useObject) { - CodeBlock instance = - copyParameter(methodBuilder, type, parameterNameSet.getUniqueName("instance"), useObject); - // 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; + String name, + boolean useObject, + Nullability nullability) { + TypeName typeName = useObject ? TypeName.OBJECT : type.getTypeName(); + nullability.typeUseNullableAnnotations().stream() + .map(it -> AnnotationSpec.builder(it).build()) + .forEach(typeName::annotated); + methodBuilder.addParameter( + ParameterSpec.builder(typeName, name) + .addAnnotations( + nullability.nonTypeUseNullableAnnotations().stream() + .map(it -> AnnotationSpec.builder(it).build()) + .collect(toImmutableList())) + .build()); + return useObject ? CodeBlock.of("($T) $L", type.getTypeName(), name) : CodeBlock.of("$L", name); } }
diff --git a/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java b/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java index 27e017d..3d8fd86 100644 --- a/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/InjectionOrProvisionProviderCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; @@ -66,7 +67,7 @@ @Override public CodeBlock creationExpression() { - ClassName factoryImpl = generatedClassNameForBinding(binding); + ClassName factoryImpl = toJavaPoet(generatedClassNameForBinding(binding)); CodeBlock createFactory = CodeBlock.of( "$T.$L($L)",
diff --git a/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java b/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java deleted file mode 100644 index 2c25811..0000000 --- a/java/dagger/internal/codegen/writing/LazyClassKeyProviders.java +++ /dev/null
@@ -1,117 +0,0 @@ -/* - * 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/LazyMapKeyProxyGenerator.java b/java/dagger/internal/codegen/writing/LazyMapKeyProxyGenerator.java new file mode 100644 index 0000000..a5b15f2 --- /dev/null +++ b/java/dagger/internal/codegen/writing/LazyMapKeyProxyGenerator.java
@@ -0,0 +1,97 @@ +/* + * 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 com.squareup.javapoet.TypeSpec.classBuilder; +import static dagger.internal.codegen.binding.MapKeys.KEEP_FIELD_TYPE_FIELD; +import static dagger.internal.codegen.binding.MapKeys.LAZY_CLASS_KEY_NAME_FIELD; +import static dagger.internal.codegen.binding.MapKeys.lazyClassKeyProxyClassName; +import static javax.lang.model.element.Modifier.FINAL; +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.XFiler; +import androidx.room.compiler.processing.XMethodElement; +import androidx.room.compiler.processing.XProcessingEnv; +import com.google.common.collect.ImmutableList; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.TypeSpec; +import dagger.internal.codegen.base.SourceFileGenerator; +import dagger.internal.codegen.javapoet.TypeNames; +import javax.inject.Inject; + +/** + * Generate a class containing fields that works with proguard rules to support @LazyClassKey + * usages. + */ +public final class LazyMapKeyProxyGenerator extends SourceFileGenerator<XMethodElement> { + + @Inject + LazyMapKeyProxyGenerator(XFiler filer, XProcessingEnv processingEnv) { + super(filer, processingEnv); + } + + @Override + public XElement originatingElement(XMethodElement input) { + return input; + } + + @Override + public ImmutableList<TypeSpec.Builder> topLevelTypes(XMethodElement input) { + return ImmutableList.of(lazyClassKeyProxyTypeSpec(input).toBuilder()); + } + + private TypeSpec lazyClassKeyProxyTypeSpec(XMethodElement element) { + return classBuilder(lazyClassKeyProxyClassName(element)) + .addModifiers(PUBLIC, FINAL) + .addAnnotation(TypeNames.IDENTIFIER_NAME_STRING) + .addFields(lazyClassKeyFields(element)) + .build(); + } + + private static ImmutableList<FieldSpec> lazyClassKeyFields(XMethodElement element) { + ClassName lazyClassMapKeyClassName = + element + .getAnnotation(TypeNames.LAZY_CLASS_KEY) + .getAsType("value") + .getTypeElement() + .getClassName(); + // Generate a string referencing the map key class name, and dagger will apply + // identifierrnamestring rule to it to make sure it is correctly obfuscated. + FieldSpec lazyClassKeyField = + FieldSpec.builder(TypeNames.STRING, LAZY_CLASS_KEY_NAME_FIELD) + // 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, PUBLIC) + .initializer("$S", lazyClassMapKeyClassName.reflectionName()) + .build(); + // 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. + FieldSpec keepFieldTypeField = + FieldSpec.builder(lazyClassMapKeyClassName, KEEP_FIELD_TYPE_FIELD) + .addModifiers(STATIC) + .addAnnotation(TypeNames.KEEP_FIELD_TYPE) + .build(); + return ImmutableList.of(keepFieldTypeField, lazyClassKeyField); + } +}
diff --git a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java index 0ea382d..0ac7212 100644 --- a/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java +++ b/java/dagger/internal/codegen/writing/MapFactoryCreationExpression.java
@@ -16,10 +16,11 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; +import static dagger.internal.codegen.binding.MapKeys.getLazyClassMapKeyExpression; import static dagger.internal.codegen.binding.MapKeys.getMapKeyExpression; import static dagger.internal.codegen.binding.SourceFiles.mapFactoryClassName; -import static dagger.internal.codegen.extension.DaggerCollectors.toOptional; import androidx.room.compiler.processing.XProcessingEnv; import com.squareup.javapoet.ClassName; @@ -32,9 +33,9 @@ import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.MapKeys; +import dagger.internal.codegen.binding.MultiboundMapBinding; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; -import java.util.stream.Stream; /** A factory creation expression for a multibound map. */ final class MapFactoryCreationExpression extends MultibindingFactoryCreationExpression { @@ -42,13 +43,12 @@ private final XProcessingEnv processingEnv; private final ComponentImplementation componentImplementation; private final BindingGraph graph; - private final ContributionBinding binding; + private final MultiboundMapBinding binding; private final boolean useLazyClassKey; - private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapFactoryCreationExpression( - @Assisted ContributionBinding binding, + @Assisted MultiboundMapBinding binding, XProcessingEnv processingEnv, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, @@ -59,26 +59,16 @@ this.componentImplementation = componentImplementation; this.graph = graph; this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); - this.lazyClassKeyProviders = - componentImplementation.shardImplementation(binding).getLazyClassKeyProviders(); } @Override public CodeBlock creationExpression() { - ClassName mapFactoryClassName = mapFactoryClassName(binding); + ClassName mapFactoryClassName = toJavaPoet(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 - valueTypeName = - Stream.of(TypeNames.PROVIDER, TypeNames.PRODUCER, TypeNames.PRODUCED) - .filter(mapType::valuesAreTypeOf) - .map(mapType::unwrappedValueType) - .collect(toOptional()) - .orElseGet(mapType::valueType) - .getTypeName(); + valueTypeName = mapType.unwrappedFrameworkValueType().getTypeName(); builder.add( "<$T, $T>", useLazyClassKey ? TypeNames.STRING : mapType.keyType().getTypeName(), @@ -92,7 +82,7 @@ builder.add( ".put($L, $L)", useLazyClassKey - ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + ? getLazyClassMapKeyExpression(graph.contributionBinding(dependency.key())) : getMapKeyExpression( contributionBinding, componentImplementation.name(), processingEnv), multibindingDependencyExpression(dependency)); @@ -101,14 +91,32 @@ return useLazyClassKey ? CodeBlock.of( "$T.<$T>of($L)", - TypeNames.LAZY_CLASS_KEY_MAP_FACTORY, + lazyMapFactoryClassName(binding), valueTypeName, builder.add(".build()").build()) : builder.add(".build()").build(); } + private static ClassName lazyMapFactoryClassName(MultiboundMapBinding binding) { + MapType mapType = MapType.from(binding.key()); + switch (binding.bindingType()) { + case PROVISION: + return mapType.valuesAreTypeOf(TypeNames.PROVIDER) + ? TypeNames.LAZY_CLASS_KEY_MAP_PROVIDER_FACTORY + : TypeNames.LAZY_CLASS_KEY_MAP_FACTORY; + case PRODUCTION: + return mapType.valuesAreFrameworkType() + ? mapType.valuesAreTypeOf(TypeNames.PRODUCER) + ? TypeNames.LAZY_MAP_OF_PRODUCER_PRODUCER + : TypeNames.LAZY_MAP_OF_PRODUCED_PRODUCER + : TypeNames.LAZY_MAP_PRODUCER; + default: + throw new IllegalArgumentException(binding.bindingType().toString()); + } + } + @AssistedFactory static interface Factory { - MapFactoryCreationExpression create(ContributionBinding binding); + MapFactoryCreationExpression create(MultiboundMapBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java index f631d34..a870f66 100644 --- a/java/dagger/internal/codegen/writing/MapRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/MapRequestRepresentation.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.BindingRequest.bindingRequest; +import static dagger.internal.codegen.binding.MapKeys.getLazyClassMapKeyExpression; import static dagger.internal.codegen.binding.MapKeys.getMapKeyExpression; import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; @@ -39,7 +40,7 @@ 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.binding.MultiboundMapBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.BindingKind; @@ -52,15 +53,14 @@ private static final int MAX_IMMUTABLE_MAP_OF_KEY_VALUE_PAIRS = 5; private final XProcessingEnv processingEnv; - private final ProvisionBinding binding; + private final MultiboundMapBinding binding; private final ImmutableMap<DependencyRequest, ContributionBinding> dependencies; private final ComponentRequestRepresentations componentRequestRepresentations; private final boolean useLazyClassKey; - private final LazyClassKeyProviders lazyClassKeyProviders; @AssistedInject MapRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted MultiboundMapBinding binding, XProcessingEnv processingEnv, BindingGraph graph, ComponentImplementation componentImplementation, @@ -73,8 +73,6 @@ this.dependencies = Maps.toMap(binding.dependencies(), dep -> graph.contributionBinding(dep.key())); this.useLazyClassKey = MapKeys.useLazyClassKey(binding, graph); - this.lazyClassKeyProviders = - componentImplementation.shardImplementation(binding).getLazyClassKeyProviders(); } @Override @@ -153,7 +151,7 @@ return CodeBlock.of( "$L, $L", useLazyClassKey - ? lazyClassKeyProviders.getMapKeyExpression(dependency.key()) + ? getLazyClassMapKeyExpression(dependencies.get(dependency)) : getMapKeyExpression(dependencies.get(dependency), requestingClass, processingEnv), componentRequestRepresentations .getDependencyExpression(bindingRequest(dependency), requestingClass) @@ -194,6 +192,6 @@ @AssistedFactory static interface Factory { - MapRequestRepresentation create(ProvisionBinding binding); + MapRequestRepresentation create(MultiboundMapBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/MembersInjectionMethods.java b/java/dagger/internal/codegen/writing/MembersInjectionMethods.java index a00e367..f128de3 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectionMethods.java +++ b/java/dagger/internal/codegen/writing/MembersInjectionMethods.java
@@ -32,11 +32,12 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeName; +import dagger.internal.codegen.binding.AssistedInjectionBinding; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; +import dagger.internal.codegen.binding.InjectionBinding; import dagger.internal.codegen.binding.MembersInjectionBinding; import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; -import dagger.internal.codegen.binding.ProvisionBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; @@ -91,7 +92,7 @@ } private Expression injectMethodExpression(Binding binding) { - // TODO(wanyingd): move Switching Providers and injection methods to Shard classes to avoid + // TODO(bcorso): 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 = componentImplementation.shardImplementation(binding); @@ -105,7 +106,15 @@ // simple names Foo.Builder -> injectFooBuilder String methodName = shardImplementation.getUniqueMethodName("inject" + bindingTypeName); ParameterSpec parameter = - ParameterSpec.builder(membersInjectedType.getTypeName(), "instance").build(); + ParameterSpec.builder( + membersInjectedType.getTypeName(), + // Technically this usage only needs to be unique within this method, but this will + // allocate + // a unique name within the shard. We could optimize this by cloning the + // UniqueNameSet or + // using NameAllocator which has a clone method in the future. + shardImplementation.getUniqueFieldName("instance")) + .build(); MethodSpec.Builder methodBuilder = methodBuilder(methodName) .addModifiers(PRIVATE) @@ -135,11 +144,15 @@ } private static ImmutableSet<InjectionSite> injectionSites(Binding binding) { - if (binding instanceof ProvisionBinding) { - return ((ProvisionBinding) binding).injectionSites(); - } else if (binding instanceof MembersInjectionBinding) { - return ((MembersInjectionBinding) binding).injectionSites(); + switch (binding.kind()) { + case INJECTION: + return ((InjectionBinding) binding).injectionSites(); + case ASSISTED_INJECTION: + return ((AssistedInjectionBinding) binding).injectionSites(); + case MEMBERS_INJECTION: + return ((MembersInjectionBinding) binding).injectionSites(); + default: + throw new IllegalArgumentException("Unexpected binding kind: " + binding.kind()); } - throw new IllegalArgumentException(binding.key().toString()); } }
diff --git a/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java b/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java index f8f31a3..a932a38 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/MembersInjectionRequestRepresentation.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.processing.XTypeKt.isVoid; import static com.google.common.collect.Iterables.getOnlyElement; import androidx.room.compiler.processing.XExecutableParameterElement; @@ -54,6 +55,15 @@ ComponentMethodDescriptor componentMethod, ComponentImplementation component) { XMethodElement methodElement = componentMethod.methodElement(); XExecutableParameterElement parameter = getOnlyElement(methodElement.getParameters()); + if (binding.injectionSites().isEmpty()) { + // If there are no injection sites either do nothing (if the return type is void) or return + // the input instance as-is. + return Expression.create( + methodElement.getReturnType(), + isVoid(methodElement.getReturnType()) + ? CodeBlock.of("") + : CodeBlock.of("$L", parameter.getJvmName())); + } return membersInjectionMethods.getInjectExpression( binding.key(), CodeBlock.of("$L", parameter.getJvmName()), component.name()); }
diff --git a/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java b/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java index 36a9915..1b52eb0 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java +++ b/java/dagger/internal/codegen/writing/MembersInjectorGenerator.java
@@ -16,30 +16,52 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.compat.XConverters.toJavaPoet; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Iterables.getOnlyElement; 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.SourceFiles.bindingTypeElementTypeVariableNames; import static dagger.internal.codegen.binding.SourceFiles.generateBindingFieldsForDependencies; +import static dagger.internal.codegen.binding.SourceFiles.memberInjectedFieldSignatureForVariable; +import static dagger.internal.codegen.binding.SourceFiles.membersInjectorMethodName; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; import static dagger.internal.codegen.binding.SourceFiles.parameterizedGeneratedTypeNameForBinding; import static dagger.internal.codegen.extension.DaggerStreams.presentValues; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.RAWTYPES; -import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; import static dagger.internal.codegen.javapoet.AnnotationSpecs.suppressWarnings; -import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; +import static dagger.internal.codegen.javapoet.CodeBlocks.parameterNames; +import static dagger.internal.codegen.javapoet.CodeBlocks.toConcatenatedCodeBlock; import static dagger.internal.codegen.javapoet.TypeNames.membersInjectorOf; +import static dagger.internal.codegen.langmodel.Accessibility.isRawTypePubliclyAccessible; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; +import static dagger.internal.codegen.writing.FactoryGenerator.hasDaggerProviderParams; +import static dagger.internal.codegen.writing.FactoryGenerator.remapParamsToJavaxProvider; +import static dagger.internal.codegen.writing.FactoryGenerator.wrappedParametersCodeBlock; import static dagger.internal.codegen.writing.GwtCompatibility.gwtIncompatibleAnnotation; +import static dagger.internal.codegen.writing.InjectionMethods.copyParameter; +import static dagger.internal.codegen.writing.InjectionMethods.copyParameters; +import static dagger.internal.codegen.xprocessing.XElements.asField; +import static dagger.internal.codegen.xprocessing.XElements.asMethod; +import static dagger.internal.codegen.xprocessing.XElements.asTypeElement; +import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; +import static dagger.internal.codegen.xprocessing.XTypeElements.typeVariableNames; 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.XAnnotation; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableElement; +import androidx.room.compiler.processing.XFieldElement; import androidx.room.compiler.processing.XFiler; +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.ImmutableList; import com.google.common.collect.ImmutableMap; import com.squareup.javapoet.AnnotationSpec; @@ -54,7 +76,6 @@ import dagger.MembersInjector; import dagger.internal.codegen.base.SourceFileGenerator; import dagger.internal.codegen.base.UniqueNameSet; -import dagger.internal.codegen.binding.FrameworkField; import dagger.internal.codegen.binding.MembersInjectionBinding; import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; import dagger.internal.codegen.binding.SourceFiles; @@ -63,7 +84,10 @@ import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.writing.InjectionMethods.InjectionSiteMethod; -import java.util.Map.Entry; +import dagger.internal.codegen.xprocessing.Nullability; +import dagger.internal.codegen.xprocessing.XAnnotations; +import java.util.List; +import java.util.Optional; import javax.inject.Inject; /** @@ -95,115 +119,218 @@ "tried to generate a MembersInjector for a binding of a resolved generic type: %s", binding); - ClassName generatedTypeName = membersInjectorNameForType(binding.membersInjectedType()); + ClassName generatedTypeName = + toJavaPoet(membersInjectorNameForType(binding.membersInjectedType())); ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding); + ImmutableMap<DependencyRequest, FieldSpec> frameworkFields = frameworkFields(binding); TypeSpec.Builder injectorTypeBuilder = classBuilder(generatedTypeName) .addModifiers(PUBLIC, FINAL) .addTypeVariables(typeParameters) - .addAnnotation(qualifierMetadataAnnotation(binding)); - - TypeName injectedTypeName = binding.key().type().xprocessing().getTypeName(); - TypeName implementedType = membersInjectorOf(injectedTypeName); - injectorTypeBuilder.addSuperinterface(implementedType); - - MethodSpec.Builder injectMembersBuilder = - methodBuilder("injectMembers") - .addModifiers(PUBLIC) - .addAnnotation(Override.class) - .addParameter(injectedTypeName, "instance"); - - ImmutableMap<DependencyRequest, FrameworkField> fields = - generateBindingFieldsForDependencies(binding); - - ImmutableMap.Builder<DependencyRequest, FieldSpec> dependencyFieldsBuilder = - ImmutableMap.builder(); - - MethodSpec.Builder constructorBuilder = constructorBuilder().addModifiers(PUBLIC); - - // We use a static create method so that generated components can avoid having - // to refer to the generic types of the factory. - // (Otherwise they may have visibility problems referring to the types.) - MethodSpec.Builder createMethodBuilder = - methodBuilder("create") - .returns(implementedType) - .addModifiers(PUBLIC, STATIC) - .addTypeVariables(typeParameters); - - createMethodBuilder.addCode( - "return new $T(", parameterizedGeneratedTypeNameForBinding(binding)); - ImmutableList.Builder<CodeBlock> constructorInvocationParameters = ImmutableList.builder(); - - boolean usesRawFrameworkTypes = false; - UniqueNameSet fieldNames = new UniqueNameSet(); - for (Entry<DependencyRequest, FrameworkField> fieldEntry : fields.entrySet()) { - DependencyRequest dependency = fieldEntry.getKey(); - FrameworkField bindingField = fieldEntry.getValue(); - - // If the dependency type is not visible to this members injector, then use the raw framework - // type for the field. - boolean useRawFrameworkType = - !isTypeAccessibleFrom( - dependency.key().type().xprocessing(), generatedTypeName.packageName()); - - String fieldName = fieldNames.getUniqueName(bindingField.name()); - 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); - - // If we're using the raw type for the field, then suppress the injectMembers method's - // unchecked-type warning and the field's and the constructor and create-method's - // parameters' raw-type warnings. - if (useRawFrameworkType) { - usesRawFrameworkTypes = true; - fieldBuilder.addAnnotation(suppressWarnings(RAWTYPES)); - parameterBuilder.addAnnotation(suppressWarnings(RAWTYPES)); - } - constructorBuilder.addParameter(parameterBuilder.build()); - createMethodBuilder.addParameter(parameterBuilder.build()); - - FieldSpec field = fieldBuilder.build(); - injectorTypeBuilder.addField(field); - constructorBuilder.addStatement("this.$1N = $1N", field); - dependencyFieldsBuilder.put(dependency, field); - constructorInvocationParameters.add(CodeBlock.of("$N", field)); - } - - createMethodBuilder.addCode( - constructorInvocationParameters.build().stream().collect(toParametersCodeBlock())); - createMethodBuilder.addCode(");"); - - injectorTypeBuilder.addMethod(constructorBuilder.build()); - injectorTypeBuilder.addMethod(createMethodBuilder.build()); - - ImmutableMap<DependencyRequest, FieldSpec> dependencyFields = dependencyFieldsBuilder.build(); - - injectMembersBuilder.addCode( - InjectionSiteMethod.invokeAll( - binding.injectionSites(), - generatedTypeName, - CodeBlock.of("instance"), - binding.key().type().xprocessing(), - sourceFiles.frameworkFieldUsages(binding.dependencies(), dependencyFields)::get)); - - if (usesRawFrameworkTypes) { - injectMembersBuilder.addAnnotation(suppressWarnings(UNCHECKED)); - } - injectorTypeBuilder.addMethod(injectMembersBuilder.build()); - - for (InjectionSite injectionSite : binding.injectionSites()) { - if (injectionSite.enclosingTypeElement().equals(binding.membersInjectedType())) { - injectorTypeBuilder.addMethod(InjectionSiteMethod.create(injectionSite)); - } - } + .addAnnotation(qualifierMetadataAnnotation(binding)) + .addSuperinterface(membersInjectorOf(binding.key().type().xprocessing().getTypeName())) + .addFields(frameworkFields.values()) + .addMethod(constructor(frameworkFields)) + .addMethods(createMethod(binding, frameworkFields)) + .addMethod(injectMembersMethod(binding, frameworkFields)) + .addMethods( + binding.injectionSites().stream() + .filter( + site -> site.enclosingTypeElement().equals(binding.membersInjectedType())) + .map(MembersInjectorGenerator::membersInjectionMethod) + .collect(toImmutableList())); gwtIncompatibleAnnotation(binding).ifPresent(injectorTypeBuilder::addAnnotation); return ImmutableList.of(injectorTypeBuilder); } + private static MethodSpec membersInjectionMethod(InjectionSite injectionSite) { + String methodName = membersInjectorMethodName(injectionSite); + switch (injectionSite.kind()) { + case METHOD: + return methodInjectionMethod(asMethod(injectionSite.element()), methodName); + case FIELD: + Optional<XAnnotation> qualifier = + // methods for fields have a single dependency request + getOnlyElement(injectionSite.dependencies()) + .key() + .qualifier() + .map(DaggerAnnotation::xprocessing); + return fieldInjectionMethod(asField(injectionSite.element()), methodName, qualifier); + } + throw new AssertionError(injectionSite); + } + + // Example: + // + // public static void injectMethod(Instance instance, Foo foo, Bar bar) { + // instance.injectMethod(foo, bar); + // } + private static MethodSpec methodInjectionMethod(XMethodElement method, String methodName) { + XTypeElement enclosingType = asTypeElement(method.getEnclosingElement()); + MethodSpec.Builder builder = + methodBuilder(methodName) + .addModifiers(PUBLIC, STATIC) + .varargs(method.isVarArgs()) + .addTypeVariables(typeVariableNames(enclosingType)) + .addExceptions(getThrownTypes(method)); + + UniqueNameSet parameterNameSet = new UniqueNameSet(); + CodeBlock instance = copyInstance(builder, parameterNameSet, enclosingType.getType()); + CodeBlock arguments = copyParameters(builder, parameterNameSet, method.getParameters()); + return builder.addStatement("$L.$L($L)", instance, method.getJvmName(), arguments).build(); + } + + // Example: + // + // public static void injectFoo(Instance instance, Foo foo) { + // instance.foo = foo; + // } + private static MethodSpec fieldInjectionMethod( + XFieldElement field, String methodName, Optional<XAnnotation> qualifier) { + XTypeElement enclosingType = asTypeElement(field.getEnclosingElement()); + + MethodSpec.Builder builder = + methodBuilder(methodName) + .addModifiers(PUBLIC, STATIC) + .addAnnotation( + AnnotationSpec.builder(TypeNames.INJECTED_FIELD_SIGNATURE) + .addMember("value", "$S", memberInjectedFieldSignatureForVariable(field)) + .build()) + .addTypeVariables(typeVariableNames(enclosingType)); + + qualifier.map(XAnnotations::getAnnotationSpec).ifPresent(builder::addAnnotation); + + UniqueNameSet parameterNameSet = new UniqueNameSet(); + CodeBlock instance = copyInstance(builder, parameterNameSet, enclosingType.getType()); + CodeBlock argument = copyParameters(builder, parameterNameSet, ImmutableList.of(field)); + return builder.addStatement("$L.$L = $L", instance, getSimpleName(field), argument).build(); + } + + private static ImmutableList<TypeName> getThrownTypes(XExecutableElement executable) { + return executable.getThrownTypes().stream().map(XType::getTypeName).collect(toImmutableList()); + } + + private static CodeBlock copyInstance( + MethodSpec.Builder methodBuilder, UniqueNameSet parameterNameSet, XType type) { + boolean useObject = !isRawTypePubliclyAccessible(type); + CodeBlock instance = + copyParameter( + methodBuilder, + type, + parameterNameSet.getUniqueName("instance"), + useObject, + Nullability.NOT_NULLABLE); + // 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; + } + + // MyClass( + // Provider<Dep1> dep1Provider, + // Provider<Dep2> dep2Provider, + // // Note: The raw type can happen if Dep3 is injected in a super type and not accessible to + // // the parent. Ideally, we would have passed in the parent MembersInjector instance itself + // // which would have avoided this situation, but doing it now would cause version skew. + // @SuppressWarnings("RAW_TYPE") Provider dep3Provider) { + // this.dep1Provider = dep1Provider; + // this.dep2Provider = dep2Provider; + // this.dep3Provider = dep3Provider; + // } + private MethodSpec constructor(ImmutableMap<DependencyRequest, FieldSpec> frameworkFields) { + ImmutableList<ParameterSpec> dependencyParameters = + frameworkFields.values().stream() + .map( + field -> + ParameterSpec.builder(field.type, field.name) + .addAnnotations(field.annotations) + .build()) + .collect(toImmutableList()); + return constructorBuilder() + .addModifiers(PUBLIC) + .addParameters(dependencyParameters) + .addCode( + dependencyParameters.stream() + .map(parameter -> CodeBlock.of("this.$1N = $1N;", parameter)) + .collect(toConcatenatedCodeBlock())) + .build(); + } + + // public static MyClass_MembersInjector create( + // Provider<Dep1> dep1Provider, + // Provider<Dep2> dep2Provider, + // // Note: The raw type can happen if Dep3 is injected in a super type and not accessible to + // // the parent. Ideally, we would have passed in the parent MembersInjector instance itself + // // which would have avoided this situation, but doing it now would cause version skew. + // @SuppressWarnings("RAW_TYPE") Provider dep3Provider) { + // return new MyClass_MembersInjector(dep1Provider, dep2Provider, dep3Provider); + // } + private ImmutableList<MethodSpec> createMethod( + MembersInjectionBinding binding, + ImmutableMap<DependencyRequest, FieldSpec> frameworkFields) { + ImmutableList.Builder<MethodSpec> methodsBuilder = ImmutableList.builder(); + List<ParameterSpec> params = constructor(frameworkFields).parameters; + // We use a static create method so that generated components can avoid having + // to refer to the generic types of the factory. + // (Otherwise they may have visibility problems referring to the types.) + methodsBuilder.add(methodBuilder("create") + .addModifiers(PUBLIC, STATIC) + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .returns(membersInjectorOf(binding.key().type().xprocessing().getTypeName())) + .addParameters(params) + .addStatement( + "return new $T($L)", + parameterizedGeneratedTypeNameForBinding(binding), + parameterNames(params)) + .build()); + if (hasDaggerProviderParams(params)) { + methodsBuilder.add(javaxCreateMethod(binding, params)); + } + return methodsBuilder.build(); + } + + private MethodSpec javaxCreateMethod( + MembersInjectionBinding binding, List<ParameterSpec> params) { + ImmutableList<ParameterSpec> remappedParams = remapParamsToJavaxProvider(params); + return methodBuilder("create") + .addModifiers(PUBLIC, STATIC) + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .returns(membersInjectorOf(binding.key().type().xprocessing().getTypeName())) + .addParameters(remappedParams) + .addStatement( + "return new $T($L)", + parameterizedGeneratedTypeNameForBinding(binding), + wrappedParametersCodeBlock(remappedParams)) + .build(); + } + + // @Override + // public void injectMembers(Thing instance) { + // injectDep1(instance, dep1Provider.get()); + // injectSomeMethod(instance, dep2Provider.get()); + // // This is a case where Dep3 is injected in the base class. + // MyBaseClass_MembersInjector.injectDep3(instance, dep3Provider.get()); + // } + private MethodSpec injectMembersMethod( + MembersInjectionBinding binding, + ImmutableMap<DependencyRequest, FieldSpec> frameworkFields) { + XType instanceType = binding.key().type().xprocessing(); + ImmutableMap<DependencyRequest, CodeBlock> dependencyCodeBlocks = + sourceFiles.frameworkFieldUsages(binding.dependencies(), frameworkFields); + return methodBuilder("injectMembers") + .addModifiers(PUBLIC) + .addAnnotation(Override.class) + .addParameter(instanceType.getTypeName(), "instance") + .addCode( + InjectionSiteMethod.invokeAll( + binding.injectionSites(), + toJavaPoet(membersInjectorNameForType(binding.membersInjectedType())), + CodeBlock.of("instance"), + instanceType, + dependencyCodeBlocks::get)) + .build(); + } + private AnnotationSpec qualifierMetadataAnnotation(MembersInjectionBinding binding) { AnnotationSpec.Builder builder = AnnotationSpec.builder(TypeNames.QUALIFIER_METADATA); binding.injectionSites().stream() @@ -222,4 +349,35 @@ .forEach(qualifier -> builder.addMember("value", "$S", qualifier)); return builder.build(); } + + private static ImmutableMap<DependencyRequest, FieldSpec> frameworkFields( + MembersInjectionBinding binding) { + UniqueNameSet fieldNames = new UniqueNameSet(); + ClassName membersInjectorTypeName = + toJavaPoet(membersInjectorNameForType(binding.membersInjectedType())); + ImmutableMap.Builder<DependencyRequest, FieldSpec> builder = ImmutableMap.builder(); + generateBindingFieldsForDependencies(binding) + .forEach( + (request, bindingField) -> { + // If the dependency type is not visible to this members injector, then use the raw + // framework type for the field. + boolean useRawFrameworkType = + !isTypeAccessibleFrom( + request.key().type().xprocessing(), + membersInjectorTypeName.packageName()); + TypeName fieldType = + useRawFrameworkType + ? toJavaPoet(bindingField.type().getRawTypeName()) + : toJavaPoet(bindingField.type()); + String fieldName = fieldNames.getUniqueName(bindingField.name()); + FieldSpec field = + useRawFrameworkType + ? FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL) + .addAnnotation(suppressWarnings(RAWTYPES)) + .build() + : FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL).build(); + builder.put(request, field); + }); + return builder.buildOrThrow(); + } }
diff --git a/java/dagger/internal/codegen/writing/MembersInjectorProviderCreationExpression.java b/java/dagger/internal/codegen/writing/MembersInjectorProviderCreationExpression.java index e6906ea..5b9d348 100644 --- a/java/dagger/internal/codegen/writing/MembersInjectorProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/MembersInjectorProviderCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.getOnlyElement; import static dagger.internal.codegen.binding.SourceFiles.membersInjectorNameForType; @@ -29,7 +30,7 @@ import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.MembersInjectionBinding.InjectionSite; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.MembersInjectorBinding; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; @@ -39,11 +40,11 @@ private final ShardImplementation shardImplementation; private final ComponentRequestRepresentations componentRequestRepresentations; - private final ProvisionBinding binding; + private final MembersInjectorBinding binding; @AssistedInject MembersInjectorProviderCreationExpression( - @Assisted ProvisionBinding binding, + @Assisted MembersInjectorBinding binding, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations) { this.binding = checkNotNull(binding); @@ -73,7 +74,7 @@ membersInjector = CodeBlock.of( "$T.create($L)", - membersInjectorNameForType(injectedTypeElement), + toJavaPoet(membersInjectorNameForType(injectedTypeElement)), componentRequestRepresentations.getCreateMethodArgumentsCodeBlock( binding, shardImplementation.name())); } @@ -100,6 +101,6 @@ @AssistedFactory static interface Factory { - MembersInjectorProviderCreationExpression create(ProvisionBinding binding); + MembersInjectorProviderCreationExpression create(MembersInjectorBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ModuleProxies.java b/java/dagger/internal/codegen/writing/ModuleProxies.java index eaf57ee..772cc63 100644 --- a/java/dagger/internal/codegen/writing/ModuleProxies.java +++ b/java/dagger/internal/codegen/writing/ModuleProxies.java
@@ -16,9 +16,11 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; 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.SourceFiles.classFileName; import static dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom; import static dagger.internal.codegen.xprocessing.XTypeElements.isNested; import static javax.lang.model.element.Modifier.FINAL; @@ -26,6 +28,7 @@ import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; +import androidx.room.compiler.codegen.XClassName; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XFiler; @@ -37,7 +40,6 @@ import com.squareup.javapoet.TypeSpec; import dagger.internal.codegen.base.ModuleKind; import dagger.internal.codegen.base.SourceFileGenerator; -import dagger.internal.codegen.binding.SourceFiles; import dagger.internal.codegen.langmodel.Accessibility; import java.util.Optional; import javax.inject.Inject; @@ -86,10 +88,10 @@ /** The name of the class that hosts the module constructor proxy method. */ private static ClassName constructorProxyTypeName(XTypeElement moduleElement) { ModuleKind.checkIsModule(moduleElement); - ClassName moduleClassName = moduleElement.getClassName(); - return moduleClassName + XClassName moduleClassName = moduleElement.asClassName(); + return toJavaPoet(moduleClassName) .topLevelClassName() - .peerClass(SourceFiles.classFileName(moduleClassName) + "_Proxy"); + .peerClass(classFileName(moduleClassName) + "_Proxy"); } /**
diff --git a/java/dagger/internal/codegen/writing/MultibindingFactoryCreationExpression.java b/java/dagger/internal/codegen/writing/MultibindingFactoryCreationExpression.java index 5cb47bb..667fe08 100644 --- a/java/dagger/internal/codegen/writing/MultibindingFactoryCreationExpression.java +++ b/java/dagger/internal/codegen/writing/MultibindingFactoryCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import com.squareup.javapoet.CodeBlock; @@ -52,7 +53,7 @@ .codeBlock(); return useRawType() - ? CodeBlocks.cast(expression, binding.frameworkType().frameworkClassName()) + ? CodeBlocks.cast(expression, toJavaPoet(binding.frameworkType().frameworkClassName())) : expression; }
diff --git a/java/dagger/internal/codegen/writing/OptionalFactories.java b/java/dagger/internal/codegen/writing/OptionalFactories.java index 3c327e8..fc31989 100644 --- a/java/dagger/internal/codegen/writing/OptionalFactories.java +++ b/java/dagger/internal/codegen/writing/OptionalFactories.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.CaseFormat.UPPER_CAMEL; import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE; import static com.google.common.base.Verify.verify; @@ -57,8 +58,8 @@ import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.base.OptionalType.OptionalKind; import dagger.internal.codegen.binding.BindingType; -import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.FrameworkType; +import dagger.internal.codegen.binding.OptionalBinding; import dagger.internal.codegen.javapoet.AnnotationSpecs; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.RequestKind; @@ -119,7 +120,7 @@ * Returns an expression that calls a static method that returns a {@code Provider<Optional<T>>} * for absent optional bindings. */ - CodeBlock absentOptionalProvider(ContributionBinding binding) { + CodeBlock absentOptionalProvider(OptionalBinding binding) { verify( binding.bindingType().equals(BindingType.PROVISION), "Absent optional bindings should be provisions: %s", @@ -267,11 +268,11 @@ return new StringBuilder("Present") .append(UPPER_UNDERSCORE.to(UPPER_CAMEL, optionalKind().name())) .append(UPPER_UNDERSCORE.to(UPPER_CAMEL, valueKind().toString())) - .append(frameworkType().frameworkClassName().simpleName()) + .append(toJavaPoet(frameworkType().frameworkClassName()).simpleName()) .toString(); } - private static PresentFactorySpec of(ContributionBinding binding) { + private static PresentFactorySpec of(OptionalBinding binding) { return new AutoValue_OptionalFactories_PresentFactorySpec( FrameworkType.forBindingType(binding.bindingType()), OptionalType.from(binding.key()).kind(), @@ -302,7 +303,7 @@ * @param delegateFactory an expression for a {@code Provider} or {@code Producer} of the * underlying type */ - CodeBlock presentOptionalFactory(ContributionBinding binding, CodeBlock delegateFactory) { + CodeBlock presentOptionalFactory(OptionalBinding binding, CodeBlock delegateFactory) { return CodeBlock.of( "$N.of($L)", perGeneratedFileCache.presentFactoryClasses.computeIfAbsent(
diff --git a/java/dagger/internal/codegen/writing/OptionalFactoryInstanceCreationExpression.java b/java/dagger/internal/codegen/writing/OptionalFactoryInstanceCreationExpression.java index 2f2ae58..0ff13a9 100644 --- a/java/dagger/internal/codegen/writing/OptionalFactoryInstanceCreationExpression.java +++ b/java/dagger/internal/codegen/writing/OptionalFactoryInstanceCreationExpression.java
@@ -23,7 +23,7 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.OptionalBinding; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; /** @@ -33,13 +33,13 @@ final class OptionalFactoryInstanceCreationExpression implements FrameworkInstanceCreationExpression { private final OptionalFactories optionalFactories; - private final ContributionBinding binding; + private final OptionalBinding binding; private final ComponentImplementation componentImplementation; private final ComponentRequestRepresentations componentRequestRepresentations; @AssistedInject OptionalFactoryInstanceCreationExpression( - @Assisted ContributionBinding binding, + @Assisted OptionalBinding binding, OptionalFactories optionalFactories, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations) { @@ -65,6 +65,6 @@ @AssistedFactory static interface Factory { - OptionalFactoryInstanceCreationExpression create(ContributionBinding binding); + OptionalFactoryInstanceCreationExpression create(OptionalBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java b/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java index 8c92191..6d91f5b 100644 --- a/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/OptionalRequestRepresentation.java
@@ -30,20 +30,20 @@ import dagger.assisted.AssistedInject; import dagger.internal.codegen.base.OptionalType; import dagger.internal.codegen.base.OptionalType.OptionalKind; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.OptionalBinding; 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 OptionalBinding binding; private final ComponentRequestRepresentations componentRequestRepresentations; private final XProcessingEnv processingEnv; @AssistedInject OptionalRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted OptionalBinding binding, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, XProcessingEnv processingEnv) { @@ -99,6 +99,6 @@ @AssistedFactory static interface Factory { - OptionalRequestRepresentation create(ProvisionBinding binding); + OptionalRequestRepresentation create(OptionalBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ProducerCreationExpression.java b/java/dagger/internal/codegen/writing/ProducerCreationExpression.java index 8e8c271..4f15f63 100644 --- a/java/dagger/internal/codegen/writing/ProducerCreationExpression.java +++ b/java/dagger/internal/codegen/writing/ProducerCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.generatedClassNameForBinding; @@ -23,7 +24,7 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.ProductionBinding; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; @@ -36,11 +37,11 @@ private final ShardImplementation shardImplementation; private final ComponentRequestRepresentations componentRequestRepresentations; - private final ContributionBinding binding; + private final ProductionBinding binding; @AssistedInject ProducerCreationExpression( - @Assisted ContributionBinding binding, + @Assisted ProductionBinding binding, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations) { this.binding = checkNotNull(binding); @@ -52,13 +53,13 @@ public CodeBlock creationExpression() { return CodeBlock.of( "$T.create($L)", - generatedClassNameForBinding(binding), + toJavaPoet(generatedClassNameForBinding(binding)), componentRequestRepresentations.getCreateMethodArgumentsCodeBlock( binding, shardImplementation.name())); } @AssistedFactory static interface Factory { - ProducerCreationExpression create(ContributionBinding binding); + ProducerCreationExpression create(ProductionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java b/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java index 1d8ab02..a588c2d 100644 --- a/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java +++ b/java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java
@@ -16,8 +16,9 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Verify.verifyNotNull; +import static com.google.common.collect.Iterables.getOnlyElement; import static com.squareup.javapoet.ClassName.OBJECT; import static com.squareup.javapoet.MethodSpec.constructorBuilder; import static com.squareup.javapoet.MethodSpec.methodBuilder; @@ -30,18 +31,21 @@ import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.FUTURE_RETURN_VALUE_IGNORED; import static dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression.UNCHECKED; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; -import static dagger.internal.codegen.javapoet.CodeBlocks.toParametersCodeBlock; +import static dagger.internal.codegen.javapoet.CodeBlocks.parameterNames; import static dagger.internal.codegen.javapoet.TypeNames.FUTURES; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCERS; import static dagger.internal.codegen.javapoet.TypeNames.PRODUCER_TOKEN; import static dagger.internal.codegen.javapoet.TypeNames.VOID_CLASS; +import static dagger.internal.codegen.javapoet.TypeNames.isFutureType; import static dagger.internal.codegen.javapoet.TypeNames.listOf; import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf; import static dagger.internal.codegen.javapoet.TypeNames.producedOf; +import static dagger.internal.codegen.writing.FactoryGenerator.hasDaggerProviderParams; +import static dagger.internal.codegen.writing.FactoryGenerator.remapParamsToJavaxProvider; +import static dagger.internal.codegen.writing.FactoryGenerator.wrappedParametersCodeBlock; import static dagger.internal.codegen.writing.GwtCompatibility.gwtIncompatibleAnnotation; +import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; import static javax.lang.model.element.Modifier.PROTECTED; @@ -50,24 +54,24 @@ import androidx.room.compiler.processing.XElement; import androidx.room.compiler.processing.XFiler; +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.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -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.MethodSpec; +import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; +import dagger.internal.codegen.base.ContributionType; +import dagger.internal.codegen.base.SetType; import dagger.internal.codegen.base.SourceFileGenerator; import dagger.internal.codegen.base.UniqueNameSet; -import dagger.internal.codegen.binding.Binding; -import dagger.internal.codegen.binding.FrameworkField; -import dagger.internal.codegen.binding.KeyFactory; import dagger.internal.codegen.binding.ProductionBinding; import dagger.internal.codegen.binding.SourceFiles; import dagger.internal.codegen.compileroption.CompilerOptions; @@ -75,18 +79,14 @@ import dagger.internal.codegen.javapoet.AnnotationSpecs.Suppression; 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 java.util.ArrayList; import java.util.List; -import java.util.Map.Entry; import java.util.Optional; import javax.inject.Inject; /** Generates {@code Producer} implementations from {@link ProductionBinding} instances. */ public final class ProducerFactoryGenerator extends SourceFileGenerator<ProductionBinding> { private final CompilerOptions compilerOptions; - private final KeyFactory keyFactory; private final SourceFiles sourceFiles; @Inject @@ -94,11 +94,9 @@ XFiler filer, XProcessingEnv processingEnv, CompilerOptions compilerOptions, - KeyFactory keyFactory, SourceFiles sourceFiles) { super(filer, processingEnv); this.compilerOptions = compilerOptions; - this.keyFactory = keyFactory; this.sourceFiles = sourceFiles; } @@ -114,173 +112,285 @@ checkArgument(!binding.unresolved().isPresent()); checkArgument(binding.bindingElement().isPresent()); - TypeName providedTypeName = binding.contributedType().getTypeName(); - TypeName futureTypeName = listenableFutureOf(providedTypeName); - - ClassName generatedTypeName = generatedClassNameForBinding(binding); + FactoryFields factoryFields = FactoryFields.create(binding); TypeSpec.Builder factoryBuilder = - classBuilder(generatedTypeName) + classBuilder(toJavaPoet(generatedClassNameForBinding(binding))) + .superclass( + ParameterizedTypeName.get( + TypeNames.ABSTRACT_PRODUCES_METHOD_PRODUCER, + callProducesMethodParameter(binding).type, + binding.contributedType().getTypeName())) .addModifiers(PUBLIC, FINAL) - .addTypeVariables(bindingTypeElementTypeVariableNames(binding)); - - UniqueNameSet uniqueFieldNames = new UniqueNameSet(); - ImmutableMap.Builder<DependencyRequest, FieldSpec> fieldsBuilder = ImmutableMap.builder(); - - MethodSpec.Builder constructorBuilder = constructorBuilder().addModifiers(PRIVATE); - - Optional<FieldSpec> moduleField = - binding.requiresModuleInstance() - ? Optional.of( - addFieldAndConstructorParameter( - factoryBuilder, - constructorBuilder, - uniqueFieldNames.getUniqueName("module"), - binding.bindingTypeElement().get().getType().getTypeName())) - : Optional.empty(); - - List<CodeBlock> frameworkFieldAssignments = new ArrayList<>(); - - String executorParameterName = null; - String monitorParameterName = null; - ImmutableMap<DependencyRequest, FrameworkField> bindingFieldsForDependencies = - generateBindingFieldsForDependencies(binding); - for (Entry<DependencyRequest, FrameworkField> entry : bindingFieldsForDependencies.entrySet()) { - DependencyRequest dependency = entry.getKey(); - Key key = dependency.key(); - FrameworkField bindingField = entry.getValue(); - String fieldName = uniqueFieldNames.getUniqueName(bindingField.name()); - if (key.equals(keyFactory.forProductionImplementationExecutor())) { - executorParameterName = fieldName; - constructorBuilder.addParameter(bindingField.type(), executorParameterName); - } else if (key.equals(keyFactory.forProductionComponentMonitor())) { - monitorParameterName = fieldName; - constructorBuilder.addParameter(bindingField.type(), monitorParameterName); - } else { - FieldSpec field = - addFieldAndConstructorParameter( - factoryBuilder, constructorBuilder, fieldName, bindingField.type()); - fieldsBuilder.put(dependency, field); - frameworkFieldAssignments.add(fieldAssignment(field, bindingField)); - } - } - ImmutableMap<DependencyRequest, FieldSpec> fields = fieldsBuilder.build(); - - constructorBuilder.addStatement( - "super($N, $L, $N)", - verifyNotNull(monitorParameterName), - producerTokenConstruction(generatedTypeName, binding), - verifyNotNull(executorParameterName)); - - if (binding.requiresModuleInstance()) { - assignField(constructorBuilder, moduleField.get(), null); - } - - constructorBuilder.addCode(CodeBlock.join(frameworkFieldAssignments, "\n")); - - MethodSpec.Builder collectDependenciesBuilder = - methodBuilder("collectDependencies").addAnnotation(Override.class).addModifiers(PROTECTED); - - ImmutableList<DependencyRequest> asyncDependencies = asyncDependencies(binding); - for (DependencyRequest dependency : asyncDependencies) { - TypeName futureType = listenableFutureOf(asyncDependencyType(dependency)); - CodeBlock futureAccess = CodeBlock.of("$N.get()", fields.get(dependency)); - collectDependenciesBuilder.addStatement( - "$T $L = $L", - futureType, - dependencyFutureName(dependency), - dependency.kind().equals(RequestKind.PRODUCED) - ? CodeBlock.of("$T.createFutureProduced($L)", PRODUCERS, futureAccess) - : futureAccess); - } - FutureTransform futureTransform = createFutureTransform(fields, binding, asyncDependencies); - - collectDependenciesBuilder - .returns(listenableFutureOf(futureTransform.applyArgType())) - .addStatement("return $L", futureTransform.futureCodeBlock()); - - MethodSpec.Builder callProducesMethod = - methodBuilder("callProducesMethod") - .returns(futureTypeName) - .addAnnotation(Override.class) - .addModifiers(PUBLIC) - .addParameter(futureTransform.applyArgType(), futureTransform.applyArgName()) - .addExceptions(binding.thrownTypes().stream().map(XType::getTypeName).collect(toList())) - .addCode( - getInvocationCodeBlock( - binding, providedTypeName, futureTransform.parameterCodeBlocks())); - if (futureTransform.hasUncheckedCast()) { - callProducesMethod.addAnnotation(AnnotationSpecs.suppressWarnings(UNCHECKED)); - } - - MethodSpec constructor = constructorBuilder.build(); - factoryBuilder - .superclass( - ParameterizedTypeName.get( - TypeNames.ABSTRACT_PRODUCES_METHOD_PRODUCER, - futureTransform.applyArgType(), - providedTypeName)) - .addMethod(constructor) - .addMethod(staticFactoryMethod(binding, constructor)) - .addMethod(collectDependenciesBuilder.build()) - .addMethod(callProducesMethod.build()); + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .addFields( + factoryFields.getAll().stream() + // The executor and monitor fields are owned by the superclass so they are not + // included as fields in the generated factory subclass. + .filter(field -> !field.equals(factoryFields.executorField)) + .filter(field -> !field.equals(factoryFields.monitorField)) + .collect(toImmutableList())) + .addMethod(constructorMethod(binding, factoryFields)) + .addMethods(staticCreateMethod(binding, factoryFields)) + .addMethod(collectDependenciesMethod(binding, factoryFields)) + .addMethod(callProducesMethod(binding, factoryFields)); gwtIncompatibleAnnotation(binding).ifPresent(factoryBuilder::addAnnotation); - // TODO(gak): write a sensible toString return ImmutableList.of(factoryBuilder); } - private MethodSpec staticFactoryMethod(ProductionBinding binding, MethodSpec constructor) { + // private FooModule_ProducesFooFactory( + // FooModule module, + // Provider<Executor> executorProvider, + // Provider<ProductionComponentMonitor> productionComponentMonitorProvider, + // Producer<Foo> fooProducer, + // Producer<Bar> barProducer) { + // super( + // productionComponentMonitorProvider, + // ProducerToken.create(FooModule_ProducesFooFactory.class), + // executorProvider); + // this.module = module; + // this.fooProducer = Producers.nonCancellationPropagatingViewOf(fooProducer); + // this.barProducer = Producers.nonCancellationPropagatingViewOf(barProducer); + // } + private MethodSpec constructorMethod(ProductionBinding binding, FactoryFields factoryFields) { + MethodSpec.Builder constructorBuilder = constructorBuilder().addModifiers(PRIVATE); + constructorBuilder.addStatement( + "super($N, $L, $N)", + factoryFields.monitorField, + producerTokenConstruction(toJavaPoet(generatedClassNameForBinding(binding)), binding), + factoryFields.executorField); + factoryFields.getAll() + .forEach( + field -> { + constructorBuilder.addParameter(field.type, field.name); + // The executor and monitor fields belong to the super class so they don't need a + // field assignment here. + if (!field.equals(factoryFields.executorField) + && !field.equals(factoryFields.monitorField)) { + if (TypeNames.rawTypeName(field.type).equals(TypeNames.PRODUCER)) { + constructorBuilder.addStatement( + "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", + field, + TypeNames.PRODUCERS); + } else { + constructorBuilder.addStatement("this.$1N = $1N", field); + } + } + }); + return constructorBuilder.build(); + } + + // public static FooModule_ProducesFooFactory create( + // FooModule module, + // Provider<Executor> executorProvider, + // Provider<ProductionComponentMonitor> productionComponentMonitorProvider, + // Producer<Foo> fooProducer, + // Producer<Bar> barProducer) { + // return new FooModule_ProducesFooFactory( + // module, executorProvider, productionComponentMonitorProvider, fooProducer, barProducer); + // } + private ImmutableList<MethodSpec> staticCreateMethod( + ProductionBinding binding, FactoryFields factoryFields) { + ImmutableList.Builder<MethodSpec> methodsBuilder = ImmutableList.builder(); + List<ParameterSpec> params = constructorMethod(binding, factoryFields).parameters; + methodsBuilder.add(MethodSpec.methodBuilder("create") + .addModifiers(PUBLIC, STATIC) + .returns(parameterizedGeneratedTypeNameForBinding(binding)) + .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) + .addParameters(params) + .addStatement( + "return new $T($L)", + parameterizedGeneratedTypeNameForBinding(binding), + parameterNames(params)) + .build()); + // If any of the parameters take a Dagger Provider type, we also need to make a + // Javax Provider type for backwards compatibility with components generated at + // an older version. + // Eventually, we will need to remove this and break backwards compatibility + // in order to fully cut the Javax dependency. + if (hasDaggerProviderParams(params)) { + methodsBuilder.add(javaxCreateMethod(binding, params)); + } + return methodsBuilder.build(); + } + + private MethodSpec javaxCreateMethod(ProductionBinding binding, List<ParameterSpec> params) { + ImmutableList<ParameterSpec> remappedParams = remapParamsToJavaxProvider(params); return MethodSpec.methodBuilder("create") .addModifiers(PUBLIC, STATIC) .returns(parameterizedGeneratedTypeNameForBinding(binding)) .addTypeVariables(bindingTypeElementTypeVariableNames(binding)) - .addParameters(constructor.parameters) + .addParameters(remappedParams) .addStatement( "return new $T($L)", parameterizedGeneratedTypeNameForBinding(binding), - constructor.parameters.stream() - .map(p -> CodeBlock.of("$N", p.name)) - .collect(toParametersCodeBlock())) + wrappedParametersCodeBlock(remappedParams)) .build(); } - // TODO(ronshapiro): consolidate versions of these - private static FieldSpec addFieldAndConstructorParameter( - TypeSpec.Builder typeBuilder, - MethodSpec.Builder constructorBuilder, - String variableName, - TypeName variableType) { - FieldSpec field = FieldSpec.builder(variableType, variableName, PRIVATE, FINAL).build(); - typeBuilder.addField(field); - constructorBuilder.addParameter(field.type, field.name); - return field; - } - - private static CodeBlock fieldAssignment(FieldSpec field, FrameworkField frameworkField) { - CodeBlock.Builder statement = CodeBlock.builder(); - if (frameworkField.type() != null - && TypeNames.rawTypeName(frameworkField.type()).equals(TypeNames.PRODUCER)) { - statement.addStatement( - "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, TypeNames.PRODUCERS); - } else { - statement.addStatement("this.$1N = $1N", field); - } - return statement.build(); - } - - private static void assignField( - MethodSpec.Builder constructorBuilder, FieldSpec field, ParameterizedTypeName type) { - if (type != null && type.rawType.equals(TypeNames.PRODUCER)) { - constructorBuilder.addStatement( - "this.$1N = $2T.nonCancellationPropagatingViewOf($1N)", field, TypeNames.PRODUCERS); - } else { - constructorBuilder.addStatement("this.$1N = $1N", field); + // Example 1: No async dependencies. + // protected ListenableFuture<Void> collectDependencies() { + // return Futures.<Void>immediateFuture(null); + // } + // + // Example 2: Single async dependency, "fooProducer". + // protected ListenableFuture<Foo> collectDependencies() { + // return fooProducer.get(); + // } + // + // Example 3: Multiple async dependencies, "fooProducer" and "barProducer". + // protected ListenableFuture<List<Object>> collectDependencies() { + // ListenableFuture<Foo> fooFuture = fooProducer.get(); + // ListenableFuture<Bar> barFuture = barProducer.get(); + // return Futures.<Object>allAsList(fooFuture, barFuture); + // } + public MethodSpec collectDependenciesMethod( + ProductionBinding binding, FactoryFields factoryFields) { + MethodSpec.Builder methodBuilder = + methodBuilder("collectDependencies") + .addAnnotation(Override.class) + .addModifiers(PROTECTED); + ImmutableList<DependencyRequest> asyncDependencies = asyncDependencies(binding); + switch (asyncDependencies.size()) { + case 0: + return methodBuilder + .returns(listenableFutureOf(VOID_CLASS)) + .addStatement("return $T.<$T>immediateFuture(null)", FUTURES, VOID_CLASS) + .build(); + case 1: { + DependencyRequest asyncDependency = getOnlyElement(asyncDependencies); + FieldSpec asyncDependencyField = factoryFields.get(asyncDependency); + return methodBuilder + .returns(listenableFutureOf(asyncDependencyType(asyncDependency))) + .addStatement("return $L", producedCodeBlock(asyncDependency, asyncDependencyField)) + .build(); + } + default: + CodeBlock.Builder argAssignments = CodeBlock.builder(); + ImmutableList.Builder<CodeBlock> argNames = ImmutableList.builder(); + for (DependencyRequest asyncDependency : asyncDependencies) { + FieldSpec asyncDependencyField = factoryFields.get(asyncDependency); + argNames.add(CodeBlock.of("$L", dependencyFutureName(asyncDependency))); + argAssignments.addStatement( + "$T $L = $L", + listenableFutureOf(asyncDependencyType(asyncDependency)), + dependencyFutureName(asyncDependency), + producedCodeBlock(asyncDependency, asyncDependencyField)); + } + return methodBuilder + .returns(listenableFutureOf(listOf(OBJECT))) + .addCode(argAssignments.build()) + .addStatement( + "return $T.<$T>allAsList($L)", + FUTURES, + OBJECT, + makeParametersCodeBlock(argNames.build())) + .build(); } } - /** Returns a list of dependencies that are generated asynchronously. */ - private static ImmutableList<DependencyRequest> asyncDependencies(Binding binding) { + private CodeBlock producedCodeBlock(DependencyRequest request, FieldSpec field) { + return request.kind() == RequestKind.PRODUCED + ? CodeBlock.of("$T.createFutureProduced($N.get())", PRODUCERS, field) + : CodeBlock.of("$N.get()", field); + } + + // Example 1: No async dependencies. + // @Override + // public ListenableFuture<Foo> callProducesMethod(Void ignoredVoidArg) { + // return module.producesFoo(); + // } + // + // Example 2: Single async dependency. + // @Override + // public ListenableFuture<Foo> callProducesMethod(Bar bar) { + // return module.producesFoo(bar); + // } + // + // Example 3: Multiple async dependencies. + // @Override + // @SuppressWarnings("unchecked") + // public ListenableFuture<Foo> callProducesMethod(List<Object> args) { + // return module.producesFoo((Bar) args.get(0), (Baz) args.get(1)); + // } + private MethodSpec callProducesMethod(ProductionBinding binding, FactoryFields factoryFields) { + TypeName contributedTypeName = binding.contributedType().getTypeName(); + ParameterSpec parameter = callProducesMethodParameter(binding); + MethodSpec.Builder methodBuilder = + methodBuilder("callProducesMethod") + .returns(listenableFutureOf(contributedTypeName)) + .addAnnotation(Override.class) + .addModifiers(PUBLIC) + .addExceptions( + asMethod(binding.bindingElement().get()).getThrownTypes().stream() + .map(XType::getTypeName) + .collect(toImmutableList())) + .addParameter(parameter); + ImmutableList<DependencyRequest> asyncDependencies = asyncDependencies(binding); + ImmutableList.Builder<CodeBlock> parameterCodeBlocks = ImmutableList.builder(); + for (DependencyRequest dependency : binding.explicitDependencies()) { + if (isAsyncDependency(dependency)) { + if (asyncDependencies.size() > 1) { + TypeName dependencyType = asyncDependencyType(dependency); + int argIndex = asyncDependencies.indexOf(dependency); + parameterCodeBlocks.add( + CodeBlock.of("($T) $N.get($L)", dependencyType, parameter, argIndex)); + } else { + parameterCodeBlocks.add(CodeBlock.of("$N", parameter)); + } + } else { + parameterCodeBlocks.add( + sourceFiles.frameworkTypeUsageStatement( + CodeBlock.of("$N", factoryFields.get(dependency)), dependency.kind())); + } + } + if (asyncDependencies.size() > 1) { + methodBuilder.addAnnotation(AnnotationSpecs.suppressWarnings(UNCHECKED)); + } + + CodeBlock moduleCodeBlock = + CodeBlock.of( + "$L.$L($L)", + factoryFields.moduleField.isPresent() + ? factoryFields.moduleField.get().name + : CodeBlock.of("$T", binding.bindingTypeElement().get().getClassName()), + getSimpleName(binding.bindingElement().get()), + makeParametersCodeBlock(parameterCodeBlocks.build())); + + switch (ProductionKind.fromProducesMethod(asMethod(binding.bindingElement().get()))) { + case IMMEDIATE: + methodBuilder.addStatement( + "return $T.<$T>immediateFuture($L)", FUTURES, contributedTypeName, moduleCodeBlock); + break; + case FUTURE: + methodBuilder.addStatement("return $L", moduleCodeBlock); + break; + case SET_OF_FUTURE: + methodBuilder.addStatement("return $T.allAsSet($L)", PRODUCERS, moduleCodeBlock); + break; + } + return methodBuilder.build(); + } + + private ParameterSpec callProducesMethodParameter(ProductionBinding binding) { + ImmutableList<DependencyRequest> asyncDependencies = asyncDependencies(binding); + switch (asyncDependencies.size()) { + case 0: + return ParameterSpec.builder(VOID_CLASS, "ignoredVoidArg").build(); + case 1: + DependencyRequest asyncDependency = getOnlyElement(asyncDependencies); + String argName = getSimpleName(asyncDependency.requestElement().get().xprocessing()); + return ParameterSpec.builder( + asyncDependencyType(asyncDependency), + argName.equals("module") ? "moduleArg" : argName) + .build(); + default: + return ParameterSpec.builder(listOf(OBJECT), "args").build(); + } + } + + private static ImmutableList<DependencyRequest> asyncDependencies(ProductionBinding binding) { return binding.dependencies().stream() .filter(ProducerFactoryGenerator::isAsyncDependency) .collect(toImmutableList()); @@ -305,184 +415,6 @@ return getSimpleName(dependency.requestElement().get().xprocessing()) + "Future"; } - private FutureTransform createFutureTransform( - ImmutableMap<DependencyRequest, FieldSpec> fields, - ProductionBinding binding, - ImmutableList<DependencyRequest> asyncDependencies) { - if (asyncDependencies.isEmpty()) { - return new NoArgFutureTransform(fields, binding); - } else if (asyncDependencies.size() == 1) { - return new SingleArgFutureTransform( - fields, binding, Iterables.getOnlyElement(asyncDependencies)); - } else { - return new MultiArgFutureTransform(fields, binding, asyncDependencies); - } - } - - /** Represents the transformation of an input future by a producer method. */ - abstract class FutureTransform { - protected final ImmutableMap<DependencyRequest, FieldSpec> fields; - protected final ProductionBinding binding; - - FutureTransform(ImmutableMap<DependencyRequest, FieldSpec> fields, ProductionBinding binding) { - this.fields = fields; - this.binding = binding; - } - - /** The code block representing the future that should be transformed. */ - abstract CodeBlock futureCodeBlock(); - - /** The type of the argument to the apply method. */ - abstract TypeName applyArgType(); - - /** The name of the argument to the apply method */ - abstract String applyArgName(); - - /** The code blocks to be passed to the produces method itself. */ - abstract ImmutableList<CodeBlock> parameterCodeBlocks(); - - /** Whether the transform method has an unchecked cast. */ - boolean hasUncheckedCast() { - return false; - } - - CodeBlock frameworkTypeUsageStatement(DependencyRequest dependency) { - return sourceFiles.frameworkTypeUsageStatement( - CodeBlock.of("$N", fields.get(dependency)), dependency.kind()); - } - } - - final class NoArgFutureTransform extends FutureTransform { - NoArgFutureTransform( - ImmutableMap<DependencyRequest, FieldSpec> fields, ProductionBinding binding) { - super(fields, binding); - } - - @Override - CodeBlock futureCodeBlock() { - return CodeBlock.of("$T.<$T>immediateFuture(null)", FUTURES, VOID_CLASS); - } - - @Override - TypeName applyArgType() { - return VOID_CLASS; - } - - @Override - String applyArgName() { - return "ignoredVoidArg"; - } - - @Override - ImmutableList<CodeBlock> parameterCodeBlocks() { - return binding.explicitDependencies().stream() - .map(this::frameworkTypeUsageStatement) - .collect(toImmutableList()); - } - } - - final class SingleArgFutureTransform extends FutureTransform { - private final DependencyRequest asyncDependency; - - SingleArgFutureTransform( - ImmutableMap<DependencyRequest, FieldSpec> fields, - ProductionBinding binding, - DependencyRequest asyncDependency) { - super(fields, binding); - this.asyncDependency = asyncDependency; - } - - @Override - CodeBlock futureCodeBlock() { - return CodeBlock.of("$L", dependencyFutureName(asyncDependency)); - } - - @Override - TypeName applyArgType() { - return asyncDependencyType(asyncDependency); - } - - @Override - String applyArgName() { - String argName = getSimpleName(asyncDependency.requestElement().get().xprocessing()); - if (argName.equals("module")) { - return "moduleArg"; - } - return argName; - } - - @Override - ImmutableList<CodeBlock> parameterCodeBlocks() { - ImmutableList.Builder<CodeBlock> parameterCodeBlocks = ImmutableList.builder(); - for (DependencyRequest dependency : binding.explicitDependencies()) { - // We really want to compare instances here, because asyncDependency is an element in the - // set binding.dependencies(). - if (dependency == asyncDependency) { - parameterCodeBlocks.add(CodeBlock.of("$L", applyArgName())); - } else { - parameterCodeBlocks.add(frameworkTypeUsageStatement(dependency)); - } - } - return parameterCodeBlocks.build(); - } - } - - final class MultiArgFutureTransform extends FutureTransform { - private final ImmutableList<DependencyRequest> asyncDependencies; - - MultiArgFutureTransform( - ImmutableMap<DependencyRequest, FieldSpec> fields, - ProductionBinding binding, - ImmutableList<DependencyRequest> asyncDependencies) { - super(fields, binding); - this.asyncDependencies = asyncDependencies; - } - - @Override - CodeBlock futureCodeBlock() { - return CodeBlock.of( - "$T.<$T>allAsList($L)", - FUTURES, - OBJECT, - asyncDependencies - .stream() - .map(ProducerFactoryGenerator::dependencyFutureName) - .collect(joining(", "))); - } - - @Override - TypeName applyArgType() { - return listOf(OBJECT); - } - - @Override - String applyArgName() { - return "args"; - } - - @Override - ImmutableList<CodeBlock> parameterCodeBlocks() { - int argIndex = 0; - ImmutableList.Builder<CodeBlock> codeBlocks = ImmutableList.builder(); - for (DependencyRequest dependency : binding.explicitDependencies()) { - if (isAsyncDependency(dependency)) { - codeBlocks.add( - CodeBlock.of( - "($T) $L.get($L)", asyncDependencyType(dependency), applyArgName(), argIndex)); - argIndex++; - } else { - codeBlocks.add(frameworkTypeUsageStatement(dependency)); - } - } - return codeBlocks.build(); - } - - @Override - boolean hasUncheckedCast() { - return true; - } - } - private static boolean isAsyncDependency(DependencyRequest dependency) { switch (dependency.kind()) { case INSTANCE: @@ -505,43 +437,60 @@ } } - /** - * Creates a code block for the invocation of the producer method from the module, which should be - * used entirely within a method body. - * - * @param binding The binding to generate the invocation code block for. - * @param providedTypeName The type name that should be provided by this producer. - * @param parameterCodeBlocks The code blocks for all the parameters to the producer method. - */ - private CodeBlock getInvocationCodeBlock( - ProductionBinding binding, - TypeName providedTypeName, - ImmutableList<CodeBlock> parameterCodeBlocks) { - CodeBlock moduleCodeBlock = - CodeBlock.of( - "$L.$L($L)", - binding.requiresModuleInstance() - ? "module" - : CodeBlock.of("$T", binding.bindingTypeElement().get().getClassName()), - getSimpleName(binding.bindingElement().get()), - makeParametersCodeBlock(parameterCodeBlocks)); + /** Represents the available fields in the generated factory class. */ + private static final class FactoryFields { + static FactoryFields create(ProductionBinding binding) { + UniqueNameSet nameSet = new UniqueNameSet(); + // TODO(bcorso, dpb): Add a test for the case when a Factory parameter is named "module". + Optional<FieldSpec> moduleField = + binding.requiresModuleInstance() + ? Optional.of( + createField( + binding.bindingTypeElement().get().getType().getTypeName(), + nameSet.getUniqueName("module"))) + : Optional.empty(); - final CodeBlock returnCodeBlock; - switch (binding.productionKind().get()) { - case IMMEDIATE: - returnCodeBlock = - CodeBlock.of("$T.<$T>immediateFuture($L)", FUTURES, providedTypeName, moduleCodeBlock); - break; - case FUTURE: - returnCodeBlock = moduleCodeBlock; - break; - case SET_OF_FUTURE: - returnCodeBlock = CodeBlock.of("$T.allAsSet($L)", PRODUCERS, moduleCodeBlock); - break; - default: - throw new AssertionError(); + ImmutableMap.Builder<DependencyRequest, FieldSpec> builder = + ImmutableMap.builder(); + generateBindingFieldsForDependencies(binding).forEach( + (dependency, field) -> + builder.put( + dependency, + createField(toJavaPoet(field.type()), nameSet.getUniqueName(field.name())))); + return new FactoryFields(binding, moduleField, builder.buildOrThrow()); } - return CodeBlock.of("return $L;", returnCodeBlock); + + private static FieldSpec createField(TypeName type, String name) { + return FieldSpec.builder(type, name, PRIVATE, FINAL).build(); + } + + private final Optional<FieldSpec> moduleField; + private final FieldSpec monitorField; + private final FieldSpec executorField; + private final ImmutableMap<DependencyRequest, FieldSpec> frameworkFields; + + private FactoryFields( + ProductionBinding binding, + Optional<FieldSpec> moduleField, + ImmutableMap<DependencyRequest, FieldSpec> frameworkFields) { + this.moduleField = moduleField; + this.monitorField = frameworkFields.get(binding.monitorRequest()); + this.executorField = frameworkFields.get(binding.executorRequest()); + this.frameworkFields = frameworkFields; + } + + FieldSpec get(DependencyRequest request) { + return frameworkFields.get(request); + } + + ImmutableList<FieldSpec> getAll() { + return moduleField.isPresent() + ? ImmutableList.<FieldSpec>builder() + .add(moduleField.get()) + .addAll(frameworkFields.values()) + .build() + : frameworkFields.values().asList(); + } } @Override @@ -549,4 +498,27 @@ // TODO(beder): examine if we can remove this or prevent subtypes of Future from being produced return ImmutableSet.of(FUTURE_RETURN_VALUE_IGNORED); } + + /** What kind of object a {@code @Produces}-annotated method returns. */ + private enum ProductionKind { + /** A value. */ + IMMEDIATE, + /** A {@code ListenableFuture<T>}. */ + FUTURE, + /** A {@code Set<ListenableFuture<T>>}. */ + SET_OF_FUTURE; + + /** Returns the kind of object a {@code @Produces}-annotated method returns. */ + static ProductionKind fromProducesMethod(XMethodElement producesMethod) { + if (isFutureType(producesMethod.getReturnType())) { + return FUTURE; + } else if (ContributionType.fromBindingElement(producesMethod) + .equals(ContributionType.SET_VALUES) + && isFutureType(SetType.from(producesMethod.getReturnType()).elementType())) { + return SET_OF_FUTURE; + } else { + return IMMEDIATE; + } + } + } }
diff --git a/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java b/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java index 9d08956..2b54779 100644 --- a/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java +++ b/java/dagger/internal/codegen/writing/ProducerFromProviderCreationExpression.java
@@ -17,15 +17,16 @@ package dagger.internal.codegen.writing; +import androidx.room.compiler.codegen.XClassName; import com.squareup.javapoet.ClassName; import com.squareup.javapoet.CodeBlock; import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; 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.internal.codegen.xprocessing.XTypeNames; import java.util.Optional; /** An {@code Producer} creation expression for provision bindings. */ @@ -49,8 +50,8 @@ } @Override - public Optional<ClassName> alternativeFrameworkClass() { - return Optional.of(TypeNames.PRODUCER); + public Optional<XClassName> alternativeFrameworkClass() { + return Optional.of(XTypeNames.PRODUCER); } @AssistedFactory
diff --git a/java/dagger/internal/codegen/writing/ProductionBindingRepresentation.java b/java/dagger/internal/codegen/writing/ProductionBindingRepresentation.java index 0793d6e..b646641 100644 --- a/java/dagger/internal/codegen/writing/ProductionBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProductionBindingRepresentation.java
@@ -24,8 +24,11 @@ import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.BindingRequest; +import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.binding.FrameworkType; -import dagger.internal.codegen.binding.ProductionBinding; +import dagger.internal.codegen.binding.MultiboundMapBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; +import dagger.internal.codegen.model.RequestKind; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -35,15 +38,15 @@ * that binding. */ final class ProductionBindingRepresentation implements BindingRepresentation { - private final ProductionBinding binding; + private final ContributionBinding binding; private final DerivedFromFrameworkInstanceRequestRepresentation.Factory derivedFromFrameworkInstanceRequestRepresentationFactory; - private final RequestRepresentation frameworkInstanceRequestRepresentation; + private final RequestRepresentation producerNodeInstanceRequestRepresentation; private final Map<BindingRequest, RequestRepresentation> requestRepresentations = new HashMap<>(); @AssistedInject ProductionBindingRepresentation( - @Assisted ProductionBinding binding, + @Assisted ContributionBinding binding, ComponentImplementation componentImplementation, DerivedFromFrameworkInstanceRequestRepresentation.Factory derivedFromFrameworkInstanceRequestRepresentationFactory, @@ -66,7 +69,7 @@ ? bindingRepresentations.scope( binding, unscopedFrameworkInstanceCreationExpressionFactory.create(binding)) : unscopedFrameworkInstanceCreationExpressionFactory.create(binding)); - this.frameworkInstanceRequestRepresentation = + this.producerNodeInstanceRequestRepresentation = producerNodeInstanceRequestRepresentationFactory.create(binding, frameworkInstanceSupplier); } @@ -77,11 +80,11 @@ } private RequestRepresentation getRequestRepresentationUncached(BindingRequest request) { - return request.frameworkType().isPresent() - ? frameworkInstanceRequestRepresentation + return request.requestKind().equals(RequestKind.PRODUCER) + ? producerNodeInstanceRequestRepresentation : derivedFromFrameworkInstanceRequestRepresentationFactory.create( binding, - frameworkInstanceRequestRepresentation, + producerNodeInstanceRequestRepresentation, request.requestKind(), FrameworkType.PRODUCER_NODE); } @@ -93,10 +96,10 @@ private Optional<MemberSelect> staticFactoryCreation() { if (binding.dependencies().isEmpty()) { if (binding.kind().equals(MULTIBOUND_MAP)) { - return Optional.of(StaticMemberSelects.emptyMapFactory(binding)); + return Optional.of(StaticMemberSelects.emptyMapFactory((MultiboundMapBinding) binding)); } if (binding.kind().equals(MULTIBOUND_SET)) { - return Optional.of(StaticMemberSelects.emptySetFactory(binding)); + return Optional.of(StaticMemberSelects.emptySetFactory((MultiboundSetBinding) binding)); } } return Optional.empty(); @@ -104,6 +107,6 @@ @AssistedFactory static interface Factory { - ProductionBindingRepresentation create(ProductionBinding binding); + ProductionBindingRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java b/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java index f031a72..cfdc718 100644 --- a/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProviderInstanceRequestRepresentation.java
@@ -20,15 +20,15 @@ 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 ProvisionBinding binding, + @Assisted ContributionBinding binding, SwitchingProviderInstanceSupplier.Factory switchingProviderInstanceSupplierFactory, StaticFactoryInstanceSupplier.Factory staticFactoryInstanceSupplierFactory, ProviderInstanceSupplier.Factory providerInstanceSupplierFactory, @@ -51,7 +51,7 @@ } private static FrameworkInstanceSupplier frameworkInstanceSupplier( - ProvisionBinding binding, + ContributionBinding binding, SwitchingProviderInstanceSupplier.Factory switchingProviderInstanceSupplierFactory, StaticFactoryInstanceSupplier.Factory staticFactoryInstanceSupplierFactory, ProviderInstanceSupplier.Factory providerInstanceSupplierFactory, @@ -71,6 +71,6 @@ @AssistedFactory static interface Factory { - ProviderInstanceRequestRepresentation create(ProvisionBinding binding); + ProviderInstanceRequestRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ProviderInstanceSupplier.java b/java/dagger/internal/codegen/writing/ProviderInstanceSupplier.java index bbfb50c..b5ec6f9 100644 --- a/java/dagger/internal/codegen/writing/ProviderInstanceSupplier.java +++ b/java/dagger/internal/codegen/writing/ProviderInstanceSupplier.java
@@ -19,7 +19,7 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; /** An object that initializes a framework-type component field for a binding. */ @@ -28,7 +28,7 @@ @AssistedInject ProviderInstanceSupplier( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, ComponentImplementation componentImplementation, UnscopedFrameworkInstanceCreationExpressionFactory unscopedFrameworkInstanceCreationExpressionFactory, @@ -51,6 +51,6 @@ @AssistedFactory static interface Factory { - ProviderInstanceSupplier create(ProvisionBinding binding); + ProviderInstanceSupplier create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java b/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java index 0f9b6f3..35cdb0d 100644 --- a/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java +++ b/java/dagger/internal/codegen/writing/ProvisionBindingRepresentation.java
@@ -24,7 +24,8 @@ 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.binding.ContributionBinding; +import dagger.internal.codegen.binding.DelegateBinding; import dagger.internal.codegen.model.RequestKind; import dagger.internal.codegen.writing.ComponentImplementation.CompilerMode; @@ -35,13 +36,13 @@ final class ProvisionBindingRepresentation implements BindingRepresentation { private final BindingGraph graph; private final CompilerMode compilerMode; - private final ProvisionBinding binding; + private final ContributionBinding binding; private final DirectInstanceBindingRepresentation directInstanceBindingRepresentation; private final FrameworkInstanceBindingRepresentation frameworkInstanceBindingRepresentation; @AssistedInject ProvisionBindingRepresentation( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, DirectInstanceBindingRepresentation.Factory directInstanceBindingRepresentationFactory, FrameworkInstanceBindingRepresentation.Factory frameworkInstanceBindingRepresentationFactory, BindingGraph graph, @@ -72,7 +73,7 @@ // be handled with simple pre-check in the graph. For example, a provider for a subcomponent // builder is backed with its direct instance, returning framework instance for both cases will // form a loop. There are also difficulties introduced by manually created framework requests. - // TODO(wanyingd): refactor framework instance so that we don't need to generate both direct + // TODO(bcorso): refactor framework instance so that we don't need to generate both direct // instance and framework instance representation for the same binding. if (compilerMode.isFastInit() && graph.topLevelBindingGraph().hasFrameworkRequest(binding)) { return false; @@ -105,18 +106,18 @@ * <p>The component needs to cache the value for scoped bindings except for {@code @Binds} * bindings whose scope is no stronger than their delegate's. */ - static boolean needsCaching(ProvisionBinding binding, BindingGraph graph) { + static boolean needsCaching(ContributionBinding binding, BindingGraph graph) { if (!binding.scope().isPresent()) { return false; } if (binding.kind().equals(DELEGATE)) { - return isBindsScopeStrongerThanDependencyScope(binding, graph); + return isBindsScopeStrongerThanDependencyScope((DelegateBinding) binding, graph); } return true; } @AssistedFactory static interface Factory { - ProvisionBindingRepresentation create(ProvisionBinding binding); + ProvisionBindingRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/SetFactoryCreationExpression.java b/java/dagger/internal/codegen/writing/SetFactoryCreationExpression.java index 559bb7d..25b9fe1 100644 --- a/java/dagger/internal/codegen/writing/SetFactoryCreationExpression.java +++ b/java/dagger/internal/codegen/writing/SetFactoryCreationExpression.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.XTypeNameKt.toJavaPoet; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.setFactoryClassName; @@ -27,18 +28,18 @@ import dagger.internal.codegen.base.SetType; import dagger.internal.codegen.binding.BindingGraph; import dagger.internal.codegen.binding.BindingType; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; import dagger.internal.codegen.javapoet.TypeNames; import dagger.internal.codegen.model.DependencyRequest; /** A factory creation expression for a multibound set. */ final class SetFactoryCreationExpression extends MultibindingFactoryCreationExpression { private final BindingGraph graph; - private final ContributionBinding binding; + private final MultiboundSetBinding binding; @AssistedInject SetFactoryCreationExpression( - @Assisted ContributionBinding binding, + @Assisted MultiboundSetBinding binding, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, BindingGraph graph) { @@ -49,7 +50,8 @@ @Override public CodeBlock creationExpression() { - CodeBlock.Builder builder = CodeBlock.builder().add("$T.", setFactoryClassName(binding)); + CodeBlock.Builder builder = + CodeBlock.builder().add("$T.", toJavaPoet(setFactoryClassName(binding))); if (!useRawType()) { SetType setType = SetType.from(binding.key()); builder.add( @@ -96,6 +98,6 @@ @AssistedFactory static interface Factory { - SetFactoryCreationExpression create(ContributionBinding binding); + SetFactoryCreationExpression create(MultiboundSetBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/SetRequestRepresentation.java b/java/dagger/internal/codegen/writing/SetRequestRepresentation.java index 68a340a..f8c9d08 100644 --- a/java/dagger/internal/codegen/writing/SetRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SetRequestRepresentation.java
@@ -34,7 +34,7 @@ import dagger.internal.codegen.base.ContributionType; import dagger.internal.codegen.base.SetType; import dagger.internal.codegen.binding.BindingGraph; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; import dagger.internal.codegen.javapoet.CodeBlocks; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.javapoet.TypeNames; @@ -43,14 +43,14 @@ /** A binding expression for multibound sets. */ final class SetRequestRepresentation extends RequestRepresentation { - private final ProvisionBinding binding; + private final MultiboundSetBinding binding; private final BindingGraph graph; private final ComponentRequestRepresentations componentRequestRepresentations; private final XProcessingEnv processingEnv; @AssistedInject SetRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted MultiboundSetBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, ComponentRequestRepresentations componentRequestRepresentations, @@ -146,7 +146,7 @@ return (!isSingleValue(dependency) && !isTypeAccessibleFrom( binding.key().type().xprocessing(), requestingClass.packageName()) - // TODO(wanyingd): Replace instanceof checks with validation on the binding. + // TODO(bcorso): Replace instanceof checks with validation on the binding. && (bindingExpression instanceof DerivedFromFrameworkInstanceRequestRepresentation || bindingExpression instanceof DelegateRequestRepresentation)) ? CodeBlocks.cast(expression, TypeNames.COLLECTION) @@ -189,6 +189,6 @@ @AssistedFactory static interface Factory { - SetRequestRepresentation create(ProvisionBinding binding); + SetRequestRepresentation create(MultiboundSetBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java b/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java index 79613fd..c284a14 100644 --- a/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SimpleMethodRequestRepresentation.java
@@ -21,25 +21,33 @@ import static com.google.common.base.Preconditions.checkArgument; import static dagger.internal.codegen.javapoet.CodeBlocks.makeParametersCodeBlock; import static dagger.internal.codegen.javapoet.TypeNames.rawTypeName; +import static dagger.internal.codegen.langmodel.Accessibility.isElementAccessibleFrom; +import static dagger.internal.codegen.langmodel.Accessibility.isRawTypeAccessible; import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom; -import static dagger.internal.codegen.writing.InjectionMethods.ProvisionMethod.requiresInjectionMethod; +import static dagger.internal.codegen.xprocessing.XElements.asExecutable; import static dagger.internal.codegen.xprocessing.XElements.asMethod; import static dagger.internal.codegen.xprocessing.XProcessingEnvs.isPreJava8SourceVersion; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XExecutableElement; +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.ImmutableSet; 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.binding.AssistedInjectionBinding; import dagger.internal.codegen.binding.ComponentRequirement; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.InjectionBinding; import dagger.internal.codegen.compileroption.CompilerOptions; import dagger.internal.codegen.javapoet.Expression; +import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.model.DependencyRequest; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.InjectionMethods.ProvisionMethod; @@ -50,9 +58,12 @@ * {@link dagger.internal.codegen.model.RequestKind#INSTANCE} requests. */ final class SimpleMethodRequestRepresentation extends RequestRepresentation { + private static final ImmutableSet<BindingKind> VALID_BINDING_KINDS = + ImmutableSet.of(BindingKind.INJECTION, BindingKind.ASSISTED_INJECTION, BindingKind.PROVISION); + private final CompilerOptions compilerOptions; private final XProcessingEnv processingEnv; - private final ProvisionBinding provisionBinding; + private final ContributionBinding binding; private final ComponentRequestRepresentations componentRequestRepresentations; private final MembersInjectionMethods membersInjectionMethods; private final ComponentRequirementExpressions componentRequirementExpressions; @@ -60,7 +71,7 @@ @AssistedInject SimpleMethodRequestRepresentation( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, MembersInjectionMethods membersInjectionMethods, CompilerOptions compilerOptions, XProcessingEnv processingEnv, @@ -69,11 +80,9 @@ ComponentImplementation componentImplementation) { this.compilerOptions = compilerOptions; this.processingEnv = processingEnv; - this.provisionBinding = binding; - checkArgument( - provisionBinding.implicitDependencies().isEmpty(), - "framework deps are not currently supported"); - checkArgument(provisionBinding.bindingElement().isPresent()); + this.binding = binding; + checkArgument(VALID_BINDING_KINDS.contains(binding.kind())); + checkArgument(binding.bindingElement().isPresent()); this.componentRequestRepresentations = componentRequestRepresentations; this.membersInjectionMethods = membersInjectionMethods; this.componentRequirementExpressions = componentRequirementExpressions; @@ -82,7 +91,7 @@ @Override Expression getDependencyExpression(ClassName requestingClass) { - return requiresInjectionMethod(provisionBinding, compilerOptions, requestingClass) + return requiresInjectionMethod(requestingClass) ? invokeInjectionMethod(requestingClass) : invokeMethod(requestingClass); } @@ -92,11 +101,11 @@ CodeBlock arguments = makeParametersCodeBlock( ProvisionMethod.invokeArguments( - provisionBinding, + binding, request -> dependencyArgument(request, requestingClass).codeBlock(), shardImplementation::getUniqueFieldNameForAssistedParam)); - XElement bindingElement = provisionBinding.bindingElement().get(); - XTypeElement bindingTypeElement = provisionBinding.bindingTypeElement().get(); + XElement bindingElement = binding.bindingElement().get(); + XTypeElement bindingTypeElement = binding.bindingTypeElement().get(); CodeBlock invocation; if (isConstructor(bindingElement)) { invocation = CodeBlock.of("new $T($L)", constructorTypeName(requestingClass), arguments); @@ -122,7 +131,7 @@ } private TypeName constructorTypeName(ClassName requestingClass) { - XType type = provisionBinding.key().type().xprocessing(); + XType type = binding.key().type().xprocessing(); return type.getTypeArguments().stream() .allMatch(t -> isTypeAccessibleFrom(t, requestingClass.packageName())) ? type.getTypeName() @@ -132,7 +141,7 @@ private Expression invokeInjectionMethod(ClassName requestingClass) { return injectMembers( ProvisionMethod.invoke( - provisionBinding, + binding, request -> dependencyArgument(request, requestingClass).codeBlock(), shardImplementation::getUniqueFieldNameForAssistedParam, requestingClass, @@ -147,25 +156,24 @@ } private Expression injectMembers(CodeBlock instance, ClassName requestingClass) { - if (provisionBinding.injectionSites().isEmpty()) { + if (!hasInjectionSites(binding)) { return Expression.create(simpleMethodReturnType(), instance); } if (isPreJava8SourceVersion(processingEnv)) { // Java 7 type inference can't figure out that instance in // injectParameterized(Parameterized_Factory.newParameterized()) is Parameterized<T> and not // Parameterized<Object> - if (!provisionBinding.key().type().xprocessing().getTypeArguments().isEmpty()) { - TypeName keyType = provisionBinding.key().type().xprocessing().getTypeName(); + if (!binding.key().type().xprocessing().getTypeArguments().isEmpty()) { + TypeName keyType = binding.key().type().xprocessing().getTypeName(); instance = CodeBlock.of("($T) ($T) $L", keyType, rawTypeName(keyType), instance); } } - return membersInjectionMethods.getInjectExpression( - provisionBinding.key(), instance, requestingClass); + return membersInjectionMethods.getInjectExpression(binding.key(), instance, requestingClass); } private Optional<CodeBlock> moduleReference(ClassName requestingClass) { - return provisionBinding.requiresModuleInstance() - ? provisionBinding + return binding.requiresModuleInstance() + ? binding .contributingModule() .map(XTypeElement::getType) .map(ComponentRequirement::forModule) @@ -174,13 +182,35 @@ } private XType simpleMethodReturnType() { - return provisionBinding - .contributedPrimitiveType() - .orElse(provisionBinding.key().type().xprocessing()); + return binding.contributedPrimitiveType().orElse(binding.key().type().xprocessing()); + } + + private boolean requiresInjectionMethod(ClassName requestingClass) { + XExecutableElement executableElement = asExecutable(binding.bindingElement().get()); + return hasInjectionSites(binding) + || binding.shouldCheckForNull(compilerOptions) + || !isElementAccessibleFrom(executableElement, requestingClass.packageName()) + // This check should be removable once we drop support for -source 7 + || executableElement.getParameters().stream() + .map(XExecutableParameterElement::getType) + .anyMatch(type -> !isRawTypeAccessible(type, requestingClass.packageName())); + } + + private static boolean hasInjectionSites(ContributionBinding binding) { + switch (binding.kind()) { + case INJECTION: + return !((InjectionBinding) binding).injectionSites().isEmpty(); + case ASSISTED_INJECTION: + return !((AssistedInjectionBinding) binding).injectionSites().isEmpty(); + case PROVISION: + return false; + default: + throw new AssertionError("Unexpected binding kind: " + binding.kind()); + } } @AssistedFactory static interface Factory { - SimpleMethodRequestRepresentation create(ProvisionBinding binding); + SimpleMethodRequestRepresentation create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/StaticFactoryInstanceSupplier.java b/java/dagger/internal/codegen/writing/StaticFactoryInstanceSupplier.java index 070cd63..cab6352 100644 --- a/java/dagger/internal/codegen/writing/StaticFactoryInstanceSupplier.java +++ b/java/dagger/internal/codegen/writing/StaticFactoryInstanceSupplier.java
@@ -23,6 +23,8 @@ import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.MultiboundMapBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; /** An object that returns static factory to satisfy framework instance request. */ final class StaticFactoryInstanceSupplier implements FrameworkInstanceSupplier { @@ -41,15 +43,15 @@ return frameworkInstanceSupplier.memberSelect(); } - // TODO(wanyingd): no-op members injector is currently handled in + // TODO(bcorso): no-op members injector is currently handled in // `MembersInjectorProviderCreationExpression`, we should inline the logic here so we won't create // an extra field for it. private MemberSelect staticFactoryCreation(ContributionBinding binding) { switch (binding.kind()) { case MULTIBOUND_MAP: - return StaticMemberSelects.emptyMapFactory(binding); + return StaticMemberSelects.emptyMapFactory((MultiboundMapBinding) binding); case MULTIBOUND_SET: - return StaticMemberSelects.emptySetFactory(binding); + return StaticMemberSelects.emptySetFactory((MultiboundSetBinding) binding); case PROVISION: case INJECTION: return StaticMemberSelects.factoryCreateNoArgumentMethod(binding);
diff --git a/java/dagger/internal/codegen/writing/StaticMemberSelects.java b/java/dagger/internal/codegen/writing/StaticMemberSelects.java index a1ea63c..7b72316 100644 --- a/java/dagger/internal/codegen/writing/StaticMemberSelects.java +++ b/java/dagger/internal/codegen/writing/StaticMemberSelects.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen.writing; +import static androidx.room.compiler.codegen.compat.XConverters.toJavaPoet; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static dagger.internal.codegen.binding.SourceFiles.bindingTypeElementTypeVariableNames; @@ -38,13 +39,14 @@ import dagger.internal.codegen.base.SetType; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingType; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.MultiboundMapBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; import dagger.internal.codegen.javapoet.CodeBlocks; /** Helper class for static member select creation. */ final class StaticMemberSelects { /** A {@link MemberSelect} for a factory of an empty map. */ - static MemberSelect emptyMapFactory(Binding binding) { + static MemberSelect emptyMapFactory(MultiboundMapBinding binding) { BindingType bindingType = binding.bindingType(); ImmutableList<XType> typeParameters = ImmutableList.copyOf(binding.key().type().xprocessing().getTypeArguments()); @@ -60,9 +62,9 @@ * dagger.internal.SetFactory#empty()}, {@link dagger.producers.internal.SetProducer#empty()}, or * {@link dagger.producers.internal.SetOfProducedProducer#empty()}, depending on the set bindings. */ - static MemberSelect emptySetFactory(ContributionBinding binding) { + static MemberSelect emptySetFactory(MultiboundSetBinding binding) { return new ParameterizedStaticMethod( - setFactoryClassName(binding), + toJavaPoet(setFactoryClassName(binding)), ImmutableList.of(SetType.from(binding.key()).elementType()), CodeBlock.of("empty()"), FACTORY); @@ -82,7 +84,7 @@ "%s should have no dependencies and be unscoped to create a no argument factory.", binding); - ClassName factoryName = generatedClassNameForBinding(binding); + ClassName factoryName = toJavaPoet(generatedClassNameForBinding(binding)); XType keyType = binding.key().type().xprocessing(); if (isDeclared(keyType)) { ImmutableList<TypeVariableName> typeVariables = bindingTypeElementTypeVariableNames(binding);
diff --git a/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java b/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java index c71c70a..bc6b189 100644 --- a/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java +++ b/java/dagger/internal/codegen/writing/SubcomponentCreatorRequestRepresentation.java
@@ -23,18 +23,19 @@ import dagger.assisted.Assisted; import dagger.assisted.AssistedFactory; import dagger.assisted.AssistedInject; -import dagger.internal.codegen.binding.ContributionBinding; +import dagger.internal.codegen.binding.SubcomponentCreatorBinding; import dagger.internal.codegen.javapoet.Expression; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; /** 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 SubcomponentCreatorBinding binding; @AssistedInject SubcomponentCreatorRequestRepresentation( - @Assisted ContributionBinding binding, ComponentImplementation componentImplementation) { + @Assisted SubcomponentCreatorBinding binding, + ComponentImplementation componentImplementation) { this.binding = binding; this.shardImplementation = componentImplementation.shardImplementation(binding); } @@ -58,6 +59,6 @@ @AssistedFactory static interface Factory { - SubcomponentCreatorRequestRepresentation create(ContributionBinding binding); + SubcomponentCreatorRequestRepresentation create(SubcomponentCreatorBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java b/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java index 6f8ca7b..4d944bd 100644 --- a/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java +++ b/java/dagger/internal/codegen/writing/SwitchingProviderInstanceSupplier.java
@@ -25,7 +25,7 @@ import dagger.assisted.AssistedInject; import dagger.internal.codegen.binding.Binding; import dagger.internal.codegen.binding.BindingGraph; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.ContributionBinding; import dagger.internal.codegen.model.BindingKind; import dagger.internal.codegen.writing.ComponentImplementation.ShardImplementation; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; @@ -39,7 +39,7 @@ @AssistedInject SwitchingProviderInstanceSupplier( - @Assisted ProvisionBinding binding, + @Assisted ContributionBinding binding, BindingGraph graph, ComponentImplementation componentImplementation, UnscopedDirectInstanceRequestRepresentationFactory @@ -80,6 +80,6 @@ @AssistedFactory static interface Factory { - SwitchingProviderInstanceSupplier create(ProvisionBinding binding); + SwitchingProviderInstanceSupplier create(ContributionBinding binding); } }
diff --git a/java/dagger/internal/codegen/writing/UnscopedDirectInstanceRequestRepresentationFactory.java b/java/dagger/internal/codegen/writing/UnscopedDirectInstanceRequestRepresentationFactory.java index cf4f260..88dd1c3 100644 --- a/java/dagger/internal/codegen/writing/UnscopedDirectInstanceRequestRepresentationFactory.java +++ b/java/dagger/internal/codegen/writing/UnscopedDirectInstanceRequestRepresentationFactory.java
@@ -16,9 +16,17 @@ package dagger.internal.codegen.writing; -import dagger.internal.codegen.binding.ComponentRequirement; +import dagger.internal.codegen.binding.AssistedFactoryBinding; +import dagger.internal.codegen.binding.BoundInstanceBinding; +import dagger.internal.codegen.binding.ComponentBinding; +import dagger.internal.codegen.binding.ComponentDependencyBinding; +import dagger.internal.codegen.binding.ComponentDependencyProvisionBinding; import dagger.internal.codegen.binding.ContributionBinding; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.DelegateBinding; +import dagger.internal.codegen.binding.MultiboundMapBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; +import dagger.internal.codegen.binding.OptionalBinding; +import dagger.internal.codegen.binding.SubcomponentCreatorBinding; import dagger.internal.codegen.model.RequestKind; import javax.inject.Inject; @@ -50,7 +58,6 @@ @Inject UnscopedDirectInstanceRequestRepresentationFactory( - ComponentImplementation componentImplementation, AssistedFactoryRequestRepresentation.Factory assistedFactoryRequestRepresentationFactory, ComponentInstanceRequestRepresentation.Factory componentInstanceRequestRepresentationFactory, ComponentProvisionRequestRepresentation.Factory @@ -84,40 +91,43 @@ RequestRepresentation create(ContributionBinding binding) { switch (binding.kind()) { case DELEGATE: - return delegateRequestRepresentationFactory.create(binding, RequestKind.INSTANCE); + return delegateRequestRepresentationFactory.create( + (DelegateBinding) binding, RequestKind.INSTANCE); case COMPONENT: - return componentInstanceRequestRepresentationFactory.create(binding); + return componentInstanceRequestRepresentationFactory.create((ComponentBinding) binding); case COMPONENT_DEPENDENCY: return componentRequirementRequestRepresentationFactory.create( - binding, ComponentRequirement.forDependency(binding.key().type().xprocessing())); + (ComponentDependencyBinding) binding); case COMPONENT_PROVISION: - return componentProvisionRequestRepresentationFactory.create((ProvisionBinding) binding); + return componentProvisionRequestRepresentationFactory.create( + (ComponentDependencyProvisionBinding) binding); case SUBCOMPONENT_CREATOR: - return subcomponentCreatorRequestRepresentationFactory.create(binding); + return subcomponentCreatorRequestRepresentationFactory.create( + (SubcomponentCreatorBinding) binding); case MULTIBOUND_SET: - return setRequestRepresentationFactory.create((ProvisionBinding) binding); + return setRequestRepresentationFactory.create((MultiboundSetBinding) binding); case MULTIBOUND_MAP: - return mapRequestRepresentationFactory.create((ProvisionBinding) binding); + return mapRequestRepresentationFactory.create((MultiboundMapBinding) binding); case OPTIONAL: - return optionalRequestRepresentationFactory.create((ProvisionBinding) binding); + return optionalRequestRepresentationFactory.create((OptionalBinding) binding); case BOUND_INSTANCE: return componentRequirementRequestRepresentationFactory.create( - binding, ComponentRequirement.forBoundInstance(binding)); + (BoundInstanceBinding) binding); case ASSISTED_FACTORY: - return assistedFactoryRequestRepresentationFactory.create((ProvisionBinding) binding); + return assistedFactoryRequestRepresentationFactory.create((AssistedFactoryBinding) binding); case INJECTION: case PROVISION: - return simpleMethodRequestRepresentationFactory.create((ProvisionBinding) binding); + return simpleMethodRequestRepresentationFactory.create(binding); case ASSISTED_INJECTION: case MEMBERS_INJECTOR:
diff --git a/java/dagger/internal/codegen/writing/UnscopedFrameworkInstanceCreationExpressionFactory.java b/java/dagger/internal/codegen/writing/UnscopedFrameworkInstanceCreationExpressionFactory.java index 36807c2..c105cff 100644 --- a/java/dagger/internal/codegen/writing/UnscopedFrameworkInstanceCreationExpressionFactory.java +++ b/java/dagger/internal/codegen/writing/UnscopedFrameworkInstanceCreationExpressionFactory.java
@@ -17,9 +17,18 @@ package dagger.internal.codegen.writing; import com.squareup.javapoet.CodeBlock; +import dagger.internal.codegen.binding.BoundInstanceBinding; +import dagger.internal.codegen.binding.ComponentDependencyBinding; +import dagger.internal.codegen.binding.ComponentDependencyProductionBinding; +import dagger.internal.codegen.binding.ComponentDependencyProvisionBinding; import dagger.internal.codegen.binding.ComponentRequirement; import dagger.internal.codegen.binding.ContributionBinding; -import dagger.internal.codegen.binding.ProvisionBinding; +import dagger.internal.codegen.binding.DelegateBinding; +import dagger.internal.codegen.binding.MembersInjectorBinding; +import dagger.internal.codegen.binding.MultiboundMapBinding; +import dagger.internal.codegen.binding.MultiboundSetBinding; +import dagger.internal.codegen.binding.OptionalBinding; +import dagger.internal.codegen.binding.ProductionBinding; import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; import javax.inject.Inject; @@ -109,14 +118,17 @@ case BOUND_INSTANCE: return instanceFactoryCreationExpression( - binding, ComponentRequirement.forBoundInstance(binding)); + binding, + ComponentRequirement.forBoundInstance((BoundInstanceBinding) binding)); case COMPONENT_DEPENDENCY: return instanceFactoryCreationExpression( - binding, ComponentRequirement.forDependency(binding.key().type().xprocessing())); + binding, + ComponentRequirement.forDependency((ComponentDependencyBinding) binding)); case COMPONENT_PROVISION: - return dependencyMethodProviderCreationExpressionFactory.create((ProvisionBinding) binding); + return dependencyMethodProviderCreationExpressionFactory.create( + (ComponentDependencyProvisionBinding) binding); case SUBCOMPONENT_CREATOR: return anonymousProviderCreationExpressionFactory.create(binding); @@ -128,25 +140,28 @@ return injectionOrProvisionProviderCreationExpressionFactory.create(binding); case COMPONENT_PRODUCTION: - return dependencyMethodProducerCreationExpressionFactory.create(binding); + return dependencyMethodProducerCreationExpressionFactory.create( + (ComponentDependencyProductionBinding) binding); case PRODUCTION: - return producerCreationExpressionFactory.create(binding); + return producerCreationExpressionFactory.create((ProductionBinding) binding); case MULTIBOUND_SET: - return setFactoryCreationExpressionFactory.create(binding); + return setFactoryCreationExpressionFactory.create((MultiboundSetBinding) binding); case MULTIBOUND_MAP: - return mapFactoryCreationExpressionFactory.create(binding); + return mapFactoryCreationExpressionFactory.create((MultiboundMapBinding) binding); case DELEGATE: - return delegatingFrameworkInstanceCreationExpressionFactory.create(binding); + return delegatingFrameworkInstanceCreationExpressionFactory.create( + (DelegateBinding) binding); case OPTIONAL: - return optionalFactoryInstanceCreationExpressionFactory.create(binding); + return optionalFactoryInstanceCreationExpressionFactory.create((OptionalBinding) binding); case MEMBERS_INJECTOR: - return membersInjectorProviderCreationExpressionFactory.create((ProvisionBinding) binding); + return membersInjectorProviderCreationExpressionFactory.create( + (MembersInjectorBinding) binding); default: throw new AssertionError(binding);
diff --git a/java/dagger/internal/codegen/xprocessing/BUILD b/java/dagger/internal/codegen/xprocessing/BUILD index da465e1..f03b2f9 100644 --- a/java/dagger/internal/codegen/xprocessing/BUILD +++ b/java/dagger/internal/codegen/xprocessing/BUILD
@@ -15,7 +15,7 @@ # Description: # Import for including XProcessing in Dagger. -load("@rules_java//java:defs.bzl", "java_import") +load("@rules_java//java:defs.bzl", "java_import", "java_library") package(default_visibility = ["//:src"]) @@ -32,6 +32,7 @@ "//java/dagger/internal/codegen/extension", "//java/dagger/spi", "//third_party/java/auto:common", + "//third_party/java/auto:value", "//third_party/java/guava/base", "//third_party/java/guava/collect", "//third_party/java/javapoet", @@ -63,6 +64,8 @@ exports = [ ":xprocessing-testing-lib", "@maven//:com_google_devtools_ksp_symbol_processing", + "@maven//:com_google_devtools_ksp_symbol_processing_aa_embeddable", + "@maven//:com_google_devtools_ksp_symbol_processing_common_deps", "@maven//:org_jetbrains_kotlin_kotlin_annotation_processing_embeddable", "@maven//:org_jetbrains_kotlin_kotlin_compiler_embeddable", "@maven//:org_jetbrains_kotlin_kotlin_daemon_embeddable",
diff --git a/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java b/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java index bf8e94f..26246ff 100644 --- a/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java +++ b/java/dagger/internal/codegen/xprocessing/JavaPoetExt.java
@@ -16,11 +16,14 @@ package dagger.internal.codegen.xprocessing; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; import static dagger.internal.codegen.xprocessing.XElements.getSimpleName; import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; +import com.google.common.collect.ImmutableSet; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.TypeSpec; @@ -53,5 +56,23 @@ return ParameterSpec.builder(param.getType().getTypeName(), param.getJvmName()).build(); } + public static ParameterSpec toParameterSpec( + XExecutableParameterElement parameter, XType parameterType) { + Nullability nullability = Nullability.of(parameter); + ImmutableSet<AnnotationSpec> typeUseNullableAnnotations = + nullability.typeUseNullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableSet()); + ImmutableSet<AnnotationSpec> nonTypeUseNullableAnnotations = + nullability.nonTypeUseNullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableSet()); + return ParameterSpec.builder( + parameterType.getTypeName().annotated(typeUseNullableAnnotations.asList()), + parameter.getJvmName()) + .addAnnotations(nonTypeUseNullableAnnotations) + .build(); + } + private JavaPoetExt() {} }
diff --git a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java index cc8c2f4..2eaac12 100644 --- a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java +++ b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java
@@ -16,15 +16,17 @@ package dagger.internal.codegen.xprocessing; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; +import static dagger.internal.codegen.xprocessing.JavaPoetExt.toParameterSpec; import static javax.lang.model.element.Modifier.PROTECTED; import static javax.lang.model.element.Modifier.PUBLIC; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XMethodType; import androidx.room.compiler.processing.XType; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.MethodSpec; -import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeName; // TODO(bcorso): Consider moving these methods into XProcessing library. /** A utility class for {@link MethodSpec} helper methods. */ @@ -33,22 +35,36 @@ /** Returns a {@link MethodSpec} that overrides the given method. */ public static MethodSpec.Builder overriding(XMethodElement method, XType owner) { XMethodType methodType = method.asMemberOf(owner); + Nullability nullability = Nullability.of(method); MethodSpec.Builder builder = // We're overriding the method so we have to use the jvm name here. MethodSpec.methodBuilder(method.getJvmName()) .addAnnotation(Override.class) + .addAnnotations( + nullability.nonTypeUseNullableAnnotations().stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList())) .addTypeVariables(methodType.getTypeVariableNames()) .varargs(method.isVarArgs()) - .returns(methodType.getReturnType().getTypeName()); + .returns( + methodType + .getReturnType() + .getTypeName() + .annotated( + nullability.typeUseNullableAnnotations().stream() + .map(AnnotationSpec::builder) + .map(AnnotationSpec.Builder::build) + .collect(toImmutableList()))); if (method.isPublic()) { builder.addModifiers(PUBLIC); } else if (method.isProtected()) { builder.addModifiers(PROTECTED); } for (int i = 0; i < methodType.getParameterTypes().size(); i++) { - String parameterName = method.getParameters().get(i).getJvmName(); - TypeName parameterType = methodType.getParameterTypes().get(i).getTypeName(); - builder.addParameter(ParameterSpec.builder(parameterType, parameterName).build()); + XExecutableParameterElement parameter = method.getParameters().get(i); + XType parameterType = methodType.getParameterTypes().get(i); + builder.addParameter(toParameterSpec(parameter, parameterType)); } method.getThrownTypes().stream().map(XType::getTypeName).forEach(builder::addException); return builder;
diff --git a/java/dagger/internal/codegen/xprocessing/Nullability.java b/java/dagger/internal/codegen/xprocessing/Nullability.java new file mode 100644 index 0000000..e704858 --- /dev/null +++ b/java/dagger/internal/codegen/xprocessing/Nullability.java
@@ -0,0 +1,112 @@ +/* + * 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 static androidx.room.compiler.processing.XElementKt.isMethod; +import static androidx.room.compiler.processing.XElementKt.isVariableElement; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet; +import static dagger.internal.codegen.xprocessing.XElements.asMethod; +import static dagger.internal.codegen.xprocessing.XElements.asVariable; + +import androidx.room.compiler.processing.XAnnotated; +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 com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import com.squareup.javapoet.ClassName; +import java.util.Optional; + +/** + * Contains information about the nullability of an element or type. + * + * <p>Note that an element can be nullable if either: + * + * <ul> + * <li>The element is annotated with {@code Nullable} or + * <li>the associated kotlin type is nullable (i.e. {@code T?} types in Kotlin source). + * </ul> + */ +@AutoValue +public abstract class Nullability { + /** A constant that can represent any non-null element. */ + public static final Nullability NOT_NULLABLE = + new AutoValue_Nullability(ImmutableSet.of(), ImmutableSet.of(), false); + + public static Nullability of(XElement element) { + ImmutableSet<ClassName> nonTypeUseNullableAnnotations = getNullableAnnotations(element); + Optional<XType> type = getType(element); + ImmutableSet<ClassName> typeUseNullableAnnotations = + ImmutableSet.of(); + boolean isKotlinTypeNullable = + // 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 ignore type nullability for elements in java sources. + !element.getClosestMemberContainer().isFromJava() + && type.isPresent() + && type.get().getNullability() == XNullability.NULLABLE; + return new AutoValue_Nullability( + nonTypeUseNullableAnnotations, + // Filter type use annotations that are also found on the element as non-type use + // annotations. This prevents them from being applied twice in some scenarios and just + // defaults to using them in the way before Dagger supported type use annotations. + Sets.difference(typeUseNullableAnnotations, nonTypeUseNullableAnnotations).immutableCopy(), + isKotlinTypeNullable); + } + + private static ImmutableSet<ClassName> getNullableAnnotations(XAnnotated annotated) { + return annotated.getAllAnnotations().stream() + .map(XAnnotations::getClassName) + .filter(annotation -> annotation.simpleName().contentEquals("Nullable")) + .collect(toImmutableSet()); + } + + private static Optional<XType> getType(XElement element) { + if (isMethod(element)) { + return Optional.of(asMethod(element).getReturnType()); + } else if (isVariableElement(element)) { + return Optional.of(asVariable(element).getType()); + } + return Optional.empty(); + } + + public abstract ImmutableSet<ClassName> nonTypeUseNullableAnnotations(); + + public abstract ImmutableSet<ClassName> typeUseNullableAnnotations(); + + /** + * 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. + */ + public abstract boolean isKotlinTypeNullable(); + + public ImmutableSet<ClassName> nullableAnnotations() { + return ImmutableSet.<ClassName>builder() + .addAll(nonTypeUseNullableAnnotations()) + .addAll(typeUseNullableAnnotations()).build(); + } + + public final boolean isNullable() { + return isKotlinTypeNullable() || !nullableAnnotations().isEmpty(); + } + + Nullability() {} +}
diff --git a/java/dagger/internal/codegen/xprocessing/XElements.java b/java/dagger/internal/codegen/xprocessing/XElements.java index b63d4d9..2f7efce 100644 --- a/java/dagger/internal/codegen/xprocessing/XElements.java +++ b/java/dagger/internal/codegen/xprocessing/XElements.java
@@ -329,16 +329,22 @@ return asTypeElement(element).getQualifiedName(); } else if (isExecutable(element)) { XExecutableElement executable = asExecutable(element); + // TODO(b/318709946) resolving ksp types can be expensive, therefore we should avoid it + // here for extreme cases until ksp improved the performance. + boolean tooManyParameters = + getProcessingEnv(element).getBackend().equals(XProcessingEnv.Backend.KSP) + && executable.getParameters().size() > 10; return String.format( "%s(%s)", getSimpleName( - isConstructor(element) - ? asConstructor(element).getEnclosingElement() - : executable), - executable.getParameters().stream() - .map(XExecutableParameterElement::getType) - .map(XTypes::toStableString) - .collect(joining(","))); + isConstructor(element) ? asConstructor(element).getEnclosingElement() : executable), + (tooManyParameters + ? executable.getParameters().stream().limit(10) + : executable.getParameters().stream() + .map(XExecutableParameterElement::getType) + .map(XTypes::toStableString) + .collect(joining(","))) + + (tooManyParameters ? ", ..." : "")); } else if (isEnumEntry(element) || isField(element) || isMethodParameter(element)
diff --git a/java/dagger/internal/codegen/xprocessing/XTypeElements.java b/java/dagger/internal/codegen/xprocessing/XTypeElements.java index 7330b8f..33b0f5b 100644 --- a/java/dagger/internal/codegen/xprocessing/XTypeElements.java +++ b/java/dagger/internal/codegen/xprocessing/XTypeElements.java
@@ -81,7 +81,7 @@ .collect(toImmutableList()); } - // TODO(wanyingd): rename this to getAllMethodsWithoutPrivate, since the private method declared + // TODO(bcorso): rename this to getAllMethodsWithoutPrivate, since the private method declared // within this element is being filtered out. This doesn't mirror {@code // MoreElements#getAllMethods}'s behavior but have the same name, and can cause confusion to // developers.
diff --git a/java/dagger/internal/codegen/xprocessing/XTypeNames.java b/java/dagger/internal/codegen/xprocessing/XTypeNames.java new file mode 100644 index 0000000..d9c7213 --- /dev/null +++ b/java/dagger/internal/codegen/xprocessing/XTypeNames.java
@@ -0,0 +1,293 @@ +/* + * 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.xprocessing; + +import static com.google.common.collect.Iterables.getLast; + +import androidx.room.compiler.codegen.XClassName; +import androidx.room.compiler.codegen.XTypeName; +import androidx.room.compiler.processing.XType; +import com.google.common.collect.ImmutableSet; + +/** Common names and convenience methods for XPoet {@link XTypeName} usage. */ +public final class XTypeNames { + + // Dagger Core classnames + public static final XClassName ASSISTED = XClassName.Companion.get("dagger.assisted", "Assisted"); + public static final XClassName ASSISTED_FACTORY = + XClassName.Companion.get("dagger.assisted", "AssistedFactory"); + public static final XClassName ASSISTED_INJECT = + XClassName.Companion.get("dagger.assisted", "AssistedInject"); + public static final XClassName BINDS = XClassName.Companion.get("dagger", "Binds"); + public static final XClassName BINDS_INSTANCE = + XClassName.Companion.get("dagger", "BindsInstance"); + public static final XClassName BINDS_OPTIONAL_OF = + XClassName.Companion.get("dagger", "BindsOptionalOf"); + public static final XClassName COMPONENT = XClassName.Companion.get("dagger", "Component"); + public static final XClassName COMPONENT_BUILDER = + XClassName.Companion.get("dagger", "Component", "Builder"); + public static final XClassName COMPONENT_FACTORY = + XClassName.Companion.get("dagger", "Component", "Factory"); + public static final XClassName DAGGER_PROCESSING_OPTIONS = + XClassName.Companion.get("dagger", "DaggerProcessingOptions"); + public static final XClassName ELEMENTS_INTO_SET = + XClassName.Companion.get("dagger.multibindings", "ElementsIntoSet"); + public static final XClassName INTO_MAP = + XClassName.Companion.get("dagger.multibindings", "IntoMap"); + public static final XClassName INTO_SET = + XClassName.Companion.get("dagger.multibindings", "IntoSet"); + public static final XClassName MAP_KEY = XClassName.Companion.get("dagger", "MapKey"); + public static final XClassName MODULE = XClassName.Companion.get("dagger", "Module"); + public static final XClassName MULTIBINDS = + XClassName.Companion.get("dagger.multibindings", "Multibinds"); + public static final XClassName PROVIDES = XClassName.Companion.get("dagger", "Provides"); + public static final XClassName REUSABLE = XClassName.Companion.get("dagger", "Reusable"); + public static final XClassName SUBCOMPONENT = XClassName.Companion.get("dagger", "Subcomponent"); + public static final XClassName SUBCOMPONENT_BUILDER = + XClassName.Companion.get("dagger", "Subcomponent", "Builder"); + public static final XClassName SUBCOMPONENT_FACTORY = + XClassName.Companion.get("dagger", "Subcomponent", "Factory"); + + // Dagger Internal classnames + public static final XClassName IDENTIFIER_NAME_STRING = + XClassName.Companion.get("dagger.internal", "IdentifierNameString"); + public static final XClassName KEEP_FIELD_TYPE = + XClassName.Companion.get("dagger.internal", "KeepFieldType"); + public static final XClassName LAZY_CLASS_KEY = + XClassName.Companion.get("dagger.multibindings", "LazyClassKey"); + public static final XClassName LAZY_CLASS_KEY_MAP = + XClassName.Companion.get("dagger.internal", "LazyClassKeyMap"); + public static final XClassName LAZY_CLASS_KEY_MAP_FACTORY = + XClassName.Companion.get("dagger.internal", "LazyClassKeyMap", "MapFactory"); + public static final XClassName LAZY_CLASS_KEY_MAP_PROVIDER_FACTORY = + XClassName.Companion.get("dagger.internal", "LazyClassKeyMap", "MapProviderFactory"); + public static final XClassName LAZY_MAP_OF_PRODUCED_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "LazyMapOfProducedProducer"); + public static final XClassName LAZY_MAP_OF_PRODUCER_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "LazyMapOfProducerProducer"); + public static final XClassName LAZY_MAP_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "LazyMapProducer"); + + public static final XClassName DELEGATE_FACTORY = + XClassName.Companion.get("dagger.internal", "DelegateFactory"); + public static final XClassName DOUBLE_CHECK = + XClassName.Companion.get("dagger.internal", "DoubleCheck"); + + public static final XClassName FACTORY = XClassName.Companion.get("dagger.internal", "Factory"); + public static final XClassName INJECTED_FIELD_SIGNATURE = + XClassName.Companion.get("dagger.internal", "InjectedFieldSignature"); + public static final XClassName INSTANCE_FACTORY = + XClassName.Companion.get("dagger.internal", "InstanceFactory"); + public static final XClassName MAP_BUILDER = + XClassName.Companion.get("dagger.internal", "MapBuilder"); + public static final XClassName MAP_FACTORY = + XClassName.Companion.get("dagger.internal", "MapFactory"); + public static final XClassName MAP_PROVIDER_FACTORY = + XClassName.Companion.get("dagger.internal", "MapProviderFactory"); + public static final XClassName MEMBERS_INJECTOR = + XClassName.Companion.get("dagger", "MembersInjector"); + public static final XClassName MEMBERS_INJECTORS = + XClassName.Companion.get("dagger.internal", "MembersInjectors"); + public static final XClassName PROVIDER = XClassName.Companion.get("javax.inject", "Provider"); + public static final XClassName DAGGER_PROVIDER = + XClassName.Companion.get("dagger.internal", "Provider"); + public static final XClassName DAGGER_PROVIDERS = + XClassName.Companion.get("dagger.internal", "Providers"); + public static final XClassName PROVIDER_OF_LAZY = + XClassName.Companion.get("dagger.internal", "ProviderOfLazy"); + public static final XClassName SCOPE_METADATA = + XClassName.Companion.get("dagger.internal", "ScopeMetadata"); + public static final XClassName QUALIFIER_METADATA = + XClassName.Companion.get("dagger.internal", "QualifierMetadata"); + public static final XClassName SET_FACTORY = + XClassName.Companion.get("dagger.internal", "SetFactory"); + public static final XClassName SINGLE_CHECK = + XClassName.Companion.get("dagger.internal", "SingleCheck"); + public static final XClassName LAZY = XClassName.Companion.get("dagger", "Lazy"); + + // Dagger Producers classnames + public static final XClassName ABSTRACT_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "AbstractProducer"); + public static final XClassName ABSTRACT_PRODUCES_METHOD_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "AbstractProducesMethodProducer"); + public static final XClassName CANCELLATION_LISTENER = + XClassName.Companion.get("dagger.producers.internal", "CancellationListener"); + public static final XClassName CANCELLATION_POLICY = + XClassName.Companion.get("dagger.producers", "CancellationPolicy"); + public static final XClassName DELEGATE_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "DelegateProducer"); + public static final XClassName DEPENDENCY_METHOD_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "DependencyMethodProducer"); + public static final XClassName MAP_OF_PRODUCED_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "MapOfProducedProducer"); + public static final XClassName MAP_OF_PRODUCER_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "MapOfProducerProducer"); + public static final XClassName MAP_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "MapProducer"); + public static final XClassName MONITORS = + XClassName.Companion.get("dagger.producers.monitoring.internal", "Monitors"); + public static final XClassName PRODUCED = + XClassName.Companion.get("dagger.producers", "Produced"); + public static final XClassName PRODUCER = + XClassName.Companion.get("dagger.producers", "Producer"); + public static final XClassName PRODUCERS = + XClassName.Companion.get("dagger.producers.internal", "Producers"); + public static final XClassName PRODUCER_MODULE = + XClassName.Companion.get("dagger.producers", "ProducerModule"); + public static final XClassName PRODUCES = + XClassName.Companion.get("dagger.producers", "Produces"); + public static final XClassName PRODUCTION = + XClassName.Companion.get("dagger.producers", "Production"); + public static final XClassName PRODUCTION_COMPONENT = + XClassName.Companion.get("dagger.producers", "ProductionComponent"); + public static final XClassName PRODUCTION_COMPONENT_BUILDER = + XClassName.Companion.get("dagger.producers", "ProductionComponent", "Builder"); + public static final XClassName PRODUCTION_COMPONENT_FACTORY = + XClassName.Companion.get("dagger.producers", "ProductionComponent", "Factory"); + public static final XClassName PRODUCTION_EXECTUTOR_MODULE = + XClassName.Companion.get("dagger.producers.internal", "ProductionExecutorModule"); + public static final XClassName PRODUCTION_IMPLEMENTATION = + XClassName.Companion.get("dagger.producers.internal", "ProductionImplementation"); + public static final XClassName PRODUCTION_SUBCOMPONENT = + XClassName.Companion.get("dagger.producers", "ProductionSubcomponent"); + public static final XClassName PRODUCTION_SUBCOMPONENT_BUILDER = + XClassName.Companion.get("dagger.producers", "ProductionSubcomponent", "Builder"); + public static final XClassName PRODUCTION_SUBCOMPONENT_FACTORY = + XClassName.Companion.get("dagger.producers", "ProductionSubcomponent", "Factory"); + public static final XClassName PRODUCER_TOKEN = + XClassName.Companion.get("dagger.producers.monitoring", "ProducerToken"); + public static final XClassName PRODUCTION_COMPONENT_MONITOR = + XClassName.Companion.get("dagger.producers.monitoring", "ProductionComponentMonitor"); + public static final XClassName PRODUCTION_COMPONENT_MONITOR_FACTORY = + XClassName.Companion.get( + "dagger.producers.monitoring", "ProductionComponentMonitor", "Factory"); + public static final XClassName SET_OF_PRODUCED_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "SetOfProducedProducer"); + public static final XClassName SET_PRODUCER = + XClassName.Companion.get("dagger.producers.internal", "SetProducer"); + public static final XClassName PRODUCTION_SCOPE = + XClassName.Companion.get("dagger.producers", "ProductionScope"); + + // Other classnames + public static final XClassName EXECUTOR = + XClassName.Companion.get("java.util.concurrent", "Executor"); + public static final XClassName ERROR = XClassName.Companion.get("java.lang", "Error"); + public static final XClassName EXCEPTION = XClassName.Companion.get("java.lang", "Exception"); + public static final XClassName RUNTIME_EXCEPTION = + XClassName.Companion.get("java.lang", "RuntimeException"); + public static final XClassName STRING = XClassName.Companion.get("java.lang", "String"); + + public static final XClassName MAP = XClassName.Companion.get("java.util", "Map"); + public static final XClassName KOTLIN_METADATA = XClassName.Companion.get("kotlin", "Metadata"); + public static final XClassName IMMUTABLE_MAP = + XClassName.Companion.get("com.google.common.collect", "ImmutableMap"); + public static final XClassName SINGLETON = + XClassName.Companion.get("jakarta.inject", "Singleton"); + public static final XClassName SINGLETON_JAVAX = + XClassName.Companion.get("javax.inject", "Singleton"); + public static final XClassName SCOPE = XClassName.Companion.get("jakarta.inject", "Scope"); + public static final XClassName SCOPE_JAVAX = XClassName.Companion.get("javax.inject", "Scope"); + public static final XClassName INJECT = XClassName.Companion.get("jakarta.inject", "Inject"); + public static final XClassName INJECT_JAVAX = XClassName.Companion.get("javax.inject", "Inject"); + public static final XClassName QUALIFIER = + XClassName.Companion.get("jakarta.inject", "Qualifier"); + public static final XClassName QUALIFIER_JAVAX = + XClassName.Companion.get("javax.inject", "Qualifier"); + public static final XClassName COLLECTION = XClassName.Companion.get("java.util", "Collection"); + public static final XClassName LIST = XClassName.Companion.get("java.util", "List"); + public static final XClassName SET = XClassName.Companion.get("java.util", "Set"); + public static final XClassName IMMUTABLE_SET = + XClassName.Companion.get("com.google.common.collect", "ImmutableSet"); + public static final XClassName FUTURES = + XClassName.Companion.get("com.google.common.util.concurrent", "Futures"); + public static final XClassName LISTENABLE_FUTURE = + XClassName.Companion.get("com.google.common.util.concurrent", "ListenableFuture"); + public static final XClassName FLUENT_FUTURE = + XClassName.Companion.get("com.google.common.util.concurrent", "FluentFuture"); + public static final XClassName GUAVA_OPTIONAL = + XClassName.Companion.get("com.google.common.base", "Optional"); + public static final XClassName JDK_OPTIONAL = XClassName.Companion.get("java.util", "Optional"); + public static final XClassName OVERRIDE = XClassName.Companion.get("java.lang", "Override"); + public static final XClassName JVM_STATIC = XClassName.Companion.get("kotlin.jvm", "JvmStatic"); + public static final XClassName CLASS = XClassName.Companion.get("java.lang", "Class"); + public static final XClassName KCLASS = XClassName.Companion.get("kotlin.reflect", "KClass"); + + public static XTypeName abstractProducerOf(XTypeName typeName) { + return ABSTRACT_PRODUCER.parametrizedBy(typeName); + } + + public static XTypeName factoryOf(XTypeName factoryType) { + return FACTORY.parametrizedBy(factoryType); + } + + public static XTypeName lazyOf(XTypeName typeName) { + return LAZY.parametrizedBy(typeName); + } + + public static XTypeName listOf(XTypeName typeName) { + return LIST.parametrizedBy(typeName); + } + + public static XTypeName listenableFutureOf(XTypeName typeName) { + return LISTENABLE_FUTURE.parametrizedBy(typeName); + } + + public static XTypeName membersInjectorOf(XTypeName membersInjectorType) { + return MEMBERS_INJECTOR.parametrizedBy(membersInjectorType); + } + + public static XTypeName producedOf(XTypeName typeName) { + return PRODUCED.parametrizedBy(typeName); + } + + public static XTypeName producerOf(XTypeName typeName) { + return PRODUCER.parametrizedBy(typeName); + } + + public static XTypeName dependencyMethodProducerOf(XTypeName typeName) { + return DEPENDENCY_METHOD_PRODUCER.parametrizedBy(typeName); + } + + public static XTypeName providerOf(XTypeName typeName) { + return PROVIDER.parametrizedBy(typeName); + } + + public static XTypeName daggerProviderOf(XTypeName typeName) { + return DAGGER_PROVIDER.parametrizedBy(typeName); + } + + public static XTypeName setOf(XTypeName elementType) { + return SET.parametrizedBy(elementType); + } + + private static final ImmutableSet<XClassName> FUTURE_TYPES = + ImmutableSet.of(LISTENABLE_FUTURE, FLUENT_FUTURE); + + public static boolean isFutureType(XType type) { + return isFutureType(type.asTypeName()); + } + + public static boolean isFutureType(XTypeName typeName) { + return FUTURE_TYPES.contains(typeName.getRawTypeName()); + } + + public static String simpleName(XClassName className) { + return getLast(className.getSimpleNames()); + } + + private XTypeNames() {} +}
diff --git a/java/dagger/internal/codegen/xprocessing/XTypes.java b/java/dagger/internal/codegen/xprocessing/XTypes.java index 7f4b77a..62d9dba 100644 --- a/java/dagger/internal/codegen/xprocessing/XTypes.java +++ b/java/dagger/internal/codegen/xprocessing/XTypes.java
@@ -250,7 +250,11 @@ case JAVAC: return isDeclared(type) && type.getTypeArguments().isEmpty() - && !type.getTypeElement().getType().getTypeArguments().isEmpty(); + // TODO(b/353979671): We previously called: + // type.getTypeElement().getType().getTypeArguments().isEmpty() + // which is a bit more symmetric to the call above, but that resulted in b/353979671, so + // we've switched to checking `XTypeElement#getTypeParameters()` until the bug is fixed. + && !type.getTypeElement().getTypeParameters().isEmpty(); case KSP: return isDeclared(type) // TODO(b/245619245): Due to the bug in XProcessing, the logic used for Javac won't work
diff --git a/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar b/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar index 4d0d7fd..f7f0203 100644 --- a/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar +++ b/java/dagger/internal/codegen/xprocessing/xprocessing-testing.jar Binary files differ
diff --git a/java/dagger/internal/codegen/xprocessing/xprocessing.jar b/java/dagger/internal/codegen/xprocessing/xprocessing.jar index 24590f8..31833cc 100644 --- a/java/dagger/internal/codegen/xprocessing/xprocessing.jar +++ b/java/dagger/internal/codegen/xprocessing/xprocessing.jar Binary files differ
diff --git a/java/dagger/internal/package-info.java b/java/dagger/internal/package-info.java new file mode 100644 index 0000000..2d83541 --- /dev/null +++ b/java/dagger/internal/package-info.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. + */ + +@NullMarked +package dagger.internal; + +import org.jspecify.annotations.NullMarked;
diff --git a/java/dagger/lint/BUILD b/java/dagger/lint/BUILD index 173d035..1e11aa2 100644 --- a/java/dagger/lint/BUILD +++ b/java/dagger/lint/BUILD
@@ -15,9 +15,9 @@ # Description: # Dagger Lint Rules +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") load("//:build_defs.bzl", "POM_VERSION") -load("//tools:maven.bzl", "gen_maven_artifact") -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"])
diff --git a/java/dagger/producers/BUILD b/java/dagger/producers/BUILD index 0dfd4d9..5bc7a5b 100644 --- a/java/dagger/producers/BUILD +++ b/java/dagger/producers/BUILD
@@ -23,7 +23,7 @@ "JAVA_RELEASE_MIN", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"])
diff --git a/java/dagger/producers/internal/LazyMapOfProducedProducer.java b/java/dagger/producers/internal/LazyMapOfProducedProducer.java new file mode 100644 index 0000000..edc3ddb --- /dev/null +++ b/java/dagger/producers/internal/LazyMapOfProducedProducer.java
@@ -0,0 +1,56 @@ +/* + * 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.producers.internal; + +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.LazyClassKeyMap; +import dagger.producers.Produced; +import java.util.Map; + +/** + * Wrapper around {@link MapOfProducedProducer} to be compatible with @LazyClassKey annotated map. + */ +public final class LazyMapOfProducedProducer<V> + extends AbstractProducer<Map<Class<?>, Produced<V>>> { + AbstractProducer<Map<String, Produced<V>>> delegate; + + public static <V> LazyMapOfProducedProducer<V> of( + AbstractProducer<Map<String, Produced<V>>> delegate) { + return new LazyMapOfProducedProducer<V>(delegate); + } + + private LazyMapOfProducedProducer(AbstractProducer<Map<String, Produced<V>>> delegate) { + this.delegate = delegate; + } + + @Override + public ListenableFuture<Map<Class<?>, Produced<V>>> compute() { + return Futures.transform( + delegate.compute(), + new Function<Map<String, Produced<V>>, Map<Class<?>, Produced<V>>>() { + @Override + public Map<Class<?>, Produced<V>> apply(Map<String, Produced<V>> classMap) { + return LazyClassKeyMap.of(classMap); + } + }, + directExecutor()); + } +}
diff --git a/java/dagger/producers/internal/LazyMapOfProducerProducer.java b/java/dagger/producers/internal/LazyMapOfProducerProducer.java new file mode 100644 index 0000000..b792557 --- /dev/null +++ b/java/dagger/producers/internal/LazyMapOfProducerProducer.java
@@ -0,0 +1,56 @@ +/* + * 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.producers.internal; + +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.LazyClassKeyMap; +import dagger.producers.Producer; +import java.util.Map; + +/** + * Wrapper around {@link MapOfProducerProducer} to be compatible with @LazyClassKey annotated map. + */ +public final class LazyMapOfProducerProducer<V> + extends AbstractProducer<Map<Class<?>, Producer<V>>> { + AbstractProducer<Map<String, Producer<V>>> delegate; + + public static <V> LazyMapOfProducerProducer<V> of( + AbstractProducer<Map<String, Producer<V>>> delegate) { + return new LazyMapOfProducerProducer<V>(delegate); + } + + private LazyMapOfProducerProducer(AbstractProducer<Map<String, Producer<V>>> delegate) { + this.delegate = delegate; + } + + @Override + public ListenableFuture<Map<Class<?>, Producer<V>>> compute() { + return Futures.transform( + delegate.compute(), + new Function<Map<String, Producer<V>>, Map<Class<?>, Producer<V>>>() { + @Override + public Map<Class<?>, Producer<V>> apply(Map<String, Producer<V>> classMap) { + return LazyClassKeyMap.of((Map<String, Producer<V>>) classMap); + } + }, + directExecutor()); + } +}
diff --git a/java/dagger/producers/internal/LazyMapProducer.java b/java/dagger/producers/internal/LazyMapProducer.java new file mode 100644 index 0000000..a09795c --- /dev/null +++ b/java/dagger/producers/internal/LazyMapProducer.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.producers.internal; + +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; + +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import dagger.internal.LazyClassKeyMap; +import java.util.Map; + +/** Wrapper around {@link MapProducer} to be compatible with @LazyClassKey annotated map. */ +public final class LazyMapProducer<V> extends AbstractProducer<Map<Class<?>, V>> { + AbstractProducer<Map<String, V>> delegate; + + public static <V> LazyMapProducer<V> of(AbstractProducer<Map<String, V>> delegate) { + return new LazyMapProducer<V>(delegate); + } + + private LazyMapProducer(AbstractProducer<Map<String, V>> delegate) { + this.delegate = delegate; + } + + @Override + public ListenableFuture<Map<Class<?>, V>> compute() { + return Futures.transform( + delegate.compute(), + new Function<Map<String, V>, Map<Class<?>, V>>() { + @Override + public Map<Class<?>, V> apply(Map<String, V> classMap) { + return LazyClassKeyMap.of((Map<String, V>) classMap); + } + }, + directExecutor()); + } +}
diff --git a/java/dagger/proguard.pro b/java/dagger/proguard.pro index 1bfc947..150194d 100644 --- a/java/dagger/proguard.pro +++ b/java/dagger/proguard.pro
@@ -1,3 +1,3 @@ --keepclasseswithmembers,includedescriptorclasses class * { +-keepclassmembers,includedescriptorclasses class * { @dagger.internal.KeepFieldType <fields>; } \ No newline at end of file
diff --git a/java/dagger/r8.pro b/java/dagger/r8.pro index 17e0ffe..6fde1b2 100644 --- a/java/dagger/r8.pro +++ b/java/dagger/r8.pro
@@ -1,3 +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 8084e63..9624019 100644 --- a/java/dagger/spi/BUILD +++ b/java/dagger/spi/BUILD
@@ -22,7 +22,7 @@ "DOCLINT_REFERENCES", "POM_VERSION", ) -load("//tools:maven.bzl", "gen_maven_artifact") +load("//tools/maven:maven.bzl", "gen_maven_artifact") package(default_visibility = ["//:src"]) @@ -80,7 +80,7 @@ # util/deploy-dagger.sh shaded_deps = [ "//third_party/java/auto:common", - "@maven//:org_jetbrains_kotlinx_kotlinx_metadata_jvm", + "//third_party/kotlin/kotlin_metadata_jvm", "//java/dagger/internal/codegen/xprocessing:xprocessing-jar", ], )
diff --git a/java/dagger/spi/model/BUILD b/java/dagger/spi/model/BUILD index e5af4e5..9567c82 100644 --- a/java/dagger/spi/model/BUILD +++ b/java/dagger/spi/model/BUILD
@@ -15,7 +15,7 @@ # Description: # Dagger's core APIs exposed for plugins -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package(default_visibility = [ # The dagger/spi should be the only direct dependent on this target. @@ -36,7 +36,7 @@ kt_jvm_library( name = "model", srcs = [":model-srcs"], - # TODO(wanyingd): Add javacopts explicitly once kt_jvm_library supports them. + # TODO(bcorso): Add javacopts explicitly once kt_jvm_library supports them. deps = [ "//java/dagger:core", "//java/dagger/internal/codegen/extension",
diff --git a/java/dagger/spi/model/BindingGraphPlugin.java b/java/dagger/spi/model/BindingGraphPlugin.java index 8edb702..007cd5a 100644 --- a/java/dagger/spi/model/BindingGraphPlugin.java +++ b/java/dagger/spi/model/BindingGraphPlugin.java
@@ -60,6 +60,14 @@ } /** + * Runs before each round of Dagger annotation processing. + * + * <p>If using the plugin to process elements that need resetting at the beginning of each + * processing round, use this function to perform the setup. + */ + default void onProcessingRoundBegin() {} + + /** * Perform any extra work after the plugin finished all its visiting. This will be called once per * instance of this plugin, after all graphs were {@linkplain #visitGraph(BindingGraph, * DiagnosticReporter) visited}
diff --git a/java/dagger/spi/model/DaggerExecutableElement.java b/java/dagger/spi/model/DaggerExecutableElement.java index afbd8e0..c585505 100644 --- a/java/dagger/spi/model/DaggerExecutableElement.java +++ b/java/dagger/spi/model/DaggerExecutableElement.java
@@ -16,7 +16,7 @@ package dagger.spi.model; -import com.google.devtools.ksp.symbol.KSFunctionDeclaration; +import com.google.devtools.ksp.symbol.KSDeclaration; import com.google.errorprone.annotations.DoNotMock; import javax.lang.model.element.ExecutableElement; @@ -31,11 +31,12 @@ public abstract ExecutableElement javac(); /** - * Returns the KSP representation for the executable element. + * Returns the KSP representation for the executable element. Can be either KSFunctionDeclaration + * or KSPropertyDeclaration. * * @throws IllegalStateException if the current backend isn't KSP. */ - public abstract KSFunctionDeclaration ksp(); + public abstract KSDeclaration ksp(); /** Returns the backend used in this compilation. */ public abstract DaggerProcessingEnv.Backend backend();
diff --git a/java/dagger/testing/compile/CompilerTests.java b/java/dagger/testing/compile/CompilerTests.java index ac74a61..39d22cb 100644 --- a/java/dagger/testing/compile/CompilerTests.java +++ b/java/dagger/testing/compile/CompilerTests.java
@@ -68,6 +68,14 @@ ImmutableMap.of( "dagger.experimentalDaggerErrorMessages", "enabled"); + private static final ImmutableList<String> DEFAULT_JAVAC_OPTIONS = ImmutableList.of(); + + private static final ImmutableList<String> DEFAULT_KOTLINC_OPTIONS = + ImmutableList.of( + "-api-version=1.9", + "-language-version=1.9", + "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"); + /** Returns the {@link XProcessingEnv.Backend} for the given {@link CompilationResultSubject}. */ public static XProcessingEnv.Backend backend(CompilationResultSubject subject) { // TODO(bcorso): Create a more official API for this in XProcessing testing. @@ -136,8 +144,8 @@ sources(), /* classpath= */ ImmutableList.of(), processorOptions(), - /* javacArguments= */ ImmutableList.of(), - /* kotlincArguments= */ ImmutableList.of(), + /* javacArguments= */ DEFAULT_JAVAC_OPTIONS, + /* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS, /* config= */ PROCESSING_ENV_CONFIG, invocation -> { onInvocation.accept(invocation); @@ -228,9 +236,8 @@ sources().asList(), /* classpath= */ ImmutableList.of(), processorOptions(), - /* javacArguments= */ ImmutableList.of(), - /* kotlincArguments= */ ImmutableList.of( - "-P", "plugin:org.jetbrains.kotlin.kapt3:correctErrorTypes=true"), + /* javacArguments= */ DEFAULT_JAVAC_OPTIONS, + /* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS, /* config= */ PROCESSING_ENV_CONFIG, /* javacProcessors= */ mergeProcessors( ImmutableList.of( @@ -306,17 +313,18 @@ Map<String, String> processorOptions, TemporaryFolder tempFolder, Consumer<TestCompilationResult> onCompilationResult) { - TestCompilationResult result = TestKotlinCompilerKt.compile( - tempFolder.getRoot(), - new TestCompilationArguments( - sources, - /*classpath=*/ ImmutableList.of(compilerDepsJar()), - /*inheritClasspath=*/ false, - /*javacArguments=*/ ImmutableList.of(), - /*kotlincArguments=*/ ImmutableList.of(), - /*kaptProcessors=*/ ImmutableList.of(new ComponentProcessor()), - /*symbolProcessorProviders=*/ ImmutableList.of(), - /*processorOptions=*/ processorOptions)); + TestCompilationResult result = + TestKotlinCompilerKt.compile( + tempFolder.getRoot(), + new TestCompilationArguments( + sources, + /* classpath= */ ImmutableList.of(compilerDepsJar()), + /* inheritClasspath= */ false, + /* javacArguments= */ DEFAULT_JAVAC_OPTIONS, + /* kotlincArguments= */ DEFAULT_KOTLINC_OPTIONS, + /* kaptProcessors= */ ImmutableList.of(new ComponentProcessor()), + /* symbolProcessorProviders= */ ImmutableList.of(), + /* processorOptions= */ processorOptions)); onCompilationResult.accept(result); }
diff --git a/java/dagger/testing/compile/macros.bzl b/java/dagger/testing/compile/macros.bzl index 9543e0e..3338e8a 100644 --- a/java/dagger/testing/compile/macros.bzl +++ b/java/dagger/testing/compile/macros.bzl
@@ -11,10 +11,10 @@ # 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. - """Macros for building compiler tests.""" -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_binary", "java_test") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") def compiler_test(name, size = "large", compiler_deps = None, **kwargs): """Generates a java_test that tests java compilation with the given compiler deps. @@ -35,7 +35,7 @@ # This JAR is loaded at runtime and contains the dependencies used by the compiler during tests. # We separate these dependencies from the java_test dependencies to avoid 1 version violations. - native.java_binary( + java_binary( name = name + "_compiler_deps", testonly = 1, tags = ["notap"], @@ -54,8 +54,7 @@ if kwargs.get("srcs", None): # Add a dep to allow usage of CompilerTests. kwargs["deps"] = kwargs.get("deps", []) + ["//java/dagger/testing/compile"] - - native.java_test(name = name, size = size, **kwargs) + java_test(name = name, size = size, **kwargs) def kt_compiler_test(name, srcs = [], deps = [], **kwargs): """Generates a java_test that tests java compilation with the given compiler deps.
diff --git a/javatests/artifacts/dagger-android-ksp/app/build.gradle b/javatests/artifacts/dagger-android-ksp/app/build.gradle index 434590a..b7634e4 100644 --- a/javatests/artifacts/dagger-android-ksp/app/build.gradle +++ b/javatests/artifacts/dagger-android-ksp/app/build.gradle
@@ -30,7 +30,7 @@ versionCode 1 versionName "1.0" } - + namespace "dagger.android.ksp" compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 @@ -49,6 +49,10 @@ } } +kotlin { + jvmToolchain(17) +} + dependencies { implementation 'androidx.appcompat:appcompat:1.2.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
diff --git a/javatests/artifacts/dagger-android-ksp/build.gradle b/javatests/artifacts/dagger-android-ksp/build.gradle index 2aa0605..f675791 100644 --- a/javatests/artifacts/dagger-android-ksp/build.gradle +++ b/javatests/artifacts/dagger-android-ksp/build.gradle
@@ -16,9 +16,9 @@ buildscript { ext { - agp_version = "8.1.0" - kotlin_version = "1.9.20" - ksp_version = "$kotlin_version-1.0.14" + agp_version = "8.1.1" + kotlin_version = "2.0.21" + ksp_version = "$kotlin_version-1.0.28" } repositories { google()
diff --git a/javatests/artifacts/dagger-android/simple/app/build.gradle b/javatests/artifacts/dagger-android/simple/app/build.gradle index 881a304..1f1ceac 100644 --- a/javatests/artifacts/dagger-android/simple/app/build.gradle +++ b/javatests/artifacts/dagger-android/simple/app/build.gradle
@@ -27,6 +27,7 @@ versionCode 1 versionName "1.0" } + namespace "dagger.android.simple" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -53,18 +54,18 @@ annotationProcessor 'com.google.dagger:dagger-android-processor:LOCAL-SNAPSHOT' testImplementation 'com.google.truth:truth:1.0.1' - testImplementation 'org.robolectric:robolectric:4.5-alpha-3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'androidx.core:core:1.3.2' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'androidx.test:runner:1.4.0' - testImplementation 'androidx.test.espresso:espresso-core:3.4.0' + testImplementation 'androidx.test.espresso:espresso-core:3.5.1' testImplementation 'com.google.dagger:dagger-compiler:LOCAL-SNAPSHOT' testAnnotationProcessor 'com.google.dagger:dagger-android-processor:LOCAL-SNAPSHOT' androidTestImplementation 'com.google.truth:truth:1.0.1' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test:runner:1.4.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation 'com.google.dagger:dagger-compiler:LOCAL-SNAPSHOT' androidTestAnnotationProcessor 'com.google.dagger:dagger-android-processor:LOCAL-SNAPSHOT'
diff --git a/javatests/artifacts/dagger-android/simple/build.gradle b/javatests/artifacts/dagger-android/simple/build.gradle index 54088d3..29d8b96 100644 --- a/javatests/artifacts/dagger-android/simple/build.gradle +++ b/javatests/artifacts/dagger-android/simple/build.gradle
@@ -16,7 +16,7 @@ buildscript { ext { - agp_version = System.getenv('AGP_VERSION') ?: "7.1.2" + agp_version = System.getenv('AGP_VERSION') ?: "8.1.1" } repositories { google()
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 98debb8..e1bef7e 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.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.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 35aea20..63b0341 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.9.20" - ksp_version = "$kotlin_version-1.0.14" + kotlin_version = "2.0.21" + ksp_version = "$kotlin_version-1.0.28" junit_version = "4.13" truth_version = "1.0.1" }
diff --git a/javatests/artifacts/dagger/build.gradle b/javatests/artifacts/dagger/build.gradle index 499b1ee..6c72ef0 100644 --- a/javatests/artifacts/dagger/build.gradle +++ b/javatests/artifacts/dagger/build.gradle
@@ -17,8 +17,8 @@ buildscript { ext { dagger_version = "LOCAL-SNAPSHOT" - kotlin_version = "1.9.20" - ksp_version = "$kotlin_version-1.0.14" + kotlin_version = "2.0.21" + ksp_version = "$kotlin_version-1.0.28" junit_version = "4.13" truth_version = "1.0.1" }
diff --git a/javatests/artifacts/dagger/java-app/build.gradle b/javatests/artifacts/dagger/java-app/build.gradle index 16c6e66..b167746 100644 --- a/javatests/artifacts/dagger/java-app/build.gradle +++ b/javatests/artifacts/dagger/java-app/build.gradle
@@ -20,8 +20,8 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 } dependencies {
diff --git a/javatests/artifacts/dagger/lazyclasskey/app/build.gradle b/javatests/artifacts/dagger/lazyclasskey/app/build.gradle index b44309a..19fef9c 100644 --- a/javatests/artifacts/dagger/lazyclasskey/app/build.gradle +++ b/javatests/artifacts/dagger/lazyclasskey/app/build.gradle
@@ -30,7 +30,7 @@ versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } - + namespace "dagger.lazyclasskey" buildTypes { debug { minifyEnabled true @@ -56,7 +56,7 @@ 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' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' // Dagger dependencies implementation "com.google.dagger:dagger:$dagger_version"
diff --git a/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro b/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro index 9598002..49d9a65 100644 --- a/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro +++ b/javatests/artifacts/dagger/lazyclasskey/app/proguard-rules.pro
@@ -1,5 +1,9 @@ -dontwarn com.google.errorprone.annotations.MustBeClosed +# These are rules to enable instrumentation test to run while main app is optimized # TODO(b/324097623) Remove the keep rules once test won't be affected by obfuscation -keep class kotlin.** -keep class javax.** { *; } +-keep class com.google.common.util.concurrent.ListenableFuture { + <methods>; +}
diff --git a/javatests/artifacts/dagger/lazyclasskey/build.gradle b/javatests/artifacts/dagger/lazyclasskey/build.gradle index a0d4252..16982d4 100644 --- a/javatests/artifacts/dagger/lazyclasskey/build.gradle +++ b/javatests/artifacts/dagger/lazyclasskey/build.gradle
@@ -17,9 +17,8 @@ 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' + agp_version = "8.1.1" + kotlin_version = '2.0.21' } repositories { google()
diff --git a/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties index 9623276..707e21e 100644 --- a/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/dagger/lazyclasskey/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME
diff --git a/javatests/artifacts/dagger/transitive-annotation-app/build.gradle b/javatests/artifacts/dagger/transitive-annotation-app/build.gradle index 22933a4..0b0cec9 100644 --- a/javatests/artifacts/dagger/transitive-annotation-app/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-app/build.gradle
@@ -20,8 +20,8 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 } dependencies {
diff --git a/javatests/artifacts/dagger/transitive-annotation-app/library1/build.gradle b/javatests/artifacts/dagger/transitive-annotation-app/library1/build.gradle index 2126f09..60259e5 100644 --- a/javatests/artifacts/dagger/transitive-annotation-app/library1/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-app/library1/build.gradle
@@ -20,8 +20,8 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 } dependencies {
diff --git a/javatests/artifacts/dagger/transitive-annotation-app/library2/build.gradle b/javatests/artifacts/dagger/transitive-annotation-app/library2/build.gradle index b4d45e4..c0a95b9 100644 --- a/javatests/artifacts/dagger/transitive-annotation-app/library2/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-app/library2/build.gradle
@@ -20,6 +20,6 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 }
diff --git a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/build.gradle b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/build.gradle index 1b0c04d..88519e9 100644 --- a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/build.gradle
@@ -21,8 +21,8 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 } kapt {
diff --git a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library1/build.gradle b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library1/build.gradle index 3875913..17c63b3 100644 --- a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library1/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library1/build.gradle
@@ -21,8 +21,8 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 } kapt {
diff --git a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library2/build.gradle b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library2/build.gradle index 9b4c087..e65b5bd 100644 --- a/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library2/build.gradle +++ b/javatests/artifacts/dagger/transitive-annotation-kotlin-app/library2/build.gradle
@@ -25,6 +25,6 @@ } java { - // Make sure the generated source is compatible with Java 7. - sourceCompatibility = JavaVersion.VERSION_1_7 + // Make sure the generated source is compatible with Java 8. + sourceCompatibility = JavaVersion.VERSION_1_8 }
diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle b/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle index 0f854cb..45c1aa9 100644 --- a/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/build.gradle
@@ -31,7 +31,7 @@ versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } - + namespace "hilt.lazyclasskey" buildTypes { debug { minifyEnabled true @@ -57,7 +57,7 @@ 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' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' // Hilt dependencies implementation "com.google.dagger:hilt-android:$hilt_version"
diff --git a/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro b/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro index d389c43..cd04bbb 100644 --- a/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro +++ b/javatests/artifacts/hilt-android/lazyclasskey/app/proguard-rules.pro
@@ -1,3 +1,7 @@ -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 +# These are rules to enable instrumentation test to run while main app is optimized +# TODO(b/324097623) Remove the keep rules once test won't be affected by obfuscation +-keep class kotlin.** +-keep class com.google.common.util.concurrent.ListenableFuture { + <methods>; +} \ No newline at end of file
diff --git a/javatests/artifacts/hilt-android/lazyclasskey/build.gradle b/javatests/artifacts/hilt-android/lazyclasskey/build.gradle index 14bbfbd..53ced2c 100644 --- a/javatests/artifacts/hilt-android/lazyclasskey/build.gradle +++ b/javatests/artifacts/hilt-android/lazyclasskey/build.gradle
@@ -17,9 +17,8 @@ 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' + agp_version = "8.1.1" + kotlin_version = '2.0.21' } repositories { google()
diff --git a/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties index 9623276..707e21e 100644 --- a/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/hilt-android/lazyclasskey/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME
diff --git a/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle b/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle index e4cde41..632e68e 100644 --- a/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle +++ b/javatests/artifacts/hilt-android/pluginMarker/app/build.gradle
@@ -15,7 +15,7 @@ */ plugins { - id 'com.android.application' version '7.0.0' + id 'com.android.application' version '8.1.1' id 'com.google.dagger.hilt.android' version 'LOCAL-SNAPSHOT' } @@ -28,7 +28,7 @@ minSdkVersion 16 targetSdkVersion 33 } - + namespace "dagger.hilt.android.simple" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 98debb8..e1bef7e 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.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.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 7a156ef..deedbef 100644 --- a/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle +++ b/javatests/artifacts/hilt-android/simple/app-java-only/build.gradle
@@ -19,7 +19,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { applicationId "dagger.hilt.android.simple" @@ -27,8 +27,8 @@ targetSdkVersion 33 versionCode 1 versionName "1.0" - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + namespace "dagger.hilt.android.simple" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -61,9 +61,9 @@ testImplementation 'com.google.truth:truth:1.0.1' testImplementation 'junit:junit:4.13' - testImplementation 'org.robolectric:robolectric:4.5-alpha-3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'androidx.core:core:1.3.2' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'androidx.test:runner:1.4.0' - testImplementation 'androidx.test.espresso:espresso-core:3.4.0' + testImplementation 'androidx.test.espresso:espresso-core:3.5.1' }
diff --git a/javatests/artifacts/hilt-android/simple/app/build.gradle b/javatests/artifacts/hilt-android/simple/app/build.gradle index 8a196cf..c0fde10 100644 --- a/javatests/artifacts/hilt-android/simple/app/build.gradle +++ b/javatests/artifacts/hilt-android/simple/app/build.gradle
@@ -44,7 +44,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { applicationId "dagger.hilt.android.simple" @@ -54,6 +54,7 @@ versionName "1.0" testInstrumentationRunner "dagger.hilt.android.simple.SimpleEmulatorTestRunner" } + namespace "dagger.hilt.android.simple" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -108,11 +109,11 @@ testImplementation 'com.google.truth:truth:1.0.1' testImplementation 'junit:junit:4.13' - testImplementation 'org.robolectric:robolectric:4.5-alpha-3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'androidx.core:core:1.3.2' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'androidx.test:runner:1.4.0' - testImplementation 'androidx.test.espresso:espresso-core:3.4.0' + testImplementation 'androidx.test.espresso:espresso-core:3.5.1' testImplementation "com.google.dagger:hilt-android-testing:$dagger_version" testAnnotationProcessor "com.google.dagger:hilt-compiler:$dagger_version" @@ -120,7 +121,7 @@ androidTestImplementation 'junit:junit:4.13' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test:runner:1.4.0' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "com.google.dagger:hilt-android-testing:$dagger_version" androidTestAnnotationProcessor "com.google.dagger:hilt-compiler:$dagger_version"
diff --git a/javatests/artifacts/hilt-android/simple/app/src/androidTest-agp-4.2.0/java/dagger/hilt/android/simple/BroadcastReceiverTest.java b/javatests/artifacts/hilt-android/simple/app/src/androidTest-agp-4.2.0/java/dagger/hilt/android/simple/BroadcastReceiverTest.java deleted file mode 100644 index 265869a..0000000 --- a/javatests/artifacts/hilt-android/simple/app/src/androidTest-agp-4.2.0/java/dagger/hilt/android/simple/BroadcastReceiverTest.java +++ /dev/null
@@ -1,202 +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.simple; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.platform.app.InstrumentationRegistry; -import dagger.hilt.android.AndroidEntryPoint; -import dagger.hilt.android.testing.BindValue; -import dagger.hilt.android.testing.HiltAndroidRule; -import dagger.hilt.android.testing.HiltAndroidTest; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import javax.inject.Inject; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -/** A injection test of Broadcast receivers */ -@HiltAndroidTest -@RunWith(AndroidJUnit4.class) -public class BroadcastReceiverTest { - - @Rule public HiltAndroidRule rule = new HiltAndroidRule(this); - - @BindValue final String valueToInject = "test value"; - - @Test - public void verifyReceiverInjectedValue() throws InterruptedException { - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - TestReceiverOne receiver = new TestReceiverOne(); - IntentFilter intentFilter = new IntentFilter("test-action"); - context.registerReceiver(receiver, intentFilter); - - Intent intent = new Intent(); - intent.setAction("test-action"); - context.sendBroadcast(intent); - - receiver.latch.await(2, TimeUnit.SECONDS); - assertThat(receiver.injectedValue).isNotEmpty(); - } - - @Test - public void verifyBaseReceiverInjectedValue() throws InterruptedException { - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - TestReceiverTwo receiver = new TestReceiverTwo(); - IntentFilter intentFilter = new IntentFilter("test-action"); - context.registerReceiver(receiver, intentFilter); - - Intent intent = new Intent(); - intent.setAction("test-action"); - context.sendBroadcast(intent); - - receiver.latch.await(2, TimeUnit.SECONDS); - assertThat(receiver.injectedValue).isNotEmpty(); - } - - @Test - public void verifyBaseReceiverIsNotDoubleInjected() throws InterruptedException { - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - TestReceiverThree receiver = new TestReceiverThree(); - IntentFilter intentFilter = new IntentFilter("test-action"); - context.registerReceiver(receiver, intentFilter); - - Intent intent = new Intent(); - intent.setAction("test-action"); - context.sendBroadcast(intent); - - receiver.latch.await(2, TimeUnit.SECONDS); - assertThat(receiver.injectedValue).isNotEmpty(); - assertThat(receiver.onReceiveCalled).isEqualTo(1); - } - - @Test - public void verifyComplexReceiverInjectedValue() throws InterruptedException { - Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - TestReceiverFour receiver = new TestReceiverFour(); - IntentFilter intentFilter = new IntentFilter("test-action"); - context.registerReceiver(receiver, intentFilter); - - Intent intent = new Intent(); - intent.setAction("test-action"); - context.sendBroadcast(intent); - - receiver.latch.await(2, TimeUnit.SECONDS); - assertThat(receiver.injectedValue).isNotEmpty(); - } - - /** Test receiver */ - @AndroidEntryPoint - public static class TestReceiverOne extends BroadcastReceiver { - - final CountDownLatch latch = new CountDownLatch(1); - - @Inject - String injectedValue; - - @Override - public void onReceive(Context context, Intent intent) { - latch.countDown(); - } - } - - /** Test receiver */ - @AndroidEntryPoint - public static class TestReceiverTwo extends BaseReceiverAbstractMethod { - - final CountDownLatch latch = new CountDownLatch(1); - - @Inject - String injectedValue; - - @Override - public void onReceive(Context context, Intent intent) { - latch.countDown(); - } - } - - /** Test receiver */ - @AndroidEntryPoint - public static class TestReceiverThree extends BaseReceiverConcreteMethod { - - final CountDownLatch latch = new CountDownLatch(1); - - @Inject - String injectedValue; - - @Override - public void onReceive(Context context, Intent intent) { - super.onReceive(context, intent); - latch.countDown(); - } - } - - /** Complex-ish test receiver */ - @AndroidEntryPoint - public static class TestReceiverFour extends BroadcastReceiver { - - final CountDownLatch latch = new CountDownLatch(1); - - @Inject String injectedValue; - - @Override - public void onReceive(Context context, Intent intent) { - // Weird code, but it tests that the exception table and stack table frames are correctly - // updated in a transformation. - boolean var0; - if (context != null) { - var0 = false; - Object var1 = context.getClass(); - try { - throw new IllegalStateException(); - } catch (IllegalStateException ex) { - var0 = true; - } - } else { - BroadcastReceiver myself = this; - var0 = false; - } - latch.countDown(); - } - } - - /** Base test receiver */ - abstract static class BaseReceiverAbstractMethod extends BroadcastReceiver { - - } - - /** Base test receiver */ - abstract static class BaseReceiverConcreteMethod extends BroadcastReceiver { - - int onReceiveCalled = 0; - - @Override - public void onReceive(Context context, Intent intent) { - onReceiveCalled++; - } - } -}
diff --git a/javatests/artifacts/hilt-android/simple/app/src/main/AndroidManifest.xml b/javatests/artifacts/hilt-android/simple/app/src/main/AndroidManifest.xml index 0b12b13..e77499f 100644 --- a/javatests/artifacts/hilt-android/simple/app/src/main/AndroidManifest.xml +++ b/javatests/artifacts/hilt-android/simple/app/src/main/AndroidManifest.xml
@@ -14,6 +14,7 @@ ~ limitations under the License. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" package="dagger.hilt.android.simple"> <application android:name=".SimpleApplication" android:label="@string/appName"> @@ -31,5 +32,11 @@ android:theme="@style/Theme.AppCompat.Light" android:exported="false"> </activity> + <!-- WM is brought due to andridx.hilt:hilt-work but we don't need it, disable it. --> + <provider + android:name="androidx.work.impl.WorkManagerInitializer" + android:authorities="${applicationId}.workmanager-init" + tools:node="remove"> + </provider> </application> </manifest>
diff --git a/javatests/artifacts/hilt-android/simple/build.gradle b/javatests/artifacts/hilt-android/simple/build.gradle index e0f39a3..3dfb1b9 100644 --- a/javatests/artifacts/hilt-android/simple/build.gradle +++ b/javatests/artifacts/hilt-android/simple/build.gradle
@@ -17,8 +17,8 @@ buildscript { ext { dagger_version = 'LOCAL-SNAPSHOT' - kotlin_version = '1.9.20' - agp_version = System.getenv('AGP_VERSION') ?: "7.1.2" + kotlin_version = '2.0.21' + agp_version = System.getenv('AGP_VERSION') ?: "8.1.1" } repositories { google()
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 ab5424e..ada7b6a 100644 --- a/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle +++ b/javatests/artifacts/hilt-android/simple/deep-android-lib/build.gradle
@@ -5,7 +5,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -13,7 +13,7 @@ versionCode 1 versionName "1.0" } - + namespace "dagger.hilt.android.simple.deep" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
diff --git a/javatests/artifacts/hilt-android/simple/deep-lib/build.gradle b/javatests/artifacts/hilt-android/simple/deep-lib/build.gradle index 22f815c..3f8223c 100644 --- a/javatests/artifacts/hilt-android/simple/deep-lib/build.gradle +++ b/javatests/artifacts/hilt-android/simple/deep-lib/build.gradle
@@ -3,8 +3,8 @@ } java { - sourceCompatibility = JavaVersion.VERSION_1_7 - targetCompatibility = JavaVersion.VERSION_1_7 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } dependencies {
diff --git a/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle b/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle index 2a36e6f..615cd86 100644 --- a/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle +++ b/javatests/artifacts/hilt-android/simple/earlyentrypoint/build.gradle
@@ -5,7 +5,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -13,6 +13,7 @@ versionCode 1 versionName "1.0" } + namespace "dagger.hilt.android.simple.earlyentrypoint" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -59,7 +60,7 @@ testImplementation 'com.google.truth:truth:1.0.1' testImplementation 'junit:junit:4.13' - testImplementation 'org.robolectric:robolectric:4.5-alpha-3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'androidx.core:core:1.3.2' testImplementation 'androidx.test.ext:junit:1.1.3' testImplementation 'androidx.test:runner:1.4.0'
diff --git a/javatests/artifacts/hilt-android/simple/feature/build.gradle b/javatests/artifacts/hilt-android/simple/feature/build.gradle index dd33e29..e3fbea2 100644 --- a/javatests/artifacts/hilt-android/simple/feature/build.gradle +++ b/javatests/artifacts/hilt-android/simple/feature/build.gradle
@@ -21,7 +21,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -29,6 +29,7 @@ versionCode 1 versionName "1.0" } + namespace "dagger.hilt.android.simple.feature" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11 @@ -44,6 +45,10 @@ } } +kotlin { + jvmToolchain(11) +} + kapt { correctErrorTypes true }
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 98debb8..e1bef7e 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.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.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 7c4e0fd..2b10c39 100644 --- a/javatests/artifacts/hilt-android/simple/uitest/build.gradle +++ b/javatests/artifacts/hilt-android/simple/uitest/build.gradle
@@ -19,7 +19,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -27,6 +27,7 @@ testInstrumentationRunner "dagger.hilt.android.simple.uitest.TestRunner" missingDimensionStrategy 'tier', 'free' } + namespace "dagger.hilt.android.simple.uitest" targetProjectPath ':app' compileOptions { sourceCompatibility JavaVersion.VERSION_11
diff --git a/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle index 1e83543..18047e5 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/android-library/build.gradle
@@ -7,7 +7,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -15,6 +15,7 @@ versionCode 1 versionName "1.0" } + namespace "dagger.hilt.android.simpleKotlin.lib" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
diff --git a/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle index fe4f5b4..8495196 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/app/build.gradle
@@ -22,7 +22,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { applicationId "dagger.hilt.android.simpleKotlin" @@ -32,6 +32,7 @@ versionName "1.0" testInstrumentationRunner "dagger.hilt.android.example.gradle.simpleKotlin.TestRunner" } + namespace "dagger.hilt.android.simpleKotlin" buildTypes { release { minifyEnabled true @@ -99,7 +100,7 @@ testImplementation 'androidx.test:runner:1.4.0' testImplementation 'com.google.truth:truth:1.0.1' testImplementation 'junit:junit:4.13' - testImplementation 'org.robolectric:robolectric:4.5-alpha-3' + testImplementation 'org.robolectric:robolectric:4.11.1' testImplementation 'androidx.core:core:1.3.2' // TODO(bcorso): This multidex dep shouldn't be required -- it's a dep for the generated code. testImplementation 'androidx.multidex:multidex:2.0.0'
diff --git a/javatests/artifacts/hilt-android/simpleKotlin/build.gradle b/javatests/artifacts/hilt-android/simpleKotlin/build.gradle index 3773deb..b109613 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/build.gradle
@@ -16,9 +16,9 @@ buildscript { ext { - kotlin_version = '1.9.20' - ksp_version = "$kotlin_version-1.0.14" - agp_version = System.getenv('AGP_VERSION') ?: "7.1.2" + kotlin_version = '2.0.21' + ksp_version = "$kotlin_version-1.0.28" + agp_version = System.getenv('AGP_VERSION') ?: "8.1.1" } repositories { google()
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 8973bb9..c0ccb16 100644 --- a/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle +++ b/javatests/artifacts/hilt-android/simpleKotlin/deep-android-lib/build.gradle
@@ -8,7 +8,7 @@ android { compileSdkVersion 33 - buildToolsVersion "33.0.0" + buildToolsVersion "33.0.1" defaultConfig { minSdkVersion 16 @@ -18,6 +18,7 @@ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + namespace "dagger.hilt.android.simpleKotlin.deep" compileOptions { sourceCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
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 98debb8..e1bef7e 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.6.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.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 index a212b3c..d7e8ba8 100644 --- a/javatests/artifacts/hilt-android/viewmodel/app/build.gradle +++ b/javatests/artifacts/hilt-android/viewmodel/app/build.gradle
@@ -57,7 +57,7 @@ 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' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' // Hilt dependencies implementation "com.google.dagger:hilt-android:$hilt_version"
diff --git a/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro b/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro index 0929028..da9e79c 100644 --- a/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro +++ b/javatests/artifacts/hilt-android/viewmodel/app/proguard-rules.pro
@@ -1,2 +1,7 @@ -dontwarn com.google.errorprone.annotations.MustBeClosed +# These are rules to enable instrumentation test to run while main app is optimized + # TODO(b/324097623) Remove the keep rules once test won't be affected by obfuscation -keep class kotlin.** +-keep class com.google.common.util.concurrent.ListenableFuture { + <methods>; +} \ No newline at end of file
diff --git a/javatests/artifacts/hilt-android/viewmodel/build.gradle b/javatests/artifacts/hilt-android/viewmodel/build.gradle index bbcc108..cb70181 100644 --- a/javatests/artifacts/hilt-android/viewmodel/build.gradle +++ b/javatests/artifacts/hilt-android/viewmodel/build.gradle
@@ -17,9 +17,8 @@ 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' + agp_version = "8.1.1" + kotlin_version = '2.0.21' } repositories { google() @@ -29,7 +28,7 @@ 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" + classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version" } }
diff --git a/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties index 9623276..707e21e 100644 --- a/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties +++ b/javatests/artifacts/hilt-android/viewmodel/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME
diff --git a/javatests/dagger/android/AndroidInjectionTest.java b/javatests/dagger/android/AndroidInjectionTest.java index 499e981..5fa3951 100644 --- a/javatests/dagger/android/AndroidInjectionTest.java +++ b/javatests/dagger/android/AndroidInjectionTest.java
@@ -30,7 +30,6 @@ import org.robolectric.Robolectric; import org.robolectric.annotation.Config; import org.robolectric.annotation.LooperMode; -import org.robolectric.util.FragmentTestUtil; @LooperMode(LEGACY) @RunWith(AndroidJUnit4.class) @@ -133,7 +132,8 @@ @Test public void injectFragment_hasFragmentInjectorNotFound() { Fragment fragment = new Fragment(); - FragmentTestUtil.startFragment(fragment); + Activity activity = Robolectric.setupActivity(Activity.class); + activity.getFragmentManager().beginTransaction().add(fragment, null).commit(); try { AndroidInjection.inject(fragment); @@ -167,7 +167,8 @@ @Config(application = ApplicationReturnsNull.class) public void fragmentInjector_returnsNull() { Fragment fragment = new Fragment(); - FragmentTestUtil.startFragment(fragment); + Activity activity = Robolectric.setupActivity(Activity.class); + activity.getFragmentManager().beginTransaction().add(fragment, null).commit(); try { AndroidInjection.inject(fragment);
diff --git a/javatests/dagger/android/processor/BUILD b/javatests/dagger/android/processor/BUILD index 518234d..ddf930b 100644 --- a/javatests/dagger/android/processor/BUILD +++ b/javatests/dagger/android/processor/BUILD
@@ -36,7 +36,7 @@ "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_activity_activity", "@maven//:androidx_fragment_fragment", "@maven//:androidx_lifecycle_lifecycle_common",
diff --git a/javatests/dagger/functional/assisted/subpackage/BUILD b/javatests/dagger/functional/assisted/subpackage/BUILD index 8f06984..a07c163 100644 --- a/javatests/dagger/functional/assisted/subpackage/BUILD +++ b/javatests/dagger/functional/assisted/subpackage/BUILD
@@ -15,6 +15,8 @@ # Description: # Functional tests for Dagger +load("@rules_java//java:defs.bzl", "java_library") + package(default_visibility = ["//:src"]) java_library(
diff --git a/javatests/dagger/functional/basic/BasicTest.java b/javatests/dagger/functional/basic/BasicTest.java index a3e4419..a4e26e8 100644 --- a/javatests/dagger/functional/basic/BasicTest.java +++ b/javatests/dagger/functional/basic/BasicTest.java
@@ -61,23 +61,23 @@ } @Theory public void boxedPrimitives(BasicComponent basicComponent) { - assertThat(basicComponent.getBoxedByte()).isEqualTo(new Byte(BOUND_BYTE)); - assertThat(basicComponent.getBoxedChar()).isEqualTo(new Character(BOUND_CHAR)); - assertThat(basicComponent.getBoxedShort()).isEqualTo(new Short(BOUND_SHORT)); - assertThat(basicComponent.getBoxedInt()).isEqualTo(new Integer(BOUND_INT)); - assertThat(basicComponent.getBoxedLong()).isEqualTo(new Long(BOUND_LONG)); - assertThat(basicComponent.getBoxedBoolean()).isEqualTo(new Boolean(BOUND_BOOLEAN)); + assertThat(basicComponent.getBoxedByte()).isEqualTo(BOUND_BYTE); + assertThat(basicComponent.getBoxedChar()).isEqualTo(BOUND_CHAR); + assertThat(basicComponent.getBoxedShort()).isEqualTo(BOUND_SHORT); + assertThat(basicComponent.getBoxedInt()).isEqualTo(BOUND_INT); + assertThat(basicComponent.getBoxedLong()).isEqualTo(BOUND_LONG); + assertThat(basicComponent.getBoxedBoolean()).isEqualTo(BOUND_BOOLEAN); assertThat(basicComponent.getBoxedFloat()).isEqualTo(BOUND_FLOAT); assertThat(basicComponent.getBoxedDouble()).isEqualTo(BOUND_DOUBLE); } @Theory public void boxedPrimitiveProviders(BasicComponent basicComponent) { - assertThat(basicComponent.getByteProvider().get()).isEqualTo(new Byte(BOUND_BYTE)); - assertThat(basicComponent.getCharProvider().get()).isEqualTo(new Character(BOUND_CHAR)); - assertThat(basicComponent.getShortProvider().get()).isEqualTo(new Short(BOUND_SHORT)); - assertThat(basicComponent.getIntProvider().get()).isEqualTo(new Integer(BOUND_INT)); - assertThat(basicComponent.getLongProvider().get()).isEqualTo(new Long(BOUND_LONG)); - assertThat(basicComponent.getBooleanProvider().get()).isEqualTo(new Boolean(BOUND_BOOLEAN)); + assertThat(basicComponent.getByteProvider().get()).isEqualTo(BOUND_BYTE); + assertThat(basicComponent.getCharProvider().get()).isEqualTo(BOUND_CHAR); + assertThat(basicComponent.getShortProvider().get()).isEqualTo(BOUND_SHORT); + assertThat(basicComponent.getIntProvider().get()).isEqualTo(BOUND_INT); + assertThat(basicComponent.getLongProvider().get()).isEqualTo(BOUND_LONG); + assertThat(basicComponent.getBooleanProvider().get()).isEqualTo(BOUND_BOOLEAN); assertThat(basicComponent.getFloatProvider().get()).isEqualTo(BOUND_FLOAT); assertThat(basicComponent.getDoubleProvider().get()).isEqualTo(BOUND_DOUBLE); }
diff --git a/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java b/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java index 83505e9..2dd16f2 100644 --- a/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java +++ b/javatests/dagger/functional/factory/FactoryBindsInstanceTest.java
@@ -17,6 +17,7 @@ package dagger.functional.factory; import static com.google.common.truth.Truth.assertThat; +import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -60,7 +61,7 @@ } } - @Target({METHOD, PARAMETER}) + @Target({METHOD, PARAMETER, FIELD}) @Retention(RUNTIME) @interface Nullable {}
diff --git a/javatests/dagger/functional/jakarta/BUILD b/javatests/dagger/functional/jakarta/BUILD index 9feb5e2..8d98d86 100644 --- a/javatests/dagger/functional/jakarta/BUILD +++ b/javatests/dagger/functional/jakarta/BUILD
@@ -32,3 +32,16 @@ "@maven//:jakarta_inject_jakarta_inject_api", ], ) + +GenJavaTests( + name = "JakartaProviderTest", + srcs = ["JakartaProviderTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/guava/base", + "//third_party/java/junit", + "//third_party/java/truth", + "@maven//:jakarta_inject_jakarta_inject_api", + ], +)
diff --git a/javatests/dagger/functional/jakarta/JakartaProviderTest.java b/javatests/dagger/functional/jakarta/JakartaProviderTest.java new file mode 100644 index 0000000..0c22861 --- /dev/null +++ b/javatests/dagger/functional/jakarta/JakartaProviderTest.java
@@ -0,0 +1,228 @@ +/* + * 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.jakarta; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.base.Optional; +import dagger.Binds; +import dagger.BindsOptionalOf; +import dagger.Component; +import dagger.Lazy; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoMap; +import dagger.multibindings.StringKey; +import jakarta.inject.Inject; +import jakarta.inject.Provider; +import jakarta.inject.Qualifier; +import jakarta.inject.Scope; +import java.util.HashMap; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class JakartaProviderTest { + + @Scope + public @interface TestScope {} + + @Qualifier + public @interface TestQualifier {} + + @TestScope + @Component(modules = TestModule.class) + interface TestComponent { + Provider<Foo> getJakartaFoo(); + + javax.inject.Provider<Foo> getJavaxFoo(); + + Provider<Bar> getJakartaBar(); + + javax.inject.Provider<Bar> getJavaxBar(); + + @TestQualifier + Provider<Foo> getJakartaQualifiedFoo(); + + @TestQualifier + javax.inject.Provider<Foo> getJavaxQualifiedFoo(); + + @TestQualifier + Provider<Bar> getJakartaQualifiedBar(); + + @TestQualifier + javax.inject.Provider<Bar> getJavaxQualifiedBar(); + + InjectUsages injectUsages(); + + Map<String, Provider<Bar>> getJakartaProviderMap(); + + Map<String, javax.inject.Provider<Bar>> getJavaxProviderMap(); + + Map<String, Provider<Lazy<Bar>>> getJakartaProviderLazyMap(); + + Map<String, javax.inject.Provider<Lazy<Bar>>> getJavaxProviderLazyMap(); + + Map<Long, Provider<Long>> getManuallyProvidedJakartaMap(); + + Map<Long, javax.inject.Provider<Long>> getManuallyProvidedJavaxMap(); + + Optional<Provider<String>> getPresentOptionalJakartaProvider(); + + Optional<javax.inject.Provider<String>> getPresentOptionalJavaxProvider(); + + Optional<Provider<Long>> getEmptyOptionalJakartaProvider(); + + Optional<javax.inject.Provider<Long>> getEmptyOptionalJavaxProvider(); + } + + public static final class Foo { + @Inject + Foo() {} + } + + @TestScope + public static final class Bar { + @Inject + Bar() {} + } + + public static final class InjectUsages { + Provider<Bar> jakartaBar; + Provider<Bar> jakartaQualifiedBar; + javax.inject.Provider<Bar> javaxQualifiedBar; + + @Inject + InjectUsages(Provider<Bar> jakartaBar) { + this.jakartaBar = jakartaBar; + } + + @Inject javax.inject.Provider<Bar> javaxBar; + + @Inject + void injectBar( + Provider<Bar> jakartaQualifiedBar, javax.inject.Provider<Bar> javaxQualifiedBar) { + this.jakartaQualifiedBar = jakartaQualifiedBar; + this.javaxQualifiedBar = javaxQualifiedBar; + } + } + + @Module + abstract static class TestModule { + @Provides + @TestQualifier + static Foo provideFoo( + Provider<Foo> fooProvider, javax.inject.Provider<Foo> unusedOtherFooProvider) { + return fooProvider.get(); + } + + @Provides + @TestQualifier + @TestScope + static Bar provideBar( + Provider<Bar> unusedBarProvider, javax.inject.Provider<Bar> otherBarProvider) { + // Use the other one in this case just to vary it from Foo + return otherBarProvider.get(); + } + + @Binds + @IntoMap + @StringKey("bar") + abstract Bar bindBarIntoMap(Bar bar); + + // TODO(b/65118638): Use @Binds @IntoMap Lazy<T> once that works properly. + @Provides + @IntoMap + @StringKey("bar") + static Lazy<Bar> provideLazyIntoMap(Lazy<Bar> bar) { + return bar; + } + + // Manually provide two Provider maps to make sure they don't conflict. + @Provides + static Map<Long, Provider<Long>> manuallyProvidedJakartaMap() { + Map<Long, Provider<Long>> map = new HashMap<>(); + map.put(9L, null); + return map; + } + + @Provides + static Map<Long, javax.inject.Provider<Long>> manuallyProvidedJavaxMap() { + Map<Long, javax.inject.Provider<Long>> map = new HashMap<>(); + map.put(0L, null); + return map; + } + + @BindsOptionalOf + abstract String bindOptionalString(); + + @Provides + static String provideString() { + return "present"; + } + + @BindsOptionalOf + abstract Long bindOptionalLong(); + } + + @Test + public void testJakartaProviders() { + TestComponent testComponent = DaggerJakartaProviderTest_TestComponent.create(); + + assertThat(testComponent.getJakartaFoo().get()).isNotNull(); + assertThat(testComponent.getJavaxFoo().get()).isNotNull(); + + assertThat(testComponent.getJakartaBar().get()) + .isSameInstanceAs(testComponent.getJavaxBar().get()); + + assertThat(testComponent.getJakartaQualifiedFoo().get()).isNotNull(); + assertThat(testComponent.getJavaxQualifiedFoo().get()).isNotNull(); + + assertThat(testComponent.getJakartaQualifiedBar().get()) + .isSameInstanceAs(testComponent.getJavaxQualifiedBar().get()); + assertThat(testComponent.getJakartaBar().get()) + .isSameInstanceAs(testComponent.getJakartaQualifiedBar().get()); + + InjectUsages injectUsages = testComponent.injectUsages(); + + assertThat(injectUsages.jakartaBar.get()).isSameInstanceAs(injectUsages.javaxBar.get()); + assertThat(injectUsages.jakartaQualifiedBar.get()) + .isSameInstanceAs(injectUsages.javaxQualifiedBar.get()); + assertThat(injectUsages.jakartaBar.get()) + .isSameInstanceAs(injectUsages.jakartaQualifiedBar.get()); + + assertThat(testComponent.getJakartaProviderMap().get("bar").get()).isSameInstanceAs( + testComponent.getJavaxProviderMap().get("bar").get()); + + assertThat(testComponent.getJakartaProviderLazyMap().get("bar").get().get()).isSameInstanceAs( + testComponent.getJavaxProviderLazyMap().get("bar").get().get()); + + Map<Long, Provider<Long>> manualJakartaMap = testComponent.getManuallyProvidedJakartaMap(); + assertThat(manualJakartaMap.keySet()).containsExactly(9L); + + Map<Long, javax.inject.Provider<Long>> manualJavaxMap = + testComponent.getManuallyProvidedJavaxMap(); + assertThat(manualJavaxMap.keySet()).containsExactly(0L); + + assertThat(testComponent.getPresentOptionalJakartaProvider().get().get()).isEqualTo("present"); + assertThat(testComponent.getPresentOptionalJavaxProvider().get().get()).isEqualTo("present"); + assertThat(testComponent.getEmptyOptionalJakartaProvider().isPresent()).isFalse(); + assertThat(testComponent.getEmptyOptionalJavaxProvider().isPresent()).isFalse(); + } +}
diff --git a/javatests/dagger/functional/jdk8/BUILD b/javatests/dagger/functional/jdk8/BUILD index 5a2b613..f65f58b 100644 --- a/javatests/dagger/functional/jdk8/BUILD +++ b/javatests/dagger/functional/jdk8/BUILD
@@ -15,6 +15,7 @@ # Description: # Functional tests for Dagger that depend on Guava +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX") load("//:test_defs.bzl", "GenJavaTests")
diff --git a/javatests/dagger/functional/kotlin/BUILD b/javatests/dagger/functional/kotlin/BUILD index 49bc2ee..345842d 100644 --- a/javatests/dagger/functional/kotlin/BUILD +++ b/javatests/dagger/functional/kotlin/BUILD
@@ -15,8 +15,8 @@ # Description: # Functional test code for Dagger-Android +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") load("@rules_java//java:defs.bzl", "java_library") -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") load("//:test_defs.bzl", "GenJavaTests") package(default_visibility = ["//:src"])
diff --git a/javatests/dagger/functional/kotlin/PropertyQualifierClasses.kt b/javatests/dagger/functional/kotlin/PropertyQualifierClasses.kt index f6b230f..e39c206 100644 --- a/javatests/dagger/functional/kotlin/PropertyQualifierClasses.kt +++ b/javatests/dagger/functional/kotlin/PropertyQualifierClasses.kt
@@ -26,56 +26,40 @@ @Component(modules = [TestKotlinModuleWithQualifier::class]) interface TestKotlinComponentWithQualifier { fun inject(testInjectedClassWithQualifier: TestMemberInjectedClassWithQualifier) + fun inject(fooWithInjectedQualifier: FooWithInjectedQualifier) } @Module class TestKotlinModuleWithQualifier { - @Provides - @JavaTestQualifier - fun provideJavaDataA() = TestDataA("test") + @Provides @JavaTestQualifier fun provideJavaDataA() = TestDataA("test") - @Provides - @JavaTestQualifier - fun provideJavaDataB() = TestDataB("test") + @Provides @JavaTestQualifier fun provideJavaDataB() = TestDataB("test") - @Provides - @JavaTestQualifierWithTarget - fun provideJavaWithTargetDataA() = TestDataA("test") + @Provides @JavaTestQualifierWithTarget fun provideJavaWithTargetDataA() = TestDataA("test") - @Provides - @KotlinTestQualifier - fun provideKotlinDataA() = TestDataA("test") + @Provides @KotlinTestQualifier fun provideKotlinDataA() = TestDataA("test") - @Provides - @JavaTestQualifier - fun provideString() = "qualified string" + @Provides @JavaTestQualifier fun provideString() = "qualified string" } -class TestConstructionInjectedClassWithQualifier @Inject constructor( - @JavaTestQualifier val data: TestDataA -) +class TestConstructionInjectedClassWithQualifier +@Inject +constructor(@JavaTestQualifier val data: TestDataA) @TriggerGeneratedTypeProcessor class TestMemberInjectedClassWithQualifier { - @Inject - @JavaTestQualifier - lateinit var javaDataA: TestDataA + @Inject @JavaTestQualifier lateinit var javaDataA: TestDataA - @Inject - @field:JavaTestQualifier - lateinit var javaDataB: TestDataB + @Inject @field:JavaTestQualifier lateinit var javaDataB: TestDataB - @Inject - @JavaTestQualifierWithTarget - lateinit var javaWithTargetDataA: TestDataA + @Inject @JavaTestQualifierWithTarget lateinit var javaWithTargetDataA: TestDataA - @Inject - @JavaTestQualifier - lateinit var kotlinDataA: TestDataA + @Inject @KotlinTestQualifier lateinit var kotlinDataA: TestDataA - @Inject - lateinit var dataWithConstructionInjection: TestConstructionInjectedClassWithQualifier + @set:Inject @setparam:KotlinTestQualifier var kotlinDataA2: TestDataA? = null + + @Inject lateinit var dataWithConstructionInjection: TestConstructionInjectedClassWithQualifier val noBackingFieldProperty: Int get() = 0 @@ -88,8 +72,14 @@ } data class TestDataA(val data: String) + data class TestDataB(val data: String) -@Qualifier -@Retention(AnnotationRetention.RUNTIME) -annotation class KotlinTestQualifier +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.PROPERTY, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY_SETTER, +) +@Qualifier @Retention(AnnotationRetention.RUNTIME) annotation class KotlinTestQualifier
diff --git a/javatests/dagger/functional/kotlin/PropertyQualifierTest.java b/javatests/dagger/functional/kotlin/PropertyQualifierTest.java index e0ebf3c..9d2de4a 100644 --- a/javatests/dagger/functional/kotlin/PropertyQualifierTest.java +++ b/javatests/dagger/functional/kotlin/PropertyQualifierTest.java
@@ -34,6 +34,7 @@ assertThat(injectedClass.javaDataB).isNotNull(); assertThat(injectedClass.javaWithTargetDataA).isNotNull(); assertThat(injectedClass.kotlinDataA).isNotNull(); + assertThat(injectedClass.getKotlinDataA2()).isNotNull(); assertThat(injectedClass.dataWithConstructionInjection).isNotNull(); assertThat(injectedClass.dataWithConstructionInjection.getData()).isNotNull(); }
diff --git a/javatests/dagger/functional/kotlin/processor/BUILD b/javatests/dagger/functional/kotlin/processor/BUILD index 25273e2..ec147bc 100644 --- a/javatests/dagger/functional/kotlin/processor/BUILD +++ b/javatests/dagger/functional/kotlin/processor/BUILD
@@ -11,7 +11,8 @@ # 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. -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_plugin") package(default_visibility = ["//:src"])
diff --git a/javatests/dagger/functional/kotlinsrc/assisted/kotlin/KotlinAssistedInjectionTest.kt b/javatests/dagger/functional/kotlinsrc/assisted/kotlin/KotlinAssistedInjectionTest.kt index b58d930..ebe8dcb 100644 --- a/javatests/dagger/functional/kotlinsrc/assisted/kotlin/KotlinAssistedInjectionTest.kt +++ b/javatests/dagger/functional/kotlinsrc/assisted/kotlin/KotlinAssistedInjectionTest.kt
@@ -28,8 +28,11 @@ @Component internal interface TestComponent { fun fooFactory(): FooFactory + fun fooDataFactory(): FooDataFactory + fun barManagerFactory(): BarManager.Factory + } @Test
diff --git a/javatests/dagger/functional/kotlinsrc/multibindings/BUILD b/javatests/dagger/functional/kotlinsrc/multibindings/BUILD index 40c2329..64e5dfb 100644 --- a/javatests/dagger/functional/kotlinsrc/multibindings/BUILD +++ b/javatests/dagger/functional/kotlinsrc/multibindings/BUILD
@@ -25,10 +25,24 @@ package(default_visibility = ["//:src"]) GenKtTests( - name = "multibindings", - srcs = glob(["*.kt"]), + name = "MultibindingTest", + srcs = [ + "BooleanKey.kt", + "ByteKey.kt", + "CharKey.kt", + "MultibindingComponent.kt", + "MultibindingDependency.kt", + "MultibindingModule.kt", + "MultibindingTest.kt", + "MultibindsModule.kt", + "NestedAnnotationContainer.kt", + "NumberClassKey.kt", + "ShortKey.kt", + "UnwrappedAnnotationKey.kt", + "WrappedAnnotationKey.kt", + ], gen_library_deps = [ - "//javatests/dagger/functional/kotlinsrc/multibindings/subpackage", + "//javatests/dagger/functional/kotlinsrc/multibindings/subpackage:ContributionsModule", ], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, deps = [ @@ -38,3 +52,66 @@ "//third_party/java/truth", ], ) + +GenKtTests( + name = "BindsInaccessibleMapKeyTest", + srcs = ["BindsInaccessibleMapKeyTest.kt"], + gen_library_deps = [ + "//javatests/dagger/functional/kotlinsrc/multibindings/subpackage:BindsInaccessibleMapKeyModule", + ], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenKtTests( + name = "ClassKeyWithGenericsTest", + srcs = ["ClassKeyWithGenericsTest.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenKtTests( + name = "ComplexMapKeysInDifferentOrderTest", + srcs = ["ComplexMapKeysInDifferentOrderTest.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/auto:value", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenKtTests( + name = "MapKeyWithDefaultTest", + srcs = ["MapKeyWithDefaultTest.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/auto:value", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenKtTests( + name = "LazyMapsTest", + srcs = [ + "LazyMaps.kt", + "LazyMapsTest.kt", + ], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +)
diff --git a/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKey.kt b/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKey.kt deleted file mode 100644 index 1b60250..0000000 --- a/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKey.kt +++ /dev/null
@@ -1,26 +0,0 @@ -/* - * 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 dagger.Component -import dagger.functional.kotlinsrc.multibindings.subpackage.BindsInaccessibleMapKeyModule - -// b/73820357 -@Component(modules = [BindsInaccessibleMapKeyModule::class]) -internal interface BindsInaccessibleMapKey { - fun mapWithAnInaccessibleMapKey(): Map<Class<*>, Any> -}
diff --git a/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKeyTest.kt b/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKeyTest.kt new file mode 100644 index 0000000..6076e23 --- /dev/null +++ b/javatests/dagger/functional/kotlinsrc/multibindings/BindsInaccessibleMapKeyTest.kt
@@ -0,0 +1,41 @@ +/* + * 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.multibindings + +import com.google.common.truth.Truth.assertThat +import dagger.Component +import dagger.functional.kotlinsrc.multibindings.subpackage.BindsInaccessibleMapKeyModule +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +// b/73820357 +@RunWith(JUnit4::class) +class BindsInaccessibleMapKeyTest { + @Component(modules = [BindsInaccessibleMapKeyModule::class]) + internal interface TestComponent { + fun mapWithAnInaccessibleMapKey(): Map<Class<*>, Any> + } + + @Test + fun test() { + val map = DaggerBindsInaccessibleMapKeyTest_TestComponent.create().mapWithAnInaccessibleMapKey() + assertThat(map).hasSize(1) + assertThat(map.keys.single().canonicalName) + .isEqualTo("dagger.functional.kotlinsrc.multibindings.subpackage.Inaccessible"); + } +}
diff --git a/javatests/dagger/functional/kotlinsrc/multibindings/subpackage/BUILD b/javatests/dagger/functional/kotlinsrc/multibindings/subpackage/BUILD index d85fe39..3442486 100644 --- a/javatests/dagger/functional/kotlinsrc/multibindings/subpackage/BUILD +++ b/javatests/dagger/functional/kotlinsrc/multibindings/subpackage/BUILD
@@ -25,8 +25,17 @@ package(default_visibility = ["//:src"]) GenKtLibrary( - name = "subpackage", - srcs = glob(["*.kt"]), + name = "ContributionsModule", + srcs = ["ContributionsModule.kt"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + ], +) + +GenKtLibrary( + name = "BindsInaccessibleMapKeyModule", + srcs = ["BindsInaccessibleMapKeyModule.kt"], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, deps = [ "//:dagger_with_compiler",
diff --git a/javatests/dagger/functional/kotlinsrc/nullables/NullabilityTest.kt b/javatests/dagger/functional/kotlinsrc/nullables/NullabilityTest.kt index c790a66..71d08e3 100644 --- a/javatests/dagger/functional/kotlinsrc/nullables/NullabilityTest.kt +++ b/javatests/dagger/functional/kotlinsrc/nullables/NullabilityTest.kt
@@ -21,9 +21,11 @@ import dagger.Module import dagger.Provides import dagger.Reusable +import dagger.multibindings.IntoSet import java.lang.NullPointerException import javax.inject.Inject import javax.inject.Provider +import javax.inject.Singleton import org.junit.Assert.fail import org.junit.Test import org.junit.runner.RunWith @@ -34,19 +36,37 @@ @Component(dependencies = [NullComponent::class]) internal interface NullComponentWithDependency { fun string(): String? + fun number(): Number + fun stringProvider(): Provider<String> + fun numberProvider(): Provider<Number> } + interface Bar<T> {} + + class BarNoNull : Bar<String> + + class BarWithNull : Bar<String?> + @Component(modules = [NullModule::class]) internal interface NullComponent { fun string(): String? + fun integer(): Int? + fun nullFoo(): NullFoo + fun number(): Number + fun stringProvider(): Provider<String> + fun numberProvider(): Provider<Number> + + fun setOfBar(): Set<Bar<String>> + + fun setOfBarWithNullableArg(): Set<Bar<String?>> } @Module @@ -54,6 +74,10 @@ var numberValue: Number? = null var integerCallCount = 0 + @IntoSet @Provides fun providesNullableStringInToSet(): Bar<String?> = BarWithNull() + + @IntoSet @Provides fun providesNonNullStringIntoSet(): Bar<String> = BarNoNull() + @Provides fun provideNullableString(): String? = null @Provides fun provideNumber(): Number = numberValue!! @@ -73,7 +97,7 @@ val string: String?, val number: Number, val stringProvider: Provider<String>, - val numberProvider: Provider<Number> + val numberProvider: Provider<Number>, ) { var methodInjectedString: String? = null lateinit var methodInjectedNumber: Number @@ -85,7 +109,7 @@ string: String?, number: Number, stringProvider: Provider<String>, - numberProvider: Provider<Number> + numberProvider: Provider<Number>, ) { methodInjectedString = string methodInjectedNumber = number @@ -126,12 +150,12 @@ validate( nullFoo.methodInjectedString, nullFoo.methodInjectedStringProvider, - nullFoo.methodInjectedNumberProvider + nullFoo.methodInjectedNumberProvider, ) validate( nullFoo.fieldInjectedString, nullFoo.fieldInjectedStringProvider, - nullFoo.fieldInjectedNumberProvider + nullFoo.fieldInjectedNumberProvider, ) } @@ -146,6 +170,8 @@ assertThat(module.integerCallCount).isEqualTo(1) assertThat(component.integer()).isNull() assertThat(module.integerCallCount).isEqualTo(1) + assertThat(component.setOfBar().size).isEqualTo(2) + assertThat(component.setOfBarWithNullableArg().size).isEqualTo(2) } @Test @@ -153,11 +179,20 @@ val nullComponent: NullComponent = object : NullComponent { override fun string(): String? = null + override fun integer(): Int? = null + override fun stringProvider(): Provider<String> = Provider { null!! } + override fun numberProvider(): Provider<Number> = Provider { null!! } + override fun number(): Number = null!! + override fun nullFoo(): NullFoo = null!! + + override fun setOfBar(): Set<Bar<String>> = emptySet() + + override fun setOfBarWithNullableArg(): Set<Bar<String?>> = emptySet() } val component = DaggerNullabilityTest_NullComponentWithDependency.builder() @@ -181,7 +216,7 @@ private fun validate( string: String?, stringProvider: Provider<String>, - numberProvider: Provider<Number> + numberProvider: Provider<Number>, ) { assertThat(string).isNull() assertThat(numberProvider).isNotNull()
diff --git a/javatests/dagger/functional/membersinject/MembersWithInstanceNameTest.java b/javatests/dagger/functional/membersinject/MembersWithInstanceNameTest.java index 7cd97d9..729059a 100644 --- a/javatests/dagger/functional/membersinject/MembersWithInstanceNameTest.java +++ b/javatests/dagger/functional/membersinject/MembersWithInstanceNameTest.java
@@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; +import dagger.BindsInstance; import dagger.Component; import dagger.Module; import dagger.Provides; @@ -36,6 +37,16 @@ @Inject Foo() {} } + static final class Bar { + // Checks that member injection fields can use injecting a bound instance that was + // named "instance" when bound. Note that the field name here doesn't matter as of + // this writing, but name it "instance" anyway in case that changes. + // https://github.com/google/dagger/issues/4352 + @Inject BoundInstance instance; + + @Inject Bar() {} + } + @Module interface TestModule { @Provides @@ -44,16 +55,60 @@ } } + public static final class BoundInstance {} + @Component(modules = TestModule.class) interface TestComponent { Foo foo(); + + Bar bar(); + + @Component.Builder + interface Builder { + // As of writing, the method name is the one that matters, but name the + // parameter the same anyway in case that changes. + Builder instance(@BindsInstance BoundInstance instance); + TestComponent build(); + } + } + + @Component(modules = TestModule.class) + interface TestComponentWithFactory { + Foo foo(); + + Bar bar(); + + @Component.Factory + interface Factory { + // As of writing, the parameter name is the one that matters, but name the + // method the same anyway in case that changes. + TestComponentWithFactory instance(@BindsInstance BoundInstance instance); + } } @Test public void testMemberWithInstanceName() { - TestComponent component = DaggerMembersWithInstanceNameTest_TestComponent.create(); + BoundInstance boundInstance = new BoundInstance(); + TestComponent component = DaggerMembersWithInstanceNameTest_TestComponent + .builder().instance(boundInstance).build(); Foo foo = component.foo(); assertThat(foo).isNotNull(); assertThat(foo.instance).isEqualTo("test"); + Bar bar = component.bar(); + assertThat(bar).isNotNull(); + assertThat(bar.instance).isSameInstanceAs(boundInstance); + } + + @Test + public void testMemberWithInstanceNameUsingFactory() { + BoundInstance boundInstance = new BoundInstance(); + TestComponentWithFactory component = DaggerMembersWithInstanceNameTest_TestComponentWithFactory + .factory().instance(boundInstance); + Foo foo = component.foo(); + assertThat(foo).isNotNull(); + assertThat(foo.instance).isEqualTo("test"); + Bar bar = component.bar(); + assertThat(bar).isNotNull(); + assertThat(bar.instance).isSameInstanceAs(boundInstance); } }
diff --git a/javatests/dagger/functional/multibindings/BUILD b/javatests/dagger/functional/multibindings/BUILD index 63a7bfd..42153c4 100644 --- a/javatests/dagger/functional/multibindings/BUILD +++ b/javatests/dagger/functional/multibindings/BUILD
@@ -25,17 +25,106 @@ package(default_visibility = ["//:src"]) GenJavaTests( - name = "multibindings", - srcs = glob(["*.java"]), + name = "MultibindingTest", + srcs = [ + "BooleanKey.java", + "ByteKey.java", + "CharKey.java", + "MultibindingComponent.java", + "MultibindingDependency.java", + "MultibindingModule.java", + "MultibindingTest.java", + "MultibindsModule.java", + "NestedAnnotationContainer.java", + "NumberClassKey.java", + "RequiresFieldInjection.java", + "ShortKey.java", + "UnwrappedAnnotationKey.java", + "WrappedAnnotationKey.java", + ], gen_library_deps = [ - "//javatests/dagger/functional/multibindings/subpackage", + "//javatests/dagger/functional/multibindings/subpackage:ContributionsModule", ], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, deps = [ "//:dagger_with_compiler", "//third_party/java/auto:value", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( + name = "BindsInaccessibleMapKeyTest", + srcs = ["BindsInaccessibleMapKeyTest.java"], + gen_library_deps = [ + "//javatests/dagger/functional/multibindings/subpackage:BindsInaccessibleMapKeyModule", + ], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", "//third_party/java/guava/collect", "//third_party/java/junit", "//third_party/java/truth", ], ) + +GenJavaTests( + name = "ClassKeyWithGenericsTest", + srcs = ["ClassKeyWithGenericsTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( + name = "LazyClassKeyWithGenericsTest", + srcs = ["LazyClassKeyWithGenericsTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( + name = "ComplexMapKeysInDifferentOrderTest", + srcs = ["ComplexMapKeysInDifferentOrderTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/auto:value", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( + name = "MapKeyWithDefaultTest", + srcs = ["MapKeyWithDefaultTest.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/auto:value", + "//third_party/java/junit", + "//third_party/java/truth", + ], +) + +GenJavaTests( + name = "LazyMapsTest", + srcs = [ + "LazyMaps.java", + "LazyMapsTest.java", + ], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + "//third_party/java/junit", + "//third_party/java/truth", + ], +)
diff --git a/javatests/dagger/functional/multibindings/BindsInaccessibleMapKeyTest.java b/javatests/dagger/functional/multibindings/BindsInaccessibleMapKeyTest.java new file mode 100644 index 0000000..470f644 --- /dev/null +++ b/javatests/dagger/functional/multibindings/BindsInaccessibleMapKeyTest.java
@@ -0,0 +1,47 @@ +/* + * 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.collect.Iterables.getOnlyElement; +import static com.google.common.truth.Truth.assertThat; + +import dagger.Component; +import dagger.functional.multibindings.subpackage.BindsInaccessibleMapKeyModule; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +// b/73820357 +@RunWith(JUnit4.class) +public class BindsInaccessibleMapKeyTest { + @Component(modules = BindsInaccessibleMapKeyModule.class) + interface TestComponent { + Map<Class<?>, Object> mapWithAnInaccessibleMapKey(); + } + + @Test + public void test() { + Map<Class<?>, Object> map = + DaggerBindsInaccessibleMapKeyTest_TestComponent.create().mapWithAnInaccessibleMapKey(); + assertThat(map).hasSize(1); + assertThat(getOnlyElement(map.keySet()).getCanonicalName()) + .isEqualTo( + "dagger.functional.multibindings.subpackage." + + "BindsInaccessibleMapKeyModule.Inaccessible"); + } +}
diff --git a/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java b/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java index 801d120..6883225 100644 --- a/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java +++ b/javatests/dagger/functional/multibindings/ComplexMapKeysInDifferentOrderTest.java
@@ -38,13 +38,23 @@ @interface ComplexMapKey { int i(); int j(); + + NestKey[] nestKeys() default {}; + } + + @Retention(RUNTIME) + @MapKey(unwrapValue = false) + @interface NestKey { + int i() default 0; + + String j() default ""; } @Module interface TestModule { @Provides @IntoMap - @ComplexMapKey(i = 1, j = 2) + @ComplexMapKey(i = 1, j = 2, nestKeys = @NestKey) static int inOrder() { return 3; } @@ -66,12 +76,21 @@ public void test() { Map<ComplexMapKey, Integer> map = DaggerComplexMapKeysInDifferentOrderTest_TestComponent.create().map(); - assertThat(map.get(mapKey(1, 2))).isEqualTo(3); - assertThat(map.get(mapKey(5, 4))).isEqualTo(6); + assertThat(map) + .containsEntry( + mapKey( + 1, + 2, + new NestKey[] { + new AutoAnnotation_ComplexMapKeysInDifferentOrderTest_ComplexMapKeyCreator_createNestKey( + 0, "") + }), + 3); + assertThat(map).containsEntry(mapKey(5, 4, new NestKey[] {}), 6); } @AutoAnnotation - static ComplexMapKey mapKey(int i, int j) { - return new AutoAnnotation_ComplexMapKeysInDifferentOrderTest_mapKey(i, j); + static ComplexMapKey mapKey(int i, int j, NestKey[] nestKeys) { + return new AutoAnnotation_ComplexMapKeysInDifferentOrderTest_mapKey(i, j, nestKeys); } }
diff --git a/javatests/dagger/functional/multibindings/LazyClassKeyWithGenericsTest.java b/javatests/dagger/functional/multibindings/LazyClassKeyWithGenericsTest.java new file mode 100644 index 0000000..95c36f8 --- /dev/null +++ b/javatests/dagger/functional/multibindings/LazyClassKeyWithGenericsTest.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.functional.multibindings; + +import static com.google.common.truth.Truth.assertThat; + +import dagger.Component; +import dagger.Module; +import dagger.Provides; +import dagger.multibindings.IntoMap; +import dagger.multibindings.LazyClassKey; +import java.util.Map; +import javax.inject.Provider; +import javax.inject.Singleton; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class LazyClassKeyWithGenericsTest { + @Component(modules = TestModule.class) + @Singleton + interface TestComponent { + Map<Class<?>, String> map(); + + Provider<Map<Class<?>, Provider<Integer>>> intMap(); + } + + @Module + interface TestModule { + @Provides + @IntoMap + @LazyClassKey(Thing.class) + static String provideThingValue() { + return "Thing"; + } + + @Provides + @IntoMap + @LazyClassKey(GenericThing.class) + static String provideGenericThingValue() { + return "GenericThing"; + } + + @Provides + @IntoMap + @LazyClassKey(Thing.class) + static Integer provideThingIntValue() { + return 2; + } + + @Provides + @IntoMap + @LazyClassKey(GenericThing.class) + static Integer provideGenericThingIntValue() { + return 1; + } + } + + class Thing {} + + class GenericThing<T> {} + + @Test + public void test() { + TestComponent testComponent = DaggerLazyClassKeyWithGenericsTest_TestComponent.create(); + Map<Class<?>, String> map = testComponent.map(); + Map<Class<?>, Provider<Integer>> intMap = testComponent.intMap().get(); + // MapSubject#containsExactly uses entrySet, which is banned from DaggerClassKey map. + assertThat(map.get(Thing.class)).isEqualTo("Thing"); + assertThat(map.get(GenericThing.class)).isEqualTo("GenericThing"); + assertThat(intMap.get(Thing.class).get()).isEqualTo(2); + assertThat(intMap.get(GenericThing.class).get()).isEqualTo(1); + } +}
diff --git a/javatests/dagger/functional/multibindings/MultibindingComponent.java b/javatests/dagger/functional/multibindings/MultibindingComponent.java index 8e61ae0..77eeb53 100644 --- a/javatests/dagger/functional/multibindings/MultibindingComponent.java +++ b/javatests/dagger/functional/multibindings/MultibindingComponent.java
@@ -17,6 +17,7 @@ package dagger.functional.multibindings; import dagger.Component; +import dagger.MembersInjector; import dagger.functional.multibindings.subpackage.ContributionsModule; import dagger.multibindings.StringKey; import java.util.Collection; @@ -67,4 +68,8 @@ @Named("complexQualifier") Map<String, CharSequence> maybeEmptyQualifiedMap(); + + Map<Class<?>, MembersInjector<?>> membersInjectorMap(); + + Set<MembersInjector<?>> membersInjectorSet(); }
diff --git a/javatests/dagger/functional/multibindings/MultibindingModule.java b/javatests/dagger/functional/multibindings/MultibindingModule.java index cc34e24..af90d3c 100644 --- a/javatests/dagger/functional/multibindings/MultibindingModule.java +++ b/javatests/dagger/functional/multibindings/MultibindingModule.java
@@ -16,6 +16,7 @@ package dagger.functional.multibindings; +import dagger.MembersInjector; import dagger.Module; import dagger.Provides; import dagger.multibindings.ClassKey; @@ -96,6 +97,27 @@ } @Provides + @Named("fieldInjectedValue") + static String provideFieldInjectedValue() { + return "fieldInjectedValue"; + } + + @Provides + @IntoMap + @ClassKey(RequiresFieldInjection.class) + static MembersInjector<?> provideMembersInjectorIntoMap( + MembersInjector<RequiresFieldInjection> injector) { + return injector; + } + + @Provides + @IntoSet + static MembersInjector<?> provideMembersInjectorIntoSet( + MembersInjector<RequiresFieldInjection> injector) { + return injector; + } + + @Provides @IntoMap @NestedAnnotationContainer.NestedWrappedKey(Integer.class) static String valueForInteger() {
diff --git a/javatests/dagger/functional/multibindings/MultibindingTest.java b/javatests/dagger/functional/multibindings/MultibindingTest.java index 9787764..96037fe 100644 --- a/javatests/dagger/functional/multibindings/MultibindingTest.java +++ b/javatests/dagger/functional/multibindings/MultibindingTest.java
@@ -19,11 +19,13 @@ import static com.google.common.truth.Truth.assertThat; import com.google.auto.value.AutoAnnotation; +import dagger.MembersInjector; import dagger.multibindings.ClassKey; import dagger.multibindings.StringKey; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Map; +import java.util.Set; import javax.inject.Provider; import org.junit.Test; import org.junit.runner.RunWith; @@ -183,6 +185,29 @@ .containsEntry("key", "qualified foo value"); } + @SuppressWarnings("unchecked") // We know the single type in the set + @Test + public void membersInjectorSet() { + Set<MembersInjector<?>> injectors = multibindingComponent.membersInjectorSet(); + assertThat(injectors).hasSize(1); + RequiresFieldInjection injected = new RequiresFieldInjection(); + assertThat(injected.value).isNull(); + ((MembersInjector<RequiresFieldInjection>) injectors.iterator().next()).injectMembers(injected); + assertThat(injected.value).isEqualTo("fieldInjectedValue"); + } + + @SuppressWarnings("unchecked") // We know the single type in the map + @Test + public void membersInjectorMap() { + Map<Class<?>, MembersInjector<?>> injectors = multibindingComponent.membersInjectorMap(); + assertThat(injectors).hasSize(1); + RequiresFieldInjection injected = new RequiresFieldInjection(); + assertThat(injected.value).isNull(); + ((MembersInjector<RequiresFieldInjection>) injectors.get(RequiresFieldInjection.class)) + .injectMembers(injected); + assertThat(injected.value).isEqualTo("fieldInjectedValue"); + } + @AutoAnnotation static StringKey testStringKey(String value) { return new AutoAnnotation_MultibindingTest_testStringKey(value);
diff --git a/javatests/dagger/functional/multibindings/MultibindsModule.java b/javatests/dagger/functional/multibindings/MultibindsModule.java index b678c9e..72698eb 100644 --- a/javatests/dagger/functional/multibindings/MultibindsModule.java +++ b/javatests/dagger/functional/multibindings/MultibindsModule.java
@@ -16,6 +16,7 @@ package dagger.functional.multibindings; +import dagger.MembersInjector; import dagger.Module; import dagger.multibindings.Multibinds; import java.util.Map; @@ -39,9 +40,15 @@ abstract Set<CharSequence> set(); @Multibinds + abstract Set<MembersInjector<?>> membersInjectorSet(); + + @Multibinds abstract Map<String, CharSequence> map(); @Multibinds + abstract Map<Class<?>, MembersInjector<?>> membersInjectorMap(); + + @Multibinds @Named("complexQualifier") abstract Set<Object> emptyQualifiedSet();
diff --git a/javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java b/javatests/dagger/functional/multibindings/RequiresFieldInjection.java similarity index 64% rename from javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java rename to javatests/dagger/functional/multibindings/RequiresFieldInjection.java index 6256812..2a1a060 100644 --- a/javatests/dagger/functional/multibindings/BindsInaccessibleMapKey.java +++ b/javatests/dagger/functional/multibindings/RequiresFieldInjection.java
@@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 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. @@ -16,12 +16,9 @@ package dagger.functional.multibindings; -import dagger.Component; -import dagger.functional.multibindings.subpackage.BindsInaccessibleMapKeyModule; -import java.util.Map; +import javax.inject.Inject; +import javax.inject.Named; -// b/73820357 -@Component(modules = BindsInaccessibleMapKeyModule.class) -interface BindsInaccessibleMapKey { - Map<Class<?>, Object> mapWithAnInaccessibleMapKey(); +public final class RequiresFieldInjection { + @Inject @Named("fieldInjectedValue") String value; }
diff --git a/javatests/dagger/functional/multibindings/subpackage/BUILD b/javatests/dagger/functional/multibindings/subpackage/BUILD index fe3abef..1485b04 100644 --- a/javatests/dagger/functional/multibindings/subpackage/BUILD +++ b/javatests/dagger/functional/multibindings/subpackage/BUILD
@@ -25,8 +25,17 @@ package(default_visibility = ["//:src"]) GenJavaLibrary( - name = "subpackage", - srcs = glob(["*.java"]), + name = "ContributionsModule", + srcs = ["ContributionsModule.java"], + javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, + deps = [ + "//:dagger_with_compiler", + ], +) + +GenJavaLibrary( + name = "BindsInaccessibleMapKeyModule", + srcs = ["BindsInaccessibleMapKeyModule.java"], javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES, deps = [ "//:dagger_with_compiler",
diff --git a/javatests/dagger/functional/producers/binds/SimpleBindingModule.java b/javatests/dagger/functional/producers/binds/SimpleBindingModule.java index f2af277..4eaec46 100644 --- a/javatests/dagger/functional/producers/binds/SimpleBindingModule.java +++ b/javatests/dagger/functional/producers/binds/SimpleBindingModule.java
@@ -37,7 +37,6 @@ import java.util.concurrent.Executor; import javax.inject.Named; import javax.inject.Qualifier; -import javax.inject.Singleton; @ProducerModule(includes = { SimpleBindingModule.ExecutorModule.class, @@ -54,7 +53,6 @@ abstract Foo<? extends Number> bindFooOfNumbers(Foo<Integer> fooOfIntegers); @Binds - @Singleton @SomeQualifier abstract Foo<String> bindQualifiedFooOfStrings(FooOfStrings impl);
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java b/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java index 651bdf8..69c53b8 100644 --- a/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java +++ b/javatests/dagger/functional/producers/multibindings/MultibindingComponent.java
@@ -29,7 +29,6 @@ import java.util.Map; import java.util.Set; - @ProductionComponent( modules = {ExecutorModule.class, MultibindingProducerModule.class, MultibindingModule.class} ) @@ -48,6 +47,12 @@ ListenableFuture<Map<Integer, Produced<String>>> mapOfProduced(); + ListenableFuture<Map<Class<?>, Produced<String>>> lazyClassKeyMapOfProduced(); + + ListenableFuture<Map<Class<?>, String>> lazyClassKeyMapOfString(); + + ListenableFuture<Map<Class<?>, Producer<String>>> lazyClassKeyMapOfProducer(); + @PossiblyThrowingMap ListenableFuture<Map<Integer, String>> possiblyThrowingMap();
diff --git a/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java b/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java index 350733b..b04ae7e 100644 --- a/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java +++ b/javatests/dagger/functional/producers/multibindings/MultibindingProducerModule.java
@@ -27,6 +27,7 @@ import dagger.multibindings.IntKey; import dagger.multibindings.IntoMap; import dagger.multibindings.IntoSet; +import dagger.multibindings.LazyClassKey; import dagger.multibindings.Multibinds; import dagger.producers.Produced; import dagger.producers.ProducerModule; @@ -36,6 +37,8 @@ @ProducerModule abstract class MultibindingProducerModule { + static class Foo {} + @Produces @IntoSet static ListenableFuture<String> futureStr() { @@ -122,6 +125,13 @@ throw new RuntimeException("monkey"); } + @Produces + @IntoMap + @LazyClassKey(Foo.class) + static String produceName() { + return "foo"; + } + @Multibinds abstract Set<Object> objs();
diff --git a/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java b/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java index f7059c7..1e3a46d 100644 --- a/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java +++ b/javatests/dagger/functional/producers/subcomponent/SubcomponentsWithBoundExecutor.java
@@ -25,6 +25,8 @@ import dagger.producers.Production; import dagger.producers.ProductionComponent; import dagger.producers.ProductionSubcomponent; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import javax.inject.Inject; @@ -32,12 +34,15 @@ import javax.inject.Qualifier; final class SubcomponentsWithBoundExecutor { + @Retention(RetentionPolicy.RUNTIME) // Technically a JSR330 requirement @Qualifier @interface FromParent {} + @Retention(RetentionPolicy.RUNTIME) // Technically a JSR330 requirement @Qualifier @interface FromChild {} + @Retention(RetentionPolicy.RUNTIME) // Technically a JSR330 requirement @Qualifier @interface FromGrandchild {}
diff --git a/javatests/dagger/hilt/android/AndroidManifest.xml b/javatests/dagger/hilt/android/AndroidManifest.xml index ed24e45..24efa4d 100644 --- a/javatests/dagger/hilt/android/AndroidManifest.xml +++ b/javatests/dagger/hilt/android/AndroidManifest.xml
@@ -46,6 +46,10 @@ android:exported="false" tools:ignore="MissingClass"/> <activity + android:name=".PackagePrivateConstructorTest$TestActivity" + android:exported="false" + tools:ignore="MissingClass"/> + <activity android:name=".QualifierInKotlinFieldsTest$TestActivity" android:exported="false" tools:ignore="MissingClass"/>
diff --git a/javatests/dagger/hilt/android/BUILD b/javatests/dagger/hilt/android/BUILD index b3da0d2..f3ae20f 100644 --- a/javatests/dagger/hilt/android/BUILD +++ b/javatests/dagger/hilt/android/BUILD
@@ -360,6 +360,22 @@ ) android_local_test( + name = "PackagePrivateConstructorTest", + srcs = ["PackagePrivateConstructorTest.java"], + manifest = "AndroidManifest.xml", + manifest_values = { + "minSdkVersion": "14", + }, + deps = [ + "//:android_local_test_exports", + "//java/dagger/hilt/android:android_entry_point", + "//java/dagger/hilt/android:package_info", + "//java/dagger/hilt/android/testing:hilt_android_test", + "//javatests/dagger/hilt/android/testsubpackage:PackagePrivateConstructorTestClasses", + ], +) + +android_local_test( name = "QualifierInKotlinFieldsTest", srcs = ["QualifierInKotlinFieldsTest.java"], manifest = "AndroidManifest.xml",
diff --git a/javatests/dagger/hilt/android/EntryPointAccessorsTest.kt b/javatests/dagger/hilt/android/EntryPointAccessorsTest.kt index fb4afc0..c741a35 100644 --- a/javatests/dagger/hilt/android/EntryPointAccessorsTest.kt +++ b/javatests/dagger/hilt/android/EntryPointAccessorsTest.kt
@@ -27,14 +27,18 @@ import dagger.Module import dagger.Provides import dagger.hilt.EntryPoint +import dagger.hilt.EntryPoints import dagger.hilt.InstallIn import dagger.hilt.android.components.ActivityComponent import dagger.hilt.android.components.FragmentComponent +import dagger.hilt.android.components.FragmentRetainedComponent import dagger.hilt.android.components.ViewComponent +import dagger.hilt.android.internal.managers.InternalFragmentRetainedComponent import dagger.hilt.android.testing.HiltAndroidRule import dagger.hilt.android.testing.HiltAndroidTest import dagger.hilt.android.testing.HiltTestApplication import dagger.hilt.components.SingletonComponent +import javax.inject.Inject import javax.inject.Qualifier import org.junit.Rule import org.junit.Test @@ -55,24 +59,15 @@ const val VIEW_STRING = "VIEW_STRING" } - @get:Rule - var rule = HiltAndroidRule(this) + @get:Rule var rule = HiltAndroidRule(this) - @Qualifier - @Retention(AnnotationRetention.BINARY) - annotation class ApplicationLevel + @Qualifier @Retention(AnnotationRetention.BINARY) annotation class ApplicationLevel - @Qualifier - @Retention(AnnotationRetention.BINARY) - annotation class ActivityLevel + @Qualifier @Retention(AnnotationRetention.BINARY) annotation class ActivityLevel - @Qualifier - @Retention(AnnotationRetention.BINARY) - annotation class FragmentLevel + @Qualifier @Retention(AnnotationRetention.BINARY) annotation class FragmentLevel - @Qualifier - @Retention(AnnotationRetention.BINARY) - annotation class ViewLevel + @Qualifier @Retention(AnnotationRetention.BINARY) annotation class ViewLevel @Module @InstallIn(SingletonComponent::class) @@ -117,50 +112,43 @@ @EntryPoint @InstallIn(SingletonComponent::class) internal interface ApplicationEntryPoint { - @ApplicationLevel - fun getString(): String + @ApplicationLevel fun getString(): String } @EntryPoint @InstallIn(ActivityComponent::class) internal interface ActivityEntryPoint { - @ActivityLevel - fun getString(): String + @ActivityLevel fun getString(): String } @EntryPoint @InstallIn(FragmentComponent::class) internal interface FragmentEntryPoint { - @FragmentLevel - fun getString(): String + @FragmentLevel fun getString(): String } @EntryPoint @InstallIn(ViewComponent::class) internal interface ViewEntryPoint { - @ViewLevel - fun getString(): String + @ViewLevel fun getString(): String } @Test fun testApplicationEntryPoint() { val app = getApplicationContext<HiltTestApplication>() val entryPoint = EntryPointAccessors.fromApplication<ApplicationEntryPoint>(app) - Truth.assertThat(entryPoint.getString()) - .isEqualTo(APPLICATION_STRING) + Truth.assertThat(entryPoint.getString()).isEqualTo(APPLICATION_STRING) val activity = Robolectric.buildActivity(TestActivity::class.java).setup().get() val applicationEntryPoint = EntryPointAccessors.fromApplication<ApplicationEntryPoint>(activity) - Truth.assertThat(applicationEntryPoint.getString()) - .isEqualTo(APPLICATION_STRING) + Truth.assertThat(applicationEntryPoint.getString()).isEqualTo(APPLICATION_STRING) } @Test fun testActivityEntryPoint() { val activity = Robolectric.buildActivity(TestActivity::class.java).setup().get() val entryPoint = EntryPointAccessors.fromActivity<ActivityEntryPoint>(activity) - Truth.assertThat(entryPoint.getString()) - .isEqualTo(ACTIVITY_STRING) + Truth.assertThat(entryPoint.getString()).isEqualTo(ACTIVITY_STRING) } @Test @@ -169,8 +157,7 @@ val fragment = TestFragment() activity.supportFragmentManager.beginTransaction().add(fragment, "").commitNow() val entryPoint = EntryPointAccessors.fromFragment<FragmentEntryPoint>(fragment) - Truth.assertThat(entryPoint.getString()) - .isEqualTo(FRAGMENT_STRING) + Truth.assertThat(entryPoint.getString()).isEqualTo(FRAGMENT_STRING) } @Test @@ -178,15 +165,15 @@ val activity = Robolectric.buildActivity(TestActivity::class.java).setup().get() val view = TestView(activity) val entryPoint = EntryPointAccessors.fromView<ViewEntryPoint>(view) - Truth.assertThat(entryPoint.getString()) - .isEqualTo(VIEW_STRING) + Truth.assertThat(entryPoint.getString()).isEqualTo(VIEW_STRING) } @AndroidEntryPoint(FragmentActivity::class) class TestActivity : Hilt_EntryPointAccessorsTest_TestActivity() @AndroidEntryPoint(Fragment::class) - class TestFragment : Hilt_EntryPointAccessorsTest_TestFragment() + class TestFragment : Hilt_EntryPointAccessorsTest_TestFragment() { + } @AndroidEntryPoint(View::class) class TestView(context: Context) : Hilt_EntryPointAccessorsTest_TestView(context)
diff --git a/javatests/dagger/hilt/android/PackagePrivateConstructorTest.java b/javatests/dagger/hilt/android/PackagePrivateConstructorTest.java new file mode 100644 index 0000000..d20ff98 --- /dev/null +++ b/javatests/dagger/hilt/android/PackagePrivateConstructorTest.java
@@ -0,0 +1,120 @@ +/* + * 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; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.IBinder; +import androidx.test.core.app.ActivityScenario; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import dagger.hilt.android.testing.HiltAndroidRule; +import dagger.hilt.android.testing.HiltAndroidTest; +import dagger.hilt.android.testing.HiltTestApplication; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseActivity; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseBroadcastReceiver; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseFragment; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseIntentService; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseService; +import dagger.hilt.android.testsubpackage.PackagePrivateConstructorTestClasses.BaseView; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; + +/** Regression test for b/331280240. */ +@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 final class PackagePrivateConstructorTest { + @Rule public final HiltAndroidRule rule = new HiltAndroidRule(this); + + @AndroidEntryPoint(BaseActivity.class) + public static final class TestActivity extends Hilt_PackagePrivateConstructorTest_TestActivity { + } + + @AndroidEntryPoint(BaseFragment.class) + public static final class TestFragment extends Hilt_PackagePrivateConstructorTest_TestFragment { + } + + @AndroidEntryPoint(BaseView.class) + public static final class TestView extends Hilt_PackagePrivateConstructorTest_TestView { + TestView(Context context) { + super(context); + } + } + + @AndroidEntryPoint(BaseService.class) + public static final class TestService extends Hilt_PackagePrivateConstructorTest_TestService { + @Override + public IBinder onBind(Intent intent) { + return null; + } + } + + @AndroidEntryPoint(BaseIntentService.class) + public static final class TestIntentService + extends Hilt_PackagePrivateConstructorTest_TestIntentService { + public TestIntentService() { + super("TestIntentServiceName"); + } + + @Override + public void onHandleIntent(Intent intent) {} + } + + @AndroidEntryPoint(BaseBroadcastReceiver.class) + public static final class TestBroadcastReceiver + extends Hilt_PackagePrivateConstructorTest_TestBroadcastReceiver { + } + + @Before + public void setup() { + rule.inject(); + } + + // Technically all the tests need to do is check for compilation, but might as well make sure the + // classes are usable + @Test + public void testActivityFragmentView() throws Exception { + try (ActivityScenario<TestActivity> scenario = ActivityScenario.launch(TestActivity.class)) { + scenario.onActivity( + activity -> { + TestFragment fragment = new TestFragment(); + activity.getSupportFragmentManager().beginTransaction().add(fragment, "").commitNow(); + TestView unused = new TestView(fragment.getContext()); + }); + } + } + + @Test + public void testServices() throws Exception { + Robolectric.setupService(TestService.class); + Robolectric.setupService(TestIntentService.class); + } + + @Test + public void testBroadcastReceiver() throws Exception { + TestBroadcastReceiver testBroadcastReceiver = new TestBroadcastReceiver(); + Intent intent = new Intent(); + testBroadcastReceiver.onReceive(ApplicationProvider.getApplicationContext(), intent); + } +}
diff --git a/javatests/dagger/hilt/android/processor/internal/BUILD b/javatests/dagger/hilt/android/processor/internal/BUILD index ac89e9d..8bb88bd 100644 --- a/javatests/dagger/hilt/android/processor/internal/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/BUILD
@@ -24,7 +24,7 @@ compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [
diff --git a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java index 55e6966..5705c91 100644 --- a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java +++ b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java
@@ -123,19 +123,122 @@ JOINER.join( " Hilt_MyView(Context p0, @Nullable AttributeSet p1) {", " super(p0, p1);", - " inject();", + " if(!isInEditMode()) {", + " inject();", + " }", " }")); } else { stringSubject.contains( JOINER.join( " Hilt_MyView(Context context, @Nullable AttributeSet attrs) {", " super(context, attrs);", - " inject();", + " if(!isInEditMode()) {", + " inject();", + " }", " }")); } }); } + // This is a regression test for b/382104423 + @Test + public void typeUseNullableCopiedFromSuperConstructor() { + Source baseView = + HiltCompilerTests.javaSource( + "test.BaseView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "import org.jspecify.annotations.Nullable;", + "", + "public class BaseView extends View {", + " public BaseView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + Source myView = + HiltCompilerTests.javaSource( + "test.MyView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "import dagger.hilt.android.AndroidEntryPoint;", + "import org.jspecify.annotations.Nullable;", + "", + "@AndroidEntryPoint(BaseView.class)", + "public class MyView extends Hilt_MyView {", + " public MyView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + HiltCompilerTests.hiltCompiler(baseView, myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("org.jspecify.annotations.Nullable"); + }); + } + + @Test + public void hybridTypeUseAndDeclarationNullableNotDuplicated() { + Source hybridNullable = + HiltCompilerTests.javaSource( + "test.Nullable", + "package test;", + "", + "import static java.lang.annotation.ElementType.PARAMETER;", + "import static java.lang.annotation.ElementType.TYPE_USE;", + "", + "import java.lang.annotation.Target;", + "", + "@Target({TYPE_USE, PARAMETER})", + "public @interface Nullable {}"); + Source baseView = + HiltCompilerTests.javaSource( + "test.BaseView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "", + "public class BaseView extends View {", + " public BaseView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + Source myView = + HiltCompilerTests.javaSource( + "test.MyView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "import dagger.hilt.android.AndroidEntryPoint;", + "", + "@AndroidEntryPoint(BaseView.class)", + "public class MyView extends Hilt_MyView {", + " public MyView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + HiltCompilerTests.hiltCompiler(hybridNullable, baseView, myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("@Nullable"); + }); + } + // This is a regression test for https://github.com/google/dagger/issues/3296 @Test public void isRestrictedApiConstructorWithPrimitiveParameterTest() {
diff --git a/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD b/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD index 146f537..2cf63e0 100644 --- a/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/aggregateddeps/BUILD
@@ -14,6 +14,7 @@ # Description: # Tests for internal code for implementing Hilt processors. +load("@rules_java//java:defs.bzl", "java_library") load("//java/dagger/testing/compile:macros.bzl", "compiler_test") package(default_visibility = ["//:src"]) @@ -30,7 +31,7 @@ "//java/dagger/hilt/android/internal/modules", "//java/dagger/hilt/testing:test_install_in", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ "//java/dagger/hilt/android/testing/compile", @@ -49,7 +50,7 @@ "//java/dagger/hilt/android:early_entry_point", "//java/dagger/hilt/android/components", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ "//java/dagger/hilt/android/testing/compile",
diff --git a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD index 8a39641..33bd535 100644 --- a/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/androidentrypoint/BUILD
@@ -23,7 +23,7 @@ srcs = ["ActivityGeneratorTest.java"], compiler_deps = [ "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], resources = glob([ "goldens/ActivityGeneratorTest_*", @@ -42,10 +42,9 @@ compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ - "//java/dagger/hilt/android:android_entry_point", "//java/dagger/hilt/android/testing/compile", "//java/dagger/internal/codegen/xprocessing", "//java/dagger/internal/codegen/xprocessing:xprocessing-testing", @@ -60,7 +59,7 @@ compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android:android_entry_point", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ "//java/dagger/hilt/android/testing/compile",
diff --git a/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD b/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD index a8d2cb9..47c9688 100644 --- a/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD +++ b/javatests/dagger/hilt/android/processor/internal/customtestapplication/BUILD
@@ -25,7 +25,7 @@ "//java/dagger/hilt/android/testing:custom_test_application", "//java/dagger/hilt/android/testing:hilt_android_test", "//java/dagger/hilt/android:hilt_android_app", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ "//java/dagger/hilt/android/testing/compile",
diff --git a/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD b/javatests/dagger/hilt/android/processor/internal/viewmodel/BUILD index eb73b3f..129a4fa 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:jvm.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"]) @@ -25,7 +25,7 @@ srcs = ["ViewModelProcessorTest.kt"], compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "//java/dagger/hilt/android/lifecycle:hilt_view_model", ], deps = [ @@ -44,7 +44,7 @@ "ViewModelValidationPluginTest.kt", ], compiler_deps = [ - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", "//third_party/java/compile_testing", @@ -76,7 +76,7 @@ "ViewModelValidationPluginWithAssistedInjectTest.kt", ], compiler_deps = [ - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_lifecycle_lifecycle_viewmodel", "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", "//third_party/java/compile_testing",
diff --git a/javatests/dagger/hilt/android/testsubpackage/BUILD b/javatests/dagger/hilt/android/testsubpackage/BUILD index 114c861..287a0ad 100644 --- a/javatests/dagger/hilt/android/testsubpackage/BUILD +++ b/javatests/dagger/hilt/android/testsubpackage/BUILD
@@ -34,6 +34,18 @@ ], ) +android_library( + name = "PackagePrivateConstructorTestClasses", + srcs = ["PackagePrivateConstructorTestClasses.java"], + deps = [ + "@maven//:androidx_activity_activity", + "@maven//:androidx_fragment_fragment", + "@maven//:androidx_lifecycle_lifecycle_common", + "@maven//:androidx_lifecycle_lifecycle_viewmodel", + "@maven//:androidx_lifecycle_lifecycle_viewmodel_savedstate", + ], +) + exports_files(srcs = [ "UsesLocalComponentTestBindingsTest.java", "UsesSharedComponent1Test.java",
diff --git a/javatests/dagger/hilt/android/testsubpackage/PackagePrivateConstructorTestClasses.java b/javatests/dagger/hilt/android/testsubpackage/PackagePrivateConstructorTestClasses.java new file mode 100644 index 0000000..a8ff381 --- /dev/null +++ b/javatests/dagger/hilt/android/testsubpackage/PackagePrivateConstructorTestClasses.java
@@ -0,0 +1,82 @@ +/* + * 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.testsubpackage; + +import android.app.IntentService; +import android.app.Service; +import android.content.BroadcastReceiver; +import android.content.Context; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +public final class PackagePrivateConstructorTestClasses { + + public abstract static class BaseActivity extends FragmentActivity { + public BaseActivity() {} + + BaseActivity(int unused) {} + } + + public abstract static class BaseFragment extends Fragment { + public BaseFragment() {} + + BaseFragment(int unused) {} + } + + public abstract static class BaseView extends LinearLayout { + public BaseView(Context context) { + super(context); + } + + public BaseView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public BaseView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + BaseView(Context context, int unused) { + super(context); + } + } + + public abstract static class BaseService extends Service { + public BaseService() {} + + BaseService(int unused) {} + } + + public abstract static class BaseIntentService extends IntentService { + public BaseIntentService(String name) { + super(name); + } + + BaseIntentService(String name, int unused) { + super(name); + } + } + + public abstract static class BaseBroadcastReceiver extends BroadcastReceiver { + public BaseBroadcastReceiver() {} + + BaseBroadcastReceiver(int unused) {} + } + +}
diff --git a/javatests/dagger/hilt/processor/internal/BUILD b/javatests/dagger/hilt/processor/internal/BUILD index 3dfe1ea..9cbf6a3 100644 --- a/javatests/dagger/hilt/processor/internal/BUILD +++ b/javatests/dagger/hilt/processor/internal/BUILD
@@ -15,6 +15,8 @@ # Description: # Tests for internal code for implementing Hilt processors. +load("@rules_java//java:defs.bzl", "java_library", "java_test") + package(default_visibility = ["//:src"]) java_test(
diff --git a/javatests/dagger/hilt/processor/internal/aggregateddeps/BUILD b/javatests/dagger/hilt/processor/internal/aggregateddeps/BUILD index 9ddf52a..1ad0176 100644 --- a/javatests/dagger/hilt/processor/internal/aggregateddeps/BUILD +++ b/javatests/dagger/hilt/processor/internal/aggregateddeps/BUILD
@@ -32,7 +32,7 @@ "//java/dagger/hilt:install_in", "//java/dagger/hilt/android/testing:hilt_android_test", "//java/dagger/hilt/android/components", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", ], deps = [ "//java/dagger/hilt/android/testing/compile",
diff --git a/javatests/dagger/hilt/processor/internal/aliasof/BUILD b/javatests/dagger/hilt/processor/internal/aliasof/BUILD index a56e140..da1fd37 100644 --- a/javatests/dagger/hilt/processor/internal/aliasof/BUILD +++ b/javatests/dagger/hilt/processor/internal/aliasof/BUILD
@@ -24,7 +24,7 @@ size = "small", srcs = ["AliasOfProcessorTest.java"], compiler_deps = [ - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "//third_party/java/jsr330_inject", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/components",
diff --git a/javatests/dagger/hilt/processor/internal/generatesrootinput/BUILD b/javatests/dagger/hilt/processor/internal/generatesrootinput/BUILD index ad919f5..c697141 100644 --- a/javatests/dagger/hilt/processor/internal/generatesrootinput/BUILD +++ b/javatests/dagger/hilt/processor/internal/generatesrootinput/BUILD
@@ -24,7 +24,7 @@ srcs = ["GeneratesRootInputProcessorTest.java"], compiler_deps = [ "//java/dagger/hilt:generates_root_input", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [
diff --git a/javatests/dagger/hilt/processor/internal/originatingelement/BUILD b/javatests/dagger/hilt/processor/internal/originatingelement/BUILD index 75f56ff..4a551f3 100644 --- a/javatests/dagger/hilt/processor/internal/originatingelement/BUILD +++ b/javatests/dagger/hilt/processor/internal/originatingelement/BUILD
@@ -24,7 +24,7 @@ srcs = ["OriginatingElementProcessorTest.java"], compiler_deps = [ "//java/dagger/hilt/codegen:originating_element", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [
diff --git a/javatests/dagger/hilt/processor/internal/root/BUILD b/javatests/dagger/hilt/processor/internal/root/BUILD index bdc69dc..35efea5 100644 --- a/javatests/dagger/hilt/processor/internal/root/BUILD +++ b/javatests/dagger/hilt/processor/internal/root/BUILD
@@ -34,7 +34,7 @@ ":MyAppPreviousCompilation", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -65,7 +65,7 @@ ":MyTestPreviousCompilation", "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -86,7 +86,7 @@ compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit", @@ -106,7 +106,7 @@ compiler_deps = [ "//java/dagger/hilt/android:hilt_android_app", "//java/dagger/hilt/android/testing:hilt_android_test", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", "@maven//:org_robolectric_robolectric", "@maven//:androidx_test_ext_junit",
diff --git a/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD b/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD index 50ffd2e..e1bd2fb 100644 --- a/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD +++ b/javatests/dagger/hilt/processor/internal/uninstallmodules/BUILD
@@ -27,7 +27,7 @@ "//java/dagger/hilt/android/testing:hilt_android_test", "//java/dagger/hilt/android/testing:uninstall_modules", "//java/dagger/hilt/migration:disable_install_in_check", - "@androidsdk//:platforms/android-32/android.jar", + "@androidsdk//:platforms/android-34/android.jar", "@maven//:androidx_annotation_annotation", ], deps = [
diff --git a/javatests/dagger/internal/codegen/BUILD b/javatests/dagger/internal/codegen/BUILD index b189fe5..42d07a6 100644 --- a/javatests/dagger/internal/codegen/BUILD +++ b/javatests/dagger/internal/codegen/BUILD
@@ -15,7 +15,8 @@ # Description: # Tests for the Dagger compiler/codegen -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_java//java:defs.bzl", "java_library") load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX") load("//:test_defs.bzl", "GenJavaTests") @@ -72,7 +73,7 @@ "//third_party/java/guava/collect", "//third_party/java/javapoet", "//third_party/java/truth", - "@com_google_auto_value_auto_value//jar", + "@maven//:com_google_auto_value_auto_value", ], ) @@ -110,7 +111,7 @@ "//third_party/java/guava/collect", "//third_party/java/guava/util/concurrent", "//third_party/java/auto:value", - "@com_google_auto_value_auto_value//jar", + "@maven//:com_google_auto_value_auto_value", "//third_party/java/auto:common", "//third_party/java/compile_testing", "//third_party/java/javapoet",
diff --git a/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java b/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java index 18cc734..a3a7ffa 100644 --- a/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java +++ b/javatests/dagger/internal/codegen/BindsInstanceValidationTest.java
@@ -187,4 +187,28 @@ }); } + @Test + public void bindsInstanceDaggerProvider() { + Source bindsDaggerProvider = + CompilerTests.javaSource( + "test.BindsInstanceFrameworkType", + "package test;", + "", + "import dagger.BindsInstance;", + "import dagger.internal.Provider;", + "import dagger.producers.Producer;", + "", + "interface BindsInstanceFrameworkType {", + " @BindsInstance void bindsProvider(Provider<Object> objectProvider);", + "}"); + CompilerTests.daggerCompiler(bindsDaggerProvider) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("@BindsInstance parameters must not be disallowed types") + .onSource(bindsDaggerProvider) + .onLine(8); + }); + } }
diff --git a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java b/javatests/dagger/internal/codegen/BindsMethodValidationTest.java index cb94f75..7806b22 100644 --- a/javatests/dagger/internal/codegen/BindsMethodValidationTest.java +++ b/javatests/dagger/internal/codegen/BindsMethodValidationTest.java
@@ -276,7 +276,6 @@ }); } - @Test public void bindsMissingTypeInReturnTypeHierarchy() { Source module = @@ -342,6 +341,107 @@ }); } + @Test + public void bindsNullableToNonNullable_fails() { + Source module = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Binds;", + "import dagger.Module;", + "import javax.annotation.Nullable;", + "", + "@Module", + "interface TestModule {", + " @Binds Object bind(@Nullable String str);", + "}"); + + CompilerTests.daggerCompiler(module) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "@Binds methods' nullability must match the nullability of its parameter"); + }); + } + + @Test + public void bindsNonNullableToNullable_fails() { + Source module = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Binds;", + "import dagger.Module;", + "import javax.annotation.Nullable;", + "", + "@Module", + "interface TestModule {", + " @Binds @Nullable Object bind(String str);", + "}"); + + CompilerTests.daggerCompiler(module) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "@Binds methods' nullability must match the nullability of its parameter"); + }); + } + + // This is a regression test for b/370367984. + @Test + public void bindsMapKVAndRequestMapKProviderV_failsWithMissingBindingError() { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "import dagger.Component;", + "import javax.inject.Provider;", + "import java.util.Map;", + "", + "@Component(modules = {TestModule.class})", + "interface TestComponent {", + " Map<K, Provider<V>> getMap();", + "}"); + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "import dagger.Binds;", + "import dagger.Module;", + "import dagger.Provides;", + "import java.util.Map;", + "", + "@Module", + "interface TestModule {", + " @Binds Map<K, V> bind(@TestQualifier Map<K, V> impl);", + "", + " @Provides", + " @TestQualifier", + " static Map<K, V> provideMap() {", + " return (Map<K, V>) null;", + " }", + "}"); + Source qualifier = + CompilerTests.javaSource( + "test.TestQualifier", + "package test;", + "import javax.inject.Qualifier;", + "", + "@Qualifier @interface TestQualifier {}"); + Source k = CompilerTests.javaSource("test.K", "package test;", "interface K {}"); + Source v = CompilerTests.javaSource("test.V", "package test;", "interface V {}"); + CompilerTests.daggerCompiler(component, module, qualifier, k, v) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("Map<test.K,Provider<test.V>> cannot be provided"); + }); + } + private DaggerModuleMethodSubject assertThatMethod(String method) { return assertThatModuleMethod(method).withDeclaration(moduleDeclaration); }
diff --git a/javatests/dagger/internal/codegen/CompilerMode.java b/javatests/dagger/internal/codegen/CompilerMode.java index 7f167d7..57a9455 100644 --- a/javatests/dagger/internal/codegen/CompilerMode.java +++ b/javatests/dagger/internal/codegen/CompilerMode.java
@@ -28,10 +28,7 @@ // TODO(bcorso): Consider moving the java version into its own separate enum. public enum CompilerMode { DEFAULT_MODE, - DEFAULT_JAVA7_MODE("-source", "7", "-target", "7"), - FAST_INIT_MODE("-Adagger.fastInit=enabled"), - FAST_INIT_JAVA7_MODE("-Adagger.fastInit=enabled", "-source", "7", "-target", "7"), - ; + FAST_INIT_MODE("-Adagger.fastInit=enabled"); /** Returns the compiler modes as a list of parameters for parameterized tests */ public static final ImmutableList<Object[]> TEST_PARAMETERS =
diff --git a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java b/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java index 65929e7..dfe74bb 100644 --- a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java +++ b/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java
@@ -33,6 +33,13 @@ return CompilerMode.TEST_PARAMETERS; } + private static final Source NON_TYPE_USE_NULLABLE = + CompilerTests.javaSource( + "test.Nullable", // force one-string-per-line format + "package test;", + "", + "public @interface Nullable {}"); + @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); private final CompilerMode compilerMode; @@ -74,6 +81,38 @@ } @Test + public void testBindsNullableInstance() throws Exception { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.BindsInstance;", + "import dagger.Component;", + "", + "@Component", + "interface TestComponent {", + " @Component.Factory", + " interface Factory {", + " TestComponent create(@BindsInstance @Nullable Bar arg);", + "}", + "}"); + Source bar = + CompilerTests.javaSource( + "test.Bar", // force one-string-per-line format + "package test;", + "", + "interface Bar {}"); + CompilerTests.daggerCompiler(component, bar, NON_TYPE_USE_NULLABLE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); + }); + } + + @Test public void instanceModuleMethod() throws Exception { Source module = CompilerTests.javaSource(
diff --git a/javatests/dagger/internal/codegen/DaggerSuperficialValidationTest.java b/javatests/dagger/internal/codegen/DaggerSuperficialValidationTest.java index 7092047..dffe701 100644 --- a/javatests/dagger/internal/codegen/DaggerSuperficialValidationTest.java +++ b/javatests/dagger/internal/codegen/DaggerSuperficialValidationTest.java
@@ -124,8 +124,17 @@ assertThrows( ValidationException.KnownErrorType.class, () -> superficialValidation.validateElement(testClassElement)); - // TODO(b/248552462): Javac and KSP should match once this bug is fixed. - boolean isJavac = processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC; + final String errorType; + if (processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC) { + // JDK 24 improves error type information. + errorType = + Runtime.version().feature() >= 24 + ? isKAPT(processingEnv) ? "MissingType" : "MissingType<?>" + : "<any>"; + } else { + // TODO(b/248552462): Javac and KSP should match once this bug is fixed. + errorType = "error.NonExistentClass"; + } assertThat(exception) .hasMessageThat() .contains( @@ -135,7 +144,7 @@ " => element (CLASS): test.TestClass", " => element (METHOD): blah()", " => type (ERROR return type): %1$s"), - isJavac ? "<any>" : "error.NonExistentClass")); + errorType)); }); } @@ -165,8 +174,14 @@ assertThrows( ValidationException.KnownErrorType.class, () -> superficialValidation.validateElement(testClassElement)); - // TODO(b/248552462): Javac and KSP should match once this bug is fixed. - boolean isJavac = processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC; + final String errorType; + if (processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC) { + // JDK 24 improves error type information. + errorType = Runtime.version().feature() >= 24 ? "MissingType<?>" : "<any>"; + } else { + // TODO(b/248552462): Javac and KSP should match once this bug is fixed. + errorType = "error.NonExistentClass"; + } assertThat(exception) .hasMessageThat() .contains( @@ -178,7 +193,7 @@ " => type (DECLARED return type): " + "java.util.Map<java.util.Set<?>,%1$s>", " => type (ERROR type argument): %1$s"), - isJavac ? "<any>" : "error.NonExistentClass")); + errorType)); }); } @@ -197,7 +212,7 @@ "class TestClass<T : MissingType>"), (processingEnv, superficialValidation) -> { if (isKAPT(processingEnv)) { - // TODO(b/268536260): Figure out why XProcessing Testing infra fails when using KAPT. + // The KAPT java stub doesn't reference the MissingType symbol (b/268536260#comment2). return; } XTypeElement testClassElement = processingEnv.findTypeElement("test.TestClass"); @@ -402,7 +417,7 @@ "class TestClass<T> where T: Number, T: Missing"), (processingEnv, superficialValidation) -> { if (isKAPT(processingEnv)) { - // TODO(b/268536260): Figure out why XProcessing Testing infra fails when using KAPT. + // The KAPT java stub doesn't reference the MissingType symbol (b/268536260#comment2). return; } XTypeElement testClassElement = processingEnv.findTypeElement("test.TestClass"); @@ -454,31 +469,29 @@ "}"), (processingEnv, superficialValidation) -> { XTypeElement testClassElement = processingEnv.findTypeElement("test.Outer.TestClass"); - if (processingEnv.getBackend() == XProcessingEnv.Backend.KSP - && sourceKind == SourceKind.KOTLIN) { - // TODO(b/269364338): When using kotlin source with KSP the MissingType annotation value - // appears to be missing so validating this element does not cause the expected failure. - superficialValidation.validateElement(testClassElement); - return; - } ValidationException exception = assertThrows( ValidationException.KnownErrorType.class, () -> superficialValidation.validateElement(testClassElement)); // TODO(b/248552462): Javac and KSP should match once this bug is fixed. boolean isJavac = processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC; - assertThat(exception) - .hasMessageThat() - .contains( - String.format( - NEW_LINES.join( - "Validation trace:", - " => element (CLASS): test.Outer.TestClass", - " => annotation type: test.Outer.TestAnnotation", - " => annotation: @test.Outer.TestAnnotation(classes={<%1$s>})", - " => annotation value (TYPE_ARRAY): classes={<%1$s>}", - " => annotation value (TYPE): classes=<%1$s>"), - isJavac ? "error" : "Error")); + String expectedMessage = + String.format( + NEW_LINES.join( + "Validation trace:", + " => element (CLASS): test.Outer.TestClass", + " => annotation type: test.Outer.TestAnnotation", + " => annotation: @test.Outer.TestAnnotation(classes={<%1$s>})", + " => annotation value (TYPE_ARRAY): classes={<%1$s>}", + " => annotation value (TYPE): classes=<%1$s>"), + isJavac ? "error" : "ERROR TYPE: MissingType"); + if (!isJavac) { + expectedMessage = + NEW_LINES.join( + expectedMessage, + " => type (ERROR annotation value type): error.NonExistentClass"); + } + assertThat(exception).hasMessageThat().contains(expectedMessage); }); } @@ -512,10 +525,8 @@ " )", "}"), (processingEnv, superficialValidation) -> { - if (sourceKind == SourceKind.KOTLIN) { - // TODO(b/268536260): Figure out why XProcessing Testing infra fails when using KAPT. - // TODO(b/269364338): When using kotlin source the MissingType annotation value appears - // to be missing so validating this element does not cause the expected failure. + if (isKAPT(processingEnv)) { + // The KAPT java stub doesn't reference the MissingType symbol (b/268536260#comment2). return; } XTypeElement testClassElement = processingEnv.findTypeElement("test.Outer.TestClass"); @@ -527,20 +538,25 @@ () -> superficialValidation.validateElement(parameter)); // TODO(b/248552462): Javac and KSP should match once this bug is fixed. boolean isJavac = processingEnv.getBackend() == XProcessingEnv.Backend.JAVAC; - assertThat(exception) - .hasMessageThat() - .contains( - String.format( - NEW_LINES.join( - "Validation trace:", - " => element (CLASS): test.Outer.TestClass", - " => element (CONSTRUCTOR): TestClass(java.lang.String)", - " => element (PARAMETER): strParam", - " => annotation type: test.Outer.TestAnnotation", - " => annotation: @test.Outer.TestAnnotation(classes={<%1$s>})", - " => annotation value (TYPE_ARRAY): classes={<%1$s>}", - " => annotation value (TYPE): classes=<%1$s>"), - isJavac ? "error" : "Error")); + String expectedMessage = + String.format( + NEW_LINES.join( + "Validation trace:", + " => element (CLASS): test.Outer.TestClass", + " => element (CONSTRUCTOR): TestClass(java.lang.String)", + " => element (PARAMETER): strParam", + " => annotation type: test.Outer.TestAnnotation", + " => annotation: @test.Outer.TestAnnotation(classes={<%1$s>})", + " => annotation value (TYPE_ARRAY): classes={<%1$s>}", + " => annotation value (TYPE): classes=<%1$s>"), + isJavac ? "error" : "ERROR TYPE: MissingType"); + if (!isJavac) { + expectedMessage = + NEW_LINES.join( + expectedMessage, + " => type (ERROR annotation value type): error.NonExistentClass"); + } + assertThat(exception).hasMessageThat().contains(expectedMessage); }); }
diff --git a/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java b/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java index e759bdc..7332351 100644 --- a/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java +++ b/javatests/dagger/internal/codegen/DependencyCycleValidationTest.java
@@ -16,15 +16,10 @@ package dagger.internal.codegen; -import static com.google.testing.compile.CompilationSubject.assertThat; -import static dagger.internal.codegen.Compilers.compilerWithOptions; -import static dagger.internal.codegen.TestUtils.endsWithMessage; - import androidx.room.compiler.processing.util.Source; import com.google.common.collect.ImmutableList; -import com.google.testing.compile.Compilation; +import com.google.common.collect.ImmutableMap; import dagger.testing.compile.CompilerTests; -import java.util.regex.Pattern; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; @@ -90,66 +85,87 @@ "\n", "Found a dependency cycle:", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.CComponent] Outer.A(cParam)", " Outer.A is injected at", - " Outer.B(aParam)", + " [Outer.CComponent] Outer.B(aParam)", " Outer.B is injected at", - " Outer.C(bParam)", + " [Outer.CComponent] Outer.C(bParam)", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.CComponent] Outer.A(cParam)", " ...", "", "The cycle is requested via:", " Outer.C is requested at", - " Outer.CComponent.getC()")) + " [Outer.CComponent] Outer.CComponent.getC()")) .onSource(SIMPLE_CYCLIC_DEPENDENCY) .onLineContaining("interface CComponent"); }); } - // TODO(b/243720787): Requires CompilationResultSubject#hasErrorContainingMatch() @Test public void cyclicDependencyWithModuleBindingValidation() { // Cycle errors should not show a dependency trace to an entry point when doing full binding // graph validation. So ensure that the message doesn't end with "test.Outer.C is requested at // test.Outer.CComponent.getC()", as the previous test's message does. - Pattern moduleBindingValidationError = - endsWithMessage( - "Found a dependency cycle:", - " Outer.C is injected at", - " Outer.A(cParam)", - " Outer.A is injected at", - " Outer.B(aParam)", - " Outer.B is injected at", - " Outer.C(bParam)", - " Outer.C is injected at", - " Outer.A(cParam)", - " ...", - "", - "======================", - "Full classname legend:", - "======================", - "Outer: test.Outer", - "========================", - "End of classname legend:", - "========================"); + CompilerTests.daggerCompiler(SIMPLE_CYCLIC_DEPENDENCY) + .withProcessingOptions( + ImmutableMap.<String, String>builder() + .put("dagger.fullBindingGraphValidation", "ERROR") + .putAll(compilerMode.processorOptions()) + .buildOrThrow()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject + .hasErrorContaining( + String.join( + "\n", + "Found a dependency cycle:", + " Outer.C is injected at", + " [Outer.MModule] Outer.A(cParam)", + " Outer.A is injected at", + " [Outer.MModule] Outer.B(aParam)", + " Outer.B is injected at", + " [Outer.MModule] Outer.C(bParam)", + " Outer.C is injected at", + " [Outer.MModule] Outer.A(cParam)", + " ...", + "", + "======================", + "Full classname legend:", + "======================", + "Outer: test.Outer", + "========================", + "End of classname legend:", + "========================")) + .onSource(SIMPLE_CYCLIC_DEPENDENCY) + .onLineContaining("interface MModule"); - Compilation compilation = - compilerWithOptions("-Adagger.fullBindingGraphValidation=ERROR") - .compile(SIMPLE_CYCLIC_DEPENDENCY.toJFO()); - assertThat(compilation).failed(); - - assertThat(compilation) - .hadErrorContainingMatch(moduleBindingValidationError) - .inFile(SIMPLE_CYCLIC_DEPENDENCY.toJFO()) - .onLineContaining("interface MModule"); - - assertThat(compilation) - .hadErrorContainingMatch(moduleBindingValidationError) - .inFile(SIMPLE_CYCLIC_DEPENDENCY.toJFO()) - .onLineContaining("interface CComponent"); - - assertThat(compilation).hadErrorCount(2); + subject + .hasErrorContaining( + String.join( + "\n", + "Found a dependency cycle:", + " Outer.C is injected at", + " [Outer.CComponent] Outer.A(cParam)", + " Outer.A is injected at", + " [Outer.CComponent] Outer.B(aParam)", + " Outer.B is injected at", + " [Outer.CComponent] Outer.C(bParam)", + " Outer.C is injected at", + " [Outer.CComponent] Outer.A(cParam)", + " ...", + "", + "======================", + "Full classname legend:", + "======================", + "Outer: test.Outer", + "========================", + "End of classname legend:", + "========================")) + .onSource(SIMPLE_CYCLIC_DEPENDENCY) + .onLineContaining("interface CComponent"); + }); } @Test public void cyclicDependencyNotIncludingEntryPoint() { @@ -196,20 +212,20 @@ "\n", "Found a dependency cycle:", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.DComponent] Outer.A(cParam)", " Outer.A is injected at", - " Outer.B(aParam)", + " [Outer.DComponent] Outer.B(aParam)", " Outer.B is injected at", - " Outer.C(bParam)", + " [Outer.DComponent] Outer.C(bParam)", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.DComponent] Outer.A(cParam)", " ...", "", "The cycle is requested via:", " Outer.C is injected at", - " Outer.D(cParam)", + " [Outer.DComponent] Outer.D(cParam)", " Outer.D is requested at", - " Outer.DComponent.getD()")) + " [Outer.DComponent] Outer.DComponent.getD()")) .onSource(component) .onLineContaining("interface DComponent"); }); @@ -268,20 +284,20 @@ "\n", "Found a dependency cycle:", " Outer.C is injected at", - " Outer.CModule.c(c)", + " [Outer.CComponent] Outer.CModule.c(c)", " Map<String,Outer.C> is injected at", - " Outer.A(cMap)", + " [Outer.CComponent] Outer.A(cMap)", " Outer.A is injected at", - " Outer.B(aParam)", + " [Outer.CComponent] Outer.B(aParam)", " Outer.B is injected at", - " Outer.C(bParam)", + " [Outer.CComponent] Outer.C(bParam)", " Outer.C is injected at", - " Outer.CModule.c(c)", + " [Outer.CComponent] Outer.CModule.c(c)", " ...", "", "The cycle is requested via:", " Outer.C is requested at", - " Outer.CComponent.getC()")) + " [Outer.CComponent] Outer.CComponent.getC()")) .onSource(component) .onLineContaining("interface CComponent"); }); @@ -338,20 +354,20 @@ "\n", "Found a dependency cycle:", " Outer.C is injected at", - " Outer.CModule.c(c)", + " [Outer.CComponent] Outer.CModule.c(c)", " Set<Outer.C> is injected at", - " Outer.A(cSet)", + " [Outer.CComponent] Outer.A(cSet)", " Outer.A is injected at", - " Outer.B(aParam)", + " [Outer.CComponent] Outer.B(aParam)", " Outer.B is injected at", - " Outer.C(bParam)", + " [Outer.CComponent] Outer.C(bParam)", " Outer.C is injected at", - " Outer.CModule.c(c)", + " [Outer.CComponent] Outer.CModule.c(c)", " ...", "", "The cycle is requested via:", " Outer.C is requested at", - " Outer.CComponent.getC()")) + " [Outer.CComponent] Outer.CComponent.getC()")) .onSource(component) .onLineContaining("interface CComponent"); }); @@ -403,20 +419,20 @@ "\n", "Found a dependency cycle:", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.DComponent] Outer.A(cParam)", " Outer.A is injected at", - " Outer.B(aParam)", + " [Outer.DComponent] Outer.B(aParam)", " Outer.B is injected at", - " Outer.C(bParam)", + " [Outer.DComponent] Outer.C(bParam)", " Outer.C is injected at", - " Outer.A(cParam)", + " [Outer.DComponent] Outer.A(cParam)", " ...", "", "The cycle is requested via:", " Provider<Outer.C> is injected at", - " Outer.D(cParam)", + " [Outer.DComponent] Outer.D(cParam)", " Outer.D is requested at", - " Outer.DComponent.getD()")) + " [Outer.DComponent] Outer.DComponent.getD()")) .onSource(component) .onLineContaining("interface DComponent"); }); @@ -496,16 +512,16 @@ "\n", "Found a dependency cycle:", " String is injected at", - " CycleModule.object(string)", + " [Child] CycleModule.object(string)", " Object is injected at", - " CycleModule.string(object)", + " [Child] CycleModule.string(object)", " String is injected at", - " CycleModule.object(string)", + " [Child] CycleModule.object(string)", " ...", "", "The cycle is requested via:", " String is requested at", - " Grandchild.entry()")) + " [Grandchild] Grandchild.entry()")) .onSource(parent) .onLineContaining("interface Parent"); }); @@ -587,16 +603,16 @@ "\n", "Found a dependency cycle:", " String is injected at", - " CycleModule.object(string)", + " [Child] CycleModule.object(string)", " Object is injected at", - " CycleModule.string(object)", + " [Child] CycleModule.string(object)", " String is injected at", - " CycleModule.object(string)", + " [Child] CycleModule.object(string)", " ...", "", "The cycle is requested via:", " String is requested at", - " Child.entry() [Parent → Child]")) + " [Child] Child.entry() [Parent → Child]")) .onSource(parent) .onLineContaining("interface Parent"); }); @@ -647,16 +663,16 @@ "\n", "Found a dependency cycle:", " Object is injected at", - " TestModule.bindQualified(unqualified)", + " [TestComponent] TestModule.bindQualified(unqualified)", " @SomeQualifier Object is injected at", - " TestModule.bindUnqualified(qualified)", + " [TestComponent] TestModule.bindUnqualified(qualified)", " Object is injected at", - " TestModule.bindQualified(unqualified)", + " [TestComponent] TestModule.bindQualified(unqualified)", " ...", "", "The cycle is requested via:", " Object is requested at", - " TestComponent.unqualified()")) + " [TestComponent] TestComponent.unqualified()")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -698,14 +714,14 @@ "\n", "Found a dependency cycle:", " Object is injected at", - " TestModule.bindToSelf(sameKey)", + " [TestComponent] TestModule.bindToSelf(sameKey)", " Object is injected at", - " TestModule.bindToSelf(sameKey)", + " [TestComponent] TestModule.bindToSelf(sameKey)", " ...", "", "The cycle is requested via:", " Object is requested at", - " TestComponent.selfReferential()")) + " [TestComponent] TestComponent.selfReferential()")) .onSource(component) .onLineContaining("interface TestComponent"); }); @@ -757,18 +773,18 @@ "\n", "Found a dependency cycle:", " test.B is injected at", - " test.A.b", + " [CycleComponent] test.A.b", " test.A is injected at", - " test.B.a", + " [CycleComponent] test.B.a", " test.B is injected at", - " test.A.b", + " [CycleComponent] test.A.b", " ...", "", "The cycle is requested via:", " test.B is injected at", - " test.A.b", + " [CycleComponent] test.A.b", " test.A is injected at", - " CycleComponent.inject(test.A)")) + " [CycleComponent] CycleComponent.inject(test.A)")) .onSource(component) .onLineContaining("interface CycleComponent"); });
diff --git a/javatests/dagger/internal/codegen/FrameworkFieldTest.java b/javatests/dagger/internal/codegen/FrameworkFieldTest.java index ba5b88f..2592c35 100644 --- a/javatests/dagger/internal/codegen/FrameworkFieldTest.java +++ b/javatests/dagger/internal/codegen/FrameworkFieldTest.java
@@ -17,16 +17,19 @@ package dagger.internal.codegen; import static com.google.common.truth.Truth.assertThat; -import static dagger.internal.codegen.javapoet.TypeNames.MEMBERS_INJECTOR; -import static dagger.internal.codegen.javapoet.TypeNames.PROVIDER; -import static dagger.internal.codegen.javapoet.TypeNames.membersInjectorOf; -import static dagger.internal.codegen.javapoet.TypeNames.providerOf; +import static dagger.internal.codegen.xprocessing.XTypeNames.MEMBERS_INJECTOR; +import static dagger.internal.codegen.xprocessing.XTypeNames.PROVIDER; +import static dagger.internal.codegen.xprocessing.XTypeNames.membersInjectorOf; +import static dagger.internal.codegen.xprocessing.XTypeNames.providerOf; +import androidx.room.compiler.processing.XProcessingEnv; +import androidx.room.compiler.processing.XType; import com.google.testing.compile.CompilationRule; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.ParameterizedTypeName; +import dagger.Component; import dagger.internal.codegen.binding.FrameworkField; +import dagger.internal.codegen.javac.JavacPluginModule; import javax.inject.Inject; +import javax.inject.Singleton; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -40,32 +43,40 @@ public class FrameworkFieldTest { @Rule public CompilationRule compilationRule = new CompilationRule(); - private ClassName xTypeName; + @Inject XProcessingEnv processingEnv; - @Before public void setUp() { - xTypeName = - ClassName.get(compilationRule.getElements().getTypeElement(X.class.getCanonicalName())); + private XType type; + + @Before + public void setUp() { + DaggerFrameworkFieldTest_TestComponent.builder() + .javacPluginModule( + new JavacPluginModule(compilationRule.getElements(), compilationRule.getTypes())) + .build() + .inject(this); + type = processingEnv.requireType(X.class.getCanonicalName()); } @Test public void frameworkType() { - assertThat(FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "test").type()) - .isEqualTo(providerOf(xTypeName)); - assertThat( - FrameworkField.create(ParameterizedTypeName.get(MEMBERS_INJECTOR, xTypeName), "test") - .type()) - .isEqualTo(membersInjectorOf(xTypeName)); + assertThat(FrameworkField.create("test", PROVIDER, type).type()) + .isEqualTo(providerOf(type.asTypeName())); + assertThat(FrameworkField.create("test", MEMBERS_INJECTOR, type).type()) + .isEqualTo(membersInjectorOf(type.asTypeName())); } @Test public void nameSuffix() { - assertThat(FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "foo").name()) - .isEqualTo("fooProvider"); - assertThat( - FrameworkField.create(ParameterizedTypeName.get(PROVIDER, xTypeName), "fooProvider") - .name()) + assertThat(FrameworkField.create("foo", PROVIDER, type).name()).isEqualTo("fooProvider"); + assertThat(FrameworkField.create("fooProvider", PROVIDER, type).name()) .isEqualTo("fooProvider"); } static final class X { @Inject X() {} } -} + + @Singleton + @Component(modules = JavacPluginModule.class) + interface TestComponent { + void inject(FrameworkFieldTest test); + } +} \ No newline at end of file
diff --git a/javatests/dagger/internal/codegen/GeneratedLines.java b/javatests/dagger/internal/codegen/GeneratedLines.java index d8a0388..f75fca8 100644 --- a/javatests/dagger/internal/codegen/GeneratedLines.java +++ b/javatests/dagger/internal/codegen/GeneratedLines.java
@@ -33,7 +33,9 @@ private static final String SUPPRESS_WARNINGS_ANNOTATION = "@SuppressWarnings({" - + "\"unchecked\", \"rawtypes\", \"KotlinInternal\", \"KotlinInternalInJava\", \"cast\"" + + "\"unchecked\", \"rawtypes\", \"KotlinInternal\", \"KotlinInternalInJava\", \"cast\", " + + "\"deprecation\"," + + "\"nullness:initialization.field.uninitialized\"" + "})"; private static final String IMPORT_DAGGER_GENERATED = "import dagger.internal.DaggerGenerated;";
diff --git a/javatests/dagger/internal/codegen/InaccessibleTypeBindsTest.java b/javatests/dagger/internal/codegen/InaccessibleTypeBindsTest.java index f4eda9c..8d2f728 100644 --- a/javatests/dagger/internal/codegen/InaccessibleTypeBindsTest.java +++ b/javatests/dagger/internal/codegen/InaccessibleTypeBindsTest.java
@@ -23,7 +23,6 @@ import com.google.testing.compile.Compilation; import com.google.testing.compile.JavaFileObjects; import dagger.testing.golden.GoldenFileRule; -import java.util.Collection; import javax.tools.JavaFileObject; import org.junit.Rule; import org.junit.Test; @@ -34,16 +33,8 @@ @RunWith(Parameterized.class) public class InaccessibleTypeBindsTest { @Parameters(name = "{0}") - public static Collection<Object[]> parameters() { - return ImmutableList.copyOf( - new Object[][] { - {CompilerMode.DEFAULT_MODE}, - {CompilerMode.DEFAULT_JAVA7_MODE}, - {CompilerMode.FAST_INIT_MODE}, - // FastInit with Java7 is the mode that motivated this test, but do the other - // modes anyway for completeness. - {CompilerMode.FAST_INIT_JAVA7_MODE} - }); + public static ImmutableList<Object[]> parameters() { + return CompilerMode.TEST_PARAMETERS; } @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
diff --git a/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java b/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java index 9937d05..444040a 100644 --- a/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/LazyClassKeyMapBindingComponentProcessorTest.java
@@ -16,13 +16,19 @@ package dagger.internal.codegen; +import static com.google.common.truth.Truth.assertThat; import static com.google.testing.compile.CompilationSubject.assertThat; +import static java.nio.charset.StandardCharsets.UTF_8; import androidx.room.compiler.processing.util.Source; +import com.google.common.truth.PrimitiveByteArraySubject; +import com.google.common.truth.StringSubject; +import com.google.common.truth.Subject; import com.google.testing.compile.Compilation; import com.google.testing.compile.JavaFileObjects; import dagger.testing.compile.CompilerTests; import dagger.testing.golden.GoldenFileRule; +import java.lang.reflect.Method; import java.util.Collection; import javax.tools.JavaFileObject; import org.junit.Rule; @@ -186,6 +192,303 @@ "}"); CompilerTests.daggerCompiler(fooBar, fooBar2, mapKeyBindingsModule, componentFile) .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); + }); + } + + @Test + public void lazyClassKeyProvider_compilesSuccessfully() 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; }", + "}"); + + Source componentFile = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import javax.inject.Provider;", + "import java.util.Map;", + "", + "@Component(modules = MapKeyBindingsModule.class)", + "interface TestComponent {", + " Map<Class<?>, Provider<Integer>> classKey();", + "}"); + CompilerTests.daggerCompiler(fooBar, fooBar2, mapKeyBindingsModule, componentFile) + .withProcessingOptions(compilerMode.processorOptions()) .compile(subject -> subject.hasErrorCount(0)); } + + @Test + public void scopedLazyClassKeyProvider_compilesSuccessfully() 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; }", + "}"); + + Source componentFile = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.Component;", + "import javax.inject.Singleton;", + "import javax.inject.Provider;", + "import java.util.Map;", + "", + "@Component(modules = MapKeyBindingsModule.class)", + "@Singleton", + "interface TestComponent {", + " Provider<Map<Class<?>, Provider<Integer>>> classKey();", + "}"); + CompilerTests.daggerCompiler(fooBar, fooBar2, mapKeyBindingsModule, componentFile) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } + + @Test + public void testProguardFile() throws Exception { + Source fooKey = + CompilerTests.javaSource( + "test.FooKey", + "package test;", + "", + "interface FooKey {}"); + Source fooKeyModule = + CompilerTests.javaSource( + "test.FooKeyModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "@Module", + "public interface FooKeyModule {", + " @Provides", + " @IntoMap", + " @LazyClassKey(FooKey.class)", + " static String provideString() { return \"\"; }", + "}"); + CompilerTests.daggerCompiler(fooKey, fooKeyModule) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + PrimitiveByteArraySubject proguardFile = + subject.generatedResourceFileWithPath( + "META-INF/proguard/test_FooKeyModule_LazyClassKeys.pro"); + assertThatContentAsUtf8String(proguardFile) + .isEqualTo("-keep,allowobfuscation,allowshrinking class test.FooKey"); + }); + } + + @Test + public void testProguardFile_nestedModule() throws Exception { + Source fooKey = + CompilerTests.javaSource( + "test.FooKey", + "package test;", + "", + "interface FooKey {}"); + Source outerClass = + CompilerTests.javaSource( + "test.OuterClass", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "public interface OuterClass {", + " @Module", + " public interface FooKeyModule {", + " @Provides", + " @IntoMap", + " @LazyClassKey(FooKey.class)", + " static String provideString() { return \"\"; }", + " }", + "}"); + CompilerTests.daggerCompiler(fooKey, outerClass) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + PrimitiveByteArraySubject proguardFile = + subject.generatedResourceFileWithPath( + "META-INF/proguard/test_OuterClass_FooKeyModule_LazyClassKeys.pro"); + assertThatContentAsUtf8String(proguardFile) + .isEqualTo("-keep,allowobfuscation,allowshrinking class test.FooKey"); + }); + } + + @Test + public void testProguardFile_multipleModules() throws Exception { + Source fooKey = + CompilerTests.javaSource( + "test.FooKey", + "package test;", + "", + "interface FooKey {}"); + Source barKey = + CompilerTests.javaSource( + "test.BarKey", + "package test;", + "", + "interface BarKey {}"); + Source fooKeyModule = + CompilerTests.javaSource( + "test.FooKeyModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "@Module", + "public interface FooKeyModule {", + " @Provides", + " @IntoMap", + " @LazyClassKey(FooKey.class)", + " static String provideString() { return \"\"; }", + "}"); + Source barKeyModule = + CompilerTests.javaSource( + "test.BarKeyModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "@Module", + "public interface BarKeyModule {", + " @Provides", + " @IntoMap", + " @LazyClassKey(BarKey.class)", + " static String provideString() { return \"\"; }", + "}"); + CompilerTests.daggerCompiler(fooKey, fooKeyModule, barKey, barKeyModule) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + PrimitiveByteArraySubject fooKeyModuleProguardFile = + subject.generatedResourceFileWithPath( + "META-INF/proguard/test_FooKeyModule_LazyClassKeys.pro"); + assertThatContentAsUtf8String(fooKeyModuleProguardFile) + .isEqualTo("-keep,allowobfuscation,allowshrinking class test.FooKey"); + + PrimitiveByteArraySubject barKeyModuleProguardFile = + subject.generatedResourceFileWithPath( + "META-INF/proguard/test_BarKeyModule_LazyClassKeys.pro"); + assertThatContentAsUtf8String(barKeyModuleProguardFile) + .isEqualTo("-keep,allowobfuscation,allowshrinking class test.BarKey"); + }); + } + + @Test + public void testProguardFile_multipleKeys() throws Exception { + Source fooKey = + CompilerTests.javaSource( + "test.FooKey", + "package test;", + "", + "interface FooKey {}"); + Source barKey = + CompilerTests.javaSource( + "test.BarKey", + "package test;", + "", + "interface BarKey {}"); + Source fooKeyAndBarKeyModule = + CompilerTests.javaSource( + "test.FooKeyAndBarKeyModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.LazyClassKey;", + "import dagger.multibindings.IntoMap;", + "", + "@Module", + "public interface FooKeyAndBarKeyModule {", + " @Provides", + " @IntoMap", + " @LazyClassKey(FooKey.class)", + " static String provideFooKeyString() { return \"\"; }", + "", + " @Provides", + " @IntoMap", + " @LazyClassKey(BarKey.class)", + " static String provideBarKeyString() { return \"\"; }", + "}"); + CompilerTests.daggerCompiler(fooKey, barKey, fooKeyAndBarKeyModule) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + PrimitiveByteArraySubject proguardFile = + subject.generatedResourceFileWithPath( + "META-INF/proguard/test_FooKeyAndBarKeyModule_LazyClassKeys.pro"); + assertThatContentAsUtf8String(proguardFile) + .isEqualTo( + "-keep,allowobfuscation,allowshrinking class test.FooKey\n" + + "-keep,allowobfuscation,allowshrinking class test.BarKey"); + }); + } + + // TODO(b/386213524): Add support for getting a resource file as a StringSubject. + // Use reflection to get the subject's byte array and then convert it to a StringSubject. + private static StringSubject assertThatContentAsUtf8String(PrimitiveByteArraySubject subject) { + try { + Method protectedActualMethod = Subject.class.getDeclaredMethod("actual"); + protectedActualMethod.setAccessible(true); + byte[] actualBytes = (byte[]) protectedActualMethod.invoke(subject); + return assertThat(new String(actualBytes, UTF_8)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } }
diff --git a/javatests/dagger/internal/codegen/MapKeyProcessorTest.java b/javatests/dagger/internal/codegen/MapKeyProcessorTest.java index 85f5a5c..c1914c1 100644 --- a/javatests/dagger/internal/codegen/MapKeyProcessorTest.java +++ b/javatests/dagger/internal/codegen/MapKeyProcessorTest.java
@@ -137,4 +137,67 @@ .and() .generatesSources(generatedKeyCreator); } + + @Test + public void nestedComplexMapKey_buildSuccessfully() { + JavaFileObject outerKey = + JavaFileObjects.forSourceLines( + "test.OuterKey", + "package test;", + "import dagger.MapKey;", + "import java.lang.annotation.Retention;", + "import static java.lang.annotation.RetentionPolicy.RUNTIME;", + "", + "@MapKey(unwrapValue = false)", + "public @interface OuterKey {", + " String value() default \"hello\";", + " NestedKey[] nestedKeys() default {};", + "}"); + JavaFileObject nestedKey = + JavaFileObjects.forSourceLines( + "test.NestedKey", + "package test;", + "import dagger.MapKey;", + "import java.lang.annotation.Retention;", + "import static java.lang.annotation.RetentionPolicy.RUNTIME;", + "", + "@MapKey(unwrapValue = false)", + "public @interface NestedKey {", + " String value() default \"hello\";", + " String otherValue() default \"world\";", + "}"); + JavaFileObject foo = + JavaFileObjects.forSourceLines( + "test.FooModule", + "package test;", + "", + "import dagger.multibindings.IntoMap;", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "public final class FooModule {", + " @IntoMap", + " @OuterKey(nestedKeys = @NestedKey)", + " @Provides", + " String provideString() { return \"hello\";}", + "}"); + JavaFileObject component = + JavaFileObjects.forSourceLines( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Map;", + "", + "@Component(modules = FooModule.class)", + "public interface MyComponent {", + " Map<OuterKey, String> getFoo();", + "}"); + assertAbout(javaSources()) + .that(ImmutableList.of(outerKey, nestedKey, foo, component)) + .withCompilerOptions(compilerMode.javacopts()) + .processedWith(new ComponentProcessor(), new AutoAnnotationProcessor()) + .compilesWithoutError(); + } }
diff --git a/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java b/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java index 68564b2..6b9c526 100644 --- a/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java +++ b/javatests/dagger/internal/codegen/MapMultibindingValidationTest.java
@@ -88,7 +88,7 @@ subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "The same map key is bound more than once for Map<String,Provider<Object>>") + "The same map key is bound more than once for Map<String,Object>") .onSource(module) .onLineContaining("class MapModule"); subject.hasErrorContaining("provideObjectForAKey()"); @@ -285,7 +285,7 @@ subject -> { subject.hasErrorCount(1); subject.hasErrorContaining( - "Map<String,Provider<Object>> uses more than one @MapKey annotation type") + "Map<String,Object> uses more than one @MapKey annotation type") .onSource(module) .onLineContaining("class MapModule"); subject.hasErrorContaining("provideObjectForAKey()"); @@ -374,6 +374,84 @@ }); } + @Test + public void mapBindingOfProvider_provides() { + Source providesModule = + CompilerTests.javaSource( + "test.MapModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.IntoMap;", + "import dagger.multibindings.StringKey;", + "import javax.inject.Provider;", + "", + "@Module", + "abstract class MapModule {", + "", + " @Provides", + " @IntoMap", + " @StringKey(\"foo\")", + " static Provider<String> provideProvider() {", + " return null;", + " }", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source providesComponent = component(""); + + CompilerTests.daggerCompiler(providesModule, providesComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Provides methods with @IntoMap must not return framework types"); + subject.hasErrorContaining("test.MapModule has errors") + .onSource(providesComponent) + .onLineContaining("@Component(modules = {MapModule.class})"); + }); + } + + @Test + public void mapBindingOfProvider_binds() { + Source bindsModule = + CompilerTests.javaSource( + "test.MapModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Binds;", + "import dagger.multibindings.IntoMap;", + "import dagger.multibindings.StringKey;", + "import javax.inject.Provider;", + "", + "@Module", + "abstract class MapModule {", + "", + " @Binds", + " @IntoMap", + " @StringKey(\"foo\")", + " abstract Provider<String> provideProvider(Provider<String> provider);", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source bindsComponent = component(""); + + CompilerTests.daggerCompiler(bindsModule, bindsComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Binds methods with @IntoMap must not return framework types"); + subject.hasErrorContaining("test.MapModule has errors") + .onSource(bindsComponent) + .onLineContaining("@Component(modules = {MapModule.class})"); + }); + } + private static Source component(String... entryPoints) { return CompilerTests.javaSource( "test.TestComponent",
diff --git a/javatests/dagger/internal/codegen/MembersInjectionTest.java b/javatests/dagger/internal/codegen/MembersInjectionTest.java index 4748853..ee02f9f 100644 --- a/javatests/dagger/internal/codegen/MembersInjectionTest.java +++ b/javatests/dagger/internal/codegen/MembersInjectionTest.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen; +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; @@ -32,6 +33,23 @@ @RunWith(Parameterized.class) public class MembersInjectionTest { + + private static final Source TYPE_USE_NULLABLE = + CompilerTests.javaSource( + "test.Nullable", // force one-string-per-line format + "package test;", + "import static java.lang.annotation.ElementType.TYPE_USE;", + "import java.lang.annotation.Target;", + "", + "@Target(TYPE_USE)", + "public @interface Nullable {}"); + private static final Source NON_TYPE_USE_NULLABLE = + CompilerTests.javaSource( + "test.Nullable", // force one-string-per-line format + "package test;", + "", + "public @interface Nullable {}"); + @Parameters(name = "{0}") public static ImmutableList<Object[]> parameters() { return CompilerMode.TEST_PARAMETERS; @@ -329,6 +347,54 @@ } @Test + public void typeUseNullableFieldInjection() { + Source file = + CompilerTests.javaSource( + "test.FieldInjection", + "package test;", + "", + "import dagger.Lazy;", + "import javax.inject.Inject;", + "import javax.inject.Provider;", + "", + "class FieldInjection {", + " @Inject @Nullable String string;", + "}"); + CompilerTests.daggerCompiler(file, TYPE_USE_NULLABLE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource( + goldenFileRule.goldenSource("test/FieldInjection_MembersInjector")); + }); + } + + @Test + public void nonTypeUseNullableFieldInjection() { + Source file = + CompilerTests.javaSource( + "test.FieldInjection", + "package test;", + "", + "import dagger.Lazy;", + "import javax.inject.Inject;", + "import javax.inject.Provider;", + "", + "class FieldInjection {", + " @Inject @Nullable String string;", + "}"); + CompilerTests.daggerCompiler(file, NON_TYPE_USE_NULLABLE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource( + goldenFileRule.goldenSource("test/FieldInjection_MembersInjector")); + }); + } + + @Test public void fieldInjectionWithQualifier() { Source file = CompilerTests.javaSource( @@ -713,33 +779,6 @@ } @Test - public void rawFrameworkTypeField() { - Source file = - CompilerTests.javaSource( - "test.RawFrameworkTypes", - "package test;", - "", - "import javax.inject.Inject;", - "import javax.inject.Provider;", - "", - "class RawProviderField {", - " @Inject", - " Provider fieldWithRawProvider;", - "}"); - - CompilerTests.daggerCompiler(file) - .withProcessingOptions(compilerMode.processorOptions()) - .compile( - subject -> { - subject.hasErrorCount(1); - subject.hasErrorContaining( - "Dagger does not support injecting raw type: javax.inject.Provider") - .onSource(file) - .onLineContaining("Provider fieldWithRawProvider"); - }); - } - - @Test public void throwExceptionInjectedMethod() { Source file = CompilerTests.javaSource( @@ -765,10 +804,37 @@ } @Test + public void rawFrameworkTypeField() { + Source file = + CompilerTests.javaSource( + "test.RawProviderField", + "package test;", + "", + "import javax.inject.Inject;", + "import javax.inject.Provider;", + "", + "class RawProviderField {", + " @Inject", + " Provider fieldWithRawProvider;", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting raw type: javax.inject.Provider") + .onSource(file) + .onLineContaining("Provider fieldWithRawProvider"); + }); + } + + @Test public void rawFrameworkMethodTypeParameter() { Source file = CompilerTests.javaSource( - "test.RawFrameworkTypes", + "test.RawProviderParameter", "package test;", "", "import javax.inject.Inject;", @@ -796,7 +862,7 @@ public void rawFrameworkConstructorTypeParameter() { Source file = CompilerTests.javaSource( - "test.RawFrameworkTypes", + "test.RawProviderParameter", "package test;", "", "import dagger.Component;", @@ -822,6 +888,274 @@ } @Test + public void rawMapFrameworkConstructorTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.RawMapProviderParameter", + "package test;", + "", + "import dagger.Component;", + "import javax.inject.Inject;", + "import javax.inject.Provider;", + "import java.util.Map;", + "", + "class RawMapProviderParameter {", + " @Inject", + " RawMapProviderParameter(", + " Map<String, Provider> rawProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting maps of raw framework types: " + + "java.util.Map<java.lang.String,javax.inject.Provider>") + .onSource(file) + .onLineContaining("Map<String, Provider> rawProviderParameter"); + }); + } + + @Test + public void daggerProviderField() { + Source file = + CompilerTests.javaSource( + "test.DaggerProviderField", + "package test;", + "", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "", + "class DaggerProviderField {", + " @Inject", + " Provider<String> fieldWithDaggerProvider;", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger disallows injecting the type: " + + "dagger.internal.Provider<java.lang.String>") + .onSource(file) + .onLineContaining("Provider<String> fieldWithDaggerProvider"); + }); + } + + @Test + public void daggerProviderMethodTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.DaggerProviderParameter", + "package test;", + "", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "", + "class DaggerProviderParameter {", + " @Inject", + " void methodInjection(", + " Provider<String> daggerProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger disallows injecting the type: " + + "dagger.internal.Provider<java.lang.String>") + .onSource(file) + .onLineContaining("Provider<String> daggerProviderParameter"); + }); + } + + @Test + public void daggerProviderConstructorTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.DaggerProviderParameter", + "package test;", + "", + "import dagger.Component;", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "", + "class DaggerProviderParameter {", + " @Inject", + " DaggerProviderParameter(", + " Provider<String> daggerProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger disallows injecting the type: " + + "dagger.internal.Provider<java.lang.String>") + .onSource(file) + .onLineContaining("Provider<String> daggerProviderParameter"); + }); + } + + @Test + public void rawDaggerProviderConstructorTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.RawDaggerProviderParameter", + "package test;", + "", + "import dagger.Component;", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "", + "class RawDaggerProviderParameter {", + " @Inject", + " RawDaggerProviderParameter(", + " Provider rawDaggerProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger disallows injecting the type: dagger.internal.Provider") + .onSource(file) + .onLineContaining("Provider rawDaggerProviderParameter"); + }); + } + + @Test + public void daggerMapProviderField() { + Source file = + CompilerTests.javaSource( + "test.DaggerMapProviderField", + "package test;", + "", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "import java.util.Map;", + "", + "class DaggerMapProviderField {", + " @Inject", + " Map<String, Provider<Long>> fieldWithDaggerMapProvider;", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting maps of disallowed types: " + + "java.util.Map<java.lang.String,dagger.internal.Provider<java.lang.Long>>") + .onSource(file) + .onLineContaining("Map<String, Provider<Long>> fieldWithDaggerMapProvider"); + }); + } + + @Test + public void daggerMapProviderMethodTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.DaggerMapProviderParameter", + "package test;", + "", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "import java.util.Map;", + "", + "class DaggerMapProviderParameter {", + " @Inject", + " void methodInjection(", + " Map<String, Provider<Long>> daggerMapProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting maps of disallowed types: " + + "java.util.Map<java.lang.String,dagger.internal.Provider<java.lang.Long>>") + .onSource(file) + .onLineContaining("Map<String, Provider<Long>> daggerMapProviderParameter"); + }); + } + + @Test + public void daggerMapProviderConstructorTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.DaggerMapProviderParameter", + "package test;", + "", + "import dagger.Component;", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "import java.util.Map;", + "", + "class DaggerMapProviderParameter {", + " @Inject", + " DaggerMapProviderParameter(", + " Map<String, Provider<Long>> daggerMapProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting maps of disallowed types: " + + "java.util.Map<java.lang.String,dagger.internal.Provider<java.lang.Long>>") + .onSource(file) + .onLineContaining("Map<String, Provider<Long>> daggerMapProviderParameter"); + }); + } + + @Test + public void rawDaggerMapProviderConstructorTypeParameter() { + Source file = + CompilerTests.javaSource( + "test.RawDaggerMapProviderParameter", + "package test;", + "", + "import dagger.Component;", + "import dagger.internal.Provider;", + "import javax.inject.Inject;", + "import java.util.Map;", + "", + "class RawDaggerMapProviderParameter {", + " @Inject", + " RawDaggerMapProviderParameter(", + " Map<String, Provider> rawDaggerMapProviderParameter) {}", + "}"); + + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Dagger does not support injecting maps of disallowed types: " + + "java.util.Map<java.lang.String,dagger.internal.Provider>") + .onSource(file) + .onLineContaining("Map<String, Provider> rawDaggerMapProviderParameter"); + }); + } + + @Test public void injectsPrimitive() throws Exception { Source injectedType = CompilerTests.javaSource( @@ -1271,4 +1605,71 @@ subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent")); }); } + + @Test + public void kotlinNullableFieldInjection() { + Source file = + CompilerTests.kotlinSource( + "MyClass.kt", + "package test;", + "", + "import javax.inject.Inject;", + "", + "class MyClass @Inject constructor() {", + " @JvmField @Inject var nullableString: String? = null", + " @JvmField @Inject var nullableObject: Any? = null", + "}"); + CompilerTests.daggerCompiler(file) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + Source expectedSource = goldenFileRule.goldenSource("test/MyClass_MembersInjector"); + subject.generatedSource( + CompilerTests.backend(subject) == XProcessingEnv.Backend.KSP + ? stripJetbrainsNullable(expectedSource) + : expectedSource); + }); + } + + @Test + public void testMembersInjectionBindingWithNoInjectionSites() throws Exception { + Source component = + CompilerTests.javaSource( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component", + "public interface MyComponent {", + " void inject(Foo foo);", + "", + " Foo injectAndReturn(Foo foo);", + "}"); + + Source foo = + CompilerTests.javaSource( + "test.Foo", + "package test;", + "", + "class Foo {}"); + + CompilerTests.daggerCompiler(component, foo) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource(goldenFileRule.goldenSource("test/DaggerMyComponent")); + }); + } + + private Source stripJetbrainsNullable(Source source) { + return CompilerTests.javaSource( + ((Source.JavaSource) source).getQName(), + source + .getContents() + .replace("@Nullable ", "") + .replace("import org.jetbrains.annotations.Nullable;\n", "")); + } }
diff --git a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java index 8250861..4910011 100644 --- a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java +++ b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java
@@ -32,6 +32,10 @@ @RunWith(Parameterized.class) public class MissingBindingValidationTest { + private static final String JVM_SUPPRESS_WILDCARDS_MESSAGE = + "(For Kotlin sources, you may need to use '@JvmSuppressWildcards' or '@JvmWildcard' if you " + + "need to explicitly control the wildcards at a particular usage site.)"; + @Parameters(name = "{0}") public static ImmutableList<Object[]> parameters() { return CompilerMode.TEST_PARAMETERS; @@ -1097,7 +1101,9 @@ " [Child1] Child1.getObject() [Parent → Child1]", "", "Note: Object is provided in the following other components:", - " [Child2] Child2Module.provideObject()")); + " [Child2] Child2Module.provideObject()", + "", + "======================")); }); } @@ -1218,7 +1224,9 @@ + "[Parent → Child1 → RepeatedSub]", "", "Note: Object is provided in the following other components:", - " [Child2] Child2Module.provideObject(…)")); + " [Child2] Child2Module.provideObject(…)", + "", + "======================")); }); } @@ -1349,7 +1357,9 @@ " [Sub] Sub.getObject() [Parent → Child1 → Sub]", "", "Note: Object is provided in the following other components:", - " [Child2] Child2Module.provideObject(…)")); + " [Child2] Child2Module.provideObject(…)", + "", + "======================")); }); } @@ -1449,7 +1459,10 @@ "", "Note: A similar binding is provided in the following other components:", " Set<Bar> is provided at:", - " [MyComponent] Dagger-generated binding for Set<Bar>")) + " [MyComponent] Dagger-generated binding for Set<Bar>", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1519,7 +1532,10 @@ "", "Note: A similar binding is provided in the following other components:", " Set<Bar> is provided at:", - " [MyComponent] Dagger-generated binding for Set<Bar>")) + " [MyComponent] Dagger-generated binding for Set<Bar>", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1592,7 +1608,10 @@ "", "Note: A similar binding is provided in the following other components:", " Set<Bar> is provided at:", - " [MyComponent] Dagger-generated binding for Set<Bar>")) + " [MyComponent] Dagger-generated binding for Set<Bar>", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1654,7 +1673,10 @@ "", "Note: A similar binding is provided in the following other components:", " List<? extends Bar> is provided at:", - " [MyComponent] TestModule.provideBars()")) + " [MyComponent] TestModule.provideBars()", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1729,7 +1751,10 @@ "", "Note: A similar binding is provided in the following other components:", " Bar<Baz,Baz,Set<Baz>> is provided at:", - " [MyComponent] TestModule.provideBar()")) + " [MyComponent] TestModule.provideBar()", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")) .onSource(component) .onLineContaining("interface MyComponent"); }); @@ -1865,7 +1890,10 @@ "", "Note: A similar binding is provided in the following other components:", " Bar is provided at:", - " [MyComponent] TestModule.provideBar()")); + " [MyComponent] TestModule.provideBar()", + JVM_SUPPRESS_WILDCARDS_MESSAGE, + "", + "======================")); }); } @@ -1923,4 +1951,218 @@ .doesNotContain("bindings with similar types exists in the graph"); }); } + + // Regression test for b/367426609 + @Test + public void failsWithMissingBindingInGrandchild() { + Source parent = + CompilerTests.javaSource( + "test.Parent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component(modules = ParentModule.class)", + "interface Parent {", + " Child child();", + "}"); + Source child = + CompilerTests.javaSource( + "test.Child", + "package test;", + "", + "import dagger.Subcomponent;", + "", + "@Subcomponent(modules = ChildModule.class)", + "interface Child {", + " Grandchild grandchild();", + "}"); + Source grandchild = + CompilerTests.javaSource( + "test.Grandchild", + "package test;", + "", + "import dagger.Subcomponent;", + "", + "@Subcomponent(modules=GrandchildModule.class)", + "interface Grandchild {", + // Note: it's important that Qux is first to reproduce the error in b/367426609. + " Qux getQux();", + " Foo getFoo();", + "}"); + Source parentModule = + CompilerTests.javaSource( + "test.ParentModule", + "package test;", + "", + "import dagger.BindsOptionalOf;", + "import dagger.Module;", + "import dagger.Provides;", + "import java.util.Optional;", + "", + "@Module", + "interface ParentModule {", + " @BindsOptionalOf", + " String optionalString();", + "", + // depend on an @BindsOptionalOf to force re-resolution in subcomponents. + " @Provides", + " static Foo provideFoo(Optional<String> str, Qux qux) { return null; }", + "}"); + Source childModule = + CompilerTests.javaSource( + "test.ChildModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "interface ChildModule {", + " @Provides", + " static Qux provideQux() { return null; }", + "}"); + Source grandchildModule = + CompilerTests.javaSource( + "test.GrandchildModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "interface GrandchildModule {", + " @Provides", + " static String provideString() { return null; }", + "}"); + Source foo = + CompilerTests.javaSource( // force one-string-per-line format + "test.Foo", + "package test;", + "", + "interface Foo {}"); + Source bar = + CompilerTests.javaSource( // force one-string-per-line format + "test.Bar", + "package test;", + "", + "interface Bar {}"); + Source qux = + CompilerTests.javaSource( // force one-string-per-line format + "test.Qux", + "package test;", + "", + "interface Qux {}"); + + CompilerTests.daggerCompiler( + parent, child, grandchild, parentModule, childModule, grandchildModule, foo, bar, qux) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } + + // Regression test for b/367426609 + @Test + public void failsWithMissingBindingInGrandchild_dependencyTracePresent() { + Source parent = + CompilerTests.javaSource( + "test.Parent", + "package test;", + "", + "import dagger.Component;", + "", + "@Component(modules = ParentModule.class)", + "interface Parent {", + " Child child();", + "}"); + Source child = + CompilerTests.javaSource( + "test.Child", + "package test;", + "", + "import dagger.Subcomponent;", + "", + "@Subcomponent(modules = ChildModule.class)", + "interface Child {", + " Grandchild grandchild();", + "}"); + Source grandchild = + CompilerTests.javaSource( + "test.Grandchild", + "package test;", + "", + "import dagger.Subcomponent;", + "", + "@Subcomponent(modules=GrandchildModule.class)", + "interface Grandchild {", + " Foo getFoo();", + "}"); + Source parentModule = + CompilerTests.javaSource( + "test.ParentModule", + "package test;", + "", + "import dagger.BindsOptionalOf;", + "import dagger.Module;", + "import dagger.Provides;", + "import java.util.Optional;", + "", + "@Module", + "interface ParentModule {", + " @BindsOptionalOf", + " String optionalString();", + "", + // depend on an @BindsOptionalOf to force re-resolution in subcomponents. + " @Provides", + " static Foo provideFoo(Optional<String> str, Qux qux) { return null; }", + "}"); + Source childModule = + CompilerTests.javaSource( + "test.ChildModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "interface ChildModule {", + " @Provides", + " static Qux provideQux() { return null; }", + "}"); + Source grandchildModule = + CompilerTests.javaSource( + "test.GrandchildModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "interface GrandchildModule {", + " @Provides", + " static String provideString() { return null; }", + "}"); + Source foo = + CompilerTests.javaSource( // force one-string-per-line format + "test.Foo", + "package test;", + "", + "interface Foo {}"); + Source bar = + CompilerTests.javaSource( // force one-string-per-line format + "test.Bar", + "package test;", + "", + "interface Bar {}"); + Source qux = + CompilerTests.javaSource( // force one-string-per-line format + "test.Qux", + "package test;", + "", + "interface Qux {}"); + + CompilerTests.daggerCompiler( + parent, child, grandchild, parentModule, childModule, grandchildModule, foo, bar, qux) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } }
diff --git a/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java b/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java index cc8e3b4..ccff741 100644 --- a/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java +++ b/javatests/dagger/internal/codegen/ModuleFactoryGeneratorTest.java
@@ -19,6 +19,7 @@ import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass; import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod; +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; @@ -32,9 +33,12 @@ @RunWith(JUnit4.class) public class ModuleFactoryGeneratorTest { - private static final Source NULLABLE = - CompilerTests.javaSource( - "test.Nullable", "package test;", "public @interface Nullable {}"); + private static final Source NON_TYPE_USE_NULLABLE = + CompilerTests.javaSource( + "test.Nullable", // force one-string-per-line format + "package test;", + "", + "public @interface Nullable {}"); @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); @@ -68,6 +72,25 @@ } @Test + public void providesMethodReturnsJakartaProvider() { + assertThatModuleMethod("@Provides jakarta.inject.Provider<String> provideProvider() {}") + .hasError("@Provides methods must not return framework types"); + } + + @Test + public void providesMethodReturnsDaggerInternalProvider() { + assertThatModuleMethod("@Provides dagger.internal.Provider<String> provideProvider() {}") + .hasError("@Provides methods must not return disallowed types"); + } + + @Test + public void providesIntoSetMethodReturnsDaggerInternalProvider() { + assertThatModuleMethod( + "@Provides @IntoSet dagger.internal.Provider<String> provideProvider() {}") + .hasError("@Provides methods must not return disallowed types"); + } + + @Test public void providesMethodReturnsLazy() { assertThatModuleMethod("@Provides Lazy<String> provideLazy() {}") .hasError("@Provides methods must not return framework types"); @@ -108,12 +131,31 @@ .hasError("@Provides methods annotated with @ElementsIntoSet cannot return a raw Set"); } + @Test public void providesElementsIntoSetMethodReturnsSetDaggerProvider() { + assertThatModuleMethod( + "@Provides @ElementsIntoSet Set<dagger.internal.Provider<String>> provideProvider() {}") + .hasError("@Provides methods must not return disallowed types"); + } + @Test public void providesMethodSetValuesNotASet() { assertThatModuleMethod( "@Provides @ElementsIntoSet List<String> provideStrings() { return null; }") .hasError("@Provides methods annotated with @ElementsIntoSet must return a Set"); } + @Test + public void bindsMethodReturnsProvider() { + assertThatModuleMethod("@Binds abstract Provider<Number> bindsProvider(Provider<Long> impl);") + .hasError("@Binds methods must not return framework types"); + } + + @Test + public void bindsMethodReturnsDaggerProvider() { + assertThatModuleMethod("@Binds abstract dagger.internal.Provider<Number> " + + "bindsProvider(dagger.internal.Provider<Long> impl);") + .hasError("@Binds methods must not return disallowed types"); + } + @Test public void modulesWithTypeParamsMustBeAbstract() { Source moduleFile = CompilerTests.javaSource( @@ -277,7 +319,8 @@ }); } - @Test public void nullableProvides() { + @Test + public void nonTypeUseNullableProvides() { Source moduleFile = CompilerTests.javaSource( "test.TestModule", @@ -290,7 +333,7 @@ "final class TestModule {", " @Provides @Nullable String provideString() { return null; }", "}"); - CompilerTests.daggerCompiler(moduleFile, NULLABLE) + CompilerTests.daggerCompiler(moduleFile, NON_TYPE_USE_NULLABLE) .compile( subject -> { subject.hasErrorCount(0); @@ -299,6 +342,80 @@ }); } + @Test + public void kotlinNullableProvides() { + Source moduleFile = + CompilerTests.kotlinSource( + "TestModule.kt", + "package test", + "", + "import dagger.Module;", + "import dagger.Provides;", + "", + "@Module", + "class TestModule {", + " @Provides fun provideString(): String? { return null; }", + "}"); + CompilerTests.daggerCompiler(moduleFile) + .compile( + subject -> { + subject.hasErrorCount(0); + boolean isJavac = CompilerTests.backend(subject) == XProcessingEnv.Backend.JAVAC; + subject.generatedSource( + CompilerTests.javaSource( + "test.TestModule_ProvideStringFactory", + "package test;", + "", + "import dagger.internal.DaggerGenerated;", + "import dagger.internal.Factory;", + "import dagger.internal.QualifierMetadata;", + "import dagger.internal.ScopeMetadata;", + "import javax.annotation.processing.Generated;", + isJavac ? "import org.jetbrains.annotations.Nullable;\n" : "", + "@ScopeMetadata", + "@QualifierMetadata", + "@DaggerGenerated", + "@Generated(", + " value = \"dagger.internal.codegen.ComponentProcessor\",", + " comments = \"https://dagger.dev\"", + ")", + "@SuppressWarnings({", + " \"unchecked\",", + " \"rawtypes\",", + " \"KotlinInternal\",", + " \"KotlinInternalInJava\",", + " \"cast\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class TestModule_ProvideStringFactory implements" + + " Factory<String> {", + " private final TestModule module;", + "", + " public TestModule_ProvideStringFactory(TestModule module) {", + " this.module = module;", + " }", + "", + // TODO(b/368129744): KSP should output the @Nullable annotation after this + // bug is fixed. + isJavac ? " @Override\n @Nullable" : " @Override", + " public String get() {", + " return provideString(module);", + " }", + "", + " public static TestModule_ProvideStringFactory create(TestModule module) {", + " return new TestModule_ProvideStringFactory(module);", + " }", + // TODO(b/368129744): KSP should output the @Nullable annotation after this + // bug is fixed. + isJavac ? "\n @Nullable" : "", + " public static String provideString(TestModule instance) {", + " return instance.provideString();", + " }", + "}")); + }); + } + @Test public void multipleProvidesMethods() { Source classXFile = CompilerTests.javaSource("test.X", @@ -344,7 +461,8 @@ }); } - @Test public void providesSetElement() { + @Test + public void providesSetElement() { Source moduleFile = CompilerTests.javaSource( "test.TestModule",
diff --git a/javatests/dagger/internal/codegen/MultibindingTest.java b/javatests/dagger/internal/codegen/MultibindingTest.java index 119fe80..e9b403f 100644 --- a/javatests/dagger/internal/codegen/MultibindingTest.java +++ b/javatests/dagger/internal/codegen/MultibindingTest.java
@@ -24,6 +24,39 @@ @RunWith(JUnit4.class) public class MultibindingTest { + @Test + public void multibindingContributedWithKotlinProperty_compilesSucessfully() { + Source component = + CompilerTests.javaSource( + "test.MyComponent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Set;", + "", + "@Component(modules = TestModule.class)", + "interface MyComponent {", + " Set<String> getStrs();", + "}"); + Source moduleSrc = + CompilerTests.kotlinSource( + "test.TestModule.kt", + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoSet", + "", + "@Module", + "object TestModule {", + "@get:IntoSet", + "@get:Provides", + "val helloString: String", + " get() = \"hello\"", + "}"); + + CompilerTests.daggerCompiler(component, moduleSrc).compile(subject -> subject.hasErrorCount(0)); + } @Test public void providesWithTwoMultibindingAnnotations_failsToCompile() { @@ -266,4 +299,341 @@ .onLineContaining("interface Parent"); }); } + + // Regression test for b/352142595. + @Test + public void testMultibindingMapWithKotlinSource() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "", + "class Usage @Inject constructor(map: Map<String, MyInterface>)"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoMap", + "import dagger.multibindings.StringKey", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoMap", + " @StringKey(\"key\")", + " fun provideMyInterface(): MyInterface = TODO()", + "}"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myInterface, usage) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("Map<String,? extends MyInterface> cannot be provided"); + }); + } + + // Regression test for b/352142595. + @Test + public void testMultibindingMapWithOutVarianceKotlinSource_succeeds() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "", + "class Usage @Inject constructor(", + " map: Map<String, @JvmSuppressWildcards MyGenericInterface<out MyInterface>>", + ")"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoMap", + "import dagger.multibindings.StringKey", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoMap", + " @StringKey(\"key\")", + " fun provideMyInterface(): MyGenericInterface<out MyInterface> = TODO()", + "}"); + Source myGenericInterface = + CompilerTests.kotlinSource( + "test.MyGenericInterface.kt", + "package test", + "", + "interface MyGenericInterface<T>"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myGenericInterface, myInterface, usage) + .compile(subject -> subject.hasErrorCount(0)); + } + + // Regression test for b/352142595. + @Test + public void testMultibindingMapWithJvmWildcardsKotlinSource_succeeds() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "", + "class Usage @Inject constructor(", + " map: Map<String,@JvmSuppressWildcards MyGenericInterface<@JvmWildcard MyInterface>>", + ")"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoMap", + "import dagger.multibindings.StringKey", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoMap", + " @StringKey(\"key\")", + " fun provideMyInterface(): MyGenericInterface<@JvmWildcard MyInterface> = TODO()", + "}"); + Source myGenericInterface = + CompilerTests.kotlinSource( + "test.MyGenericInterface.kt", + "package test", + "", + "interface MyGenericInterface<out T>"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myGenericInterface, myInterface, usage) + .compile(subject -> subject.hasErrorCount(0)); + } + + // Regression test for b/352142595. + @Test + public void testMultibindingMapProviderWithKotlinSource() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "import javax.inject.Provider", + "", + "class Usage @Inject constructor(map: Map<String, Provider<MyInterface>>)"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoMap", + "import dagger.multibindings.StringKey", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoMap", + " @StringKey(\"key\")", + " fun provideMyInterface(): MyInterface = TODO()", + "}"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myInterface, usage) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "Map<String,? extends Provider<MyInterface>> cannot be provided"); + }); + } + + // Regression test for b/352142595. + @Test + public void testMultibindingSetWithKotlinSource() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "", + "class Usage @Inject constructor(set: Set<MyInterface>)"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoSet", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoSet", + " fun provideMyInterface(): MyInterface = TODO()", + "}"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myInterface, usage) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("Set<? extends MyInterface> cannot be provided"); + }); + } + + // Regression test for b/352142595. + @Test + public void testMultibindingSetProviderWithKotlinSource() { + Source parent = + CompilerTests.kotlinSource( + "test.Parent.kt", + "package test", + "", + "import dagger.Component", + "", + "@Component(modules = [ParentModule::class])", + "interface Parent {", + " fun usage(): Usage", + "}"); + Source usage = + CompilerTests.kotlinSource( + "test.Usage.kt", + "package test", + "", + "import javax.inject.Inject", + "import javax.inject.Provider", + "", + "class Usage @Inject constructor(set: Set<Provider<MyInterface>>)"); + Source parentModule = + CompilerTests.kotlinSource( + "test.ParentModule.kt", + "@file:Suppress(\"INLINE_FROM_HIGHER_PLATFORM\")", // Required to use TODO() + "package test", + "", + "import dagger.Module", + "import dagger.Provides", + "import dagger.multibindings.IntoSet", + "", + "@Module", + "class ParentModule {", + " @Provides", + " @IntoSet", + " fun provideMyInterface(): MyInterface = TODO()", + "}"); + Source myInterface = + CompilerTests.kotlinSource( + "test.MyInterface.kt", + "package test", + "", + "interface MyInterface"); + + CompilerTests.daggerCompiler(parent, parentModule, myInterface, usage) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("Set<? extends Provider<MyInterface>> cannot be provided"); + }); + } }
diff --git a/javatests/dagger/internal/codegen/MultibindsValidationTest.java b/javatests/dagger/internal/codegen/MultibindsValidationTest.java index a006dfa..0395c70 100644 --- a/javatests/dagger/internal/codegen/MultibindsValidationTest.java +++ b/javatests/dagger/internal/codegen/MultibindsValidationTest.java
@@ -142,20 +142,6 @@ } @Test - public void providerSet() { - assertThatModuleMethod("@Multibinds abstract Set<Provider<Object>> providerSet();") - .withDeclaration(moduleDeclaration) - .hasError("return type cannot use 'Provider' in the Set value type."); - } - - @Test - public void producerSet() { - assertThatModuleMethod("@Multibinds abstract Set<Producer<Object>> producerSet();") - .withDeclaration(moduleDeclaration) - .hasError("return type cannot use 'Producer' in the Set value type."); - } - - @Test public void producedSet() { assertThatModuleMethod("@Multibinds abstract Set<Produced<Object>> producedSet();") .withDeclaration(moduleDeclaration)
diff --git a/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java b/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java index 188f4d6..d01b694 100644 --- a/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java +++ b/javatests/dagger/internal/codegen/OptionalBindingRequestFulfillmentTest.java
@@ -23,7 +23,6 @@ import com.google.testing.compile.Compilation; import com.google.testing.compile.JavaFileObjects; import dagger.testing.golden.GoldenFileRule; -import java.util.Collection; import javax.tools.JavaFileObject; import org.junit.Rule; import org.junit.Test; @@ -34,14 +33,8 @@ @RunWith(Parameterized.class) public class OptionalBindingRequestFulfillmentTest { @Parameters(name = "{0}") - public static Collection<Object[]> parameters() { - return ImmutableList.copyOf( - new Object[][] { - {CompilerMode.DEFAULT_MODE}, - {CompilerMode.DEFAULT_JAVA7_MODE}, - {CompilerMode.FAST_INIT_MODE}, - {CompilerMode.FAST_INIT_JAVA7_MODE} - }); + public static ImmutableList<Object[]> parameters() { + return CompilerMode.TEST_PARAMETERS; } @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule();
diff --git a/javatests/dagger/internal/codegen/OptionalBindingTest.java b/javatests/dagger/internal/codegen/OptionalBindingTest.java index bcec73f..76a0592 100644 --- a/javatests/dagger/internal/codegen/OptionalBindingTest.java +++ b/javatests/dagger/internal/codegen/OptionalBindingTest.java
@@ -105,4 +105,74 @@ .onLineContaining("interface Parent"); }); } + + // Note: This is a regression test for an issue we ran into in CL/644086367, where an optional + // binding owned by a parent component is also requested by a child component which declares an + // additional @BindsOptionalOf declaration. In this case, we just want to make sure that the setup + // builds successfully. + @Test + public void cachedInParent_succeeds() { + Source parent = + CompilerTests.javaSource( + "test.Parent", + "package test;", + "", + "import dagger.Component;", + "import java.util.Optional;", + "", + "@Component(modules = ParentModule.class)", + "interface Parent {", + " Optional<String> optionalString();", + " Child child();", + "}"); + Source parentModule = + CompilerTests.javaSource( + "test.ParentModule", + "package test;", + "", + "import dagger.BindsOptionalOf;", + "import dagger.Module;", + "import dagger.Provides;", + "import java.util.Optional;", + "", + "@Module", + "interface ParentModule {", + " @BindsOptionalOf", + " String optionalParentString();", + "", + " @Provides", + " static String provideString() {", + " return \"\";", + " }", + "}"); + Source child = + CompilerTests.javaSource( + "test.Child", + "package test;", + "", + "import dagger.Subcomponent;", + "import java.util.Optional;", + "", + "@Subcomponent(modules = ChildModule.class)", + "interface Child {", + " Optional<String> optionalString();", + "}"); + Source childModule = + CompilerTests.javaSource( + "test.ChildModule", + "package test;", + "", + "import dagger.BindsOptionalOf;", + "import dagger.Module;", + "", + "@Module", + "interface ChildModule {", + " @BindsOptionalOf", + " String optionalChildString();", + "}"); + + CompilerTests.daggerCompiler(parent, parentModule, child, childModule) + .withProcessingOptions(compilerMode.processorOptions()) + .compile(subject -> subject.hasErrorCount(0)); + } }
diff --git a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java b/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java index 39e63c9..6840aad 100644 --- a/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/ProductionComponentProcessorTest.java
@@ -16,6 +16,7 @@ package dagger.internal.codegen; + import androidx.room.compiler.processing.util.Source; import com.google.common.collect.ImmutableMap; import dagger.testing.compile.CompilerTests; @@ -34,6 +35,24 @@ return CompilerMode.TEST_PARAMETERS; } + private static final Source EXECUTOR_MODULE = + CompilerTests.javaSource( + "test.ExecutorModule", + "package test;", + "", + "import com.google.common.util.concurrent.MoreExecutors;", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.producers.Production;", + "import java.util.concurrent.Executor;", + "", + "@Module", + "final class ExecutorModule {", + " @Provides @Production Executor executor() {", + " return MoreExecutors.directExecutor();", + " }", + "}"); + @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); private final CompilerMode compilerMode; @@ -121,23 +140,6 @@ @Test public void dependsOnProductionExecutor() throws Exception { - Source moduleFile = - CompilerTests.javaSource( - "test.ExecutorModule", - "package test;", - "", - "import com.google.common.util.concurrent.MoreExecutors;", - "import dagger.Module;", - "import dagger.Provides;", - "import dagger.producers.Production;", - "import java.util.concurrent.Executor;", - "", - "@Module", - "final class ExecutorModule {", - " @Provides @Production Executor executor() {", - " return MoreExecutors.directExecutor();", - " }", - "}"); Source producerModuleFile = CompilerTests.javaSource( "test.SimpleModule", @@ -174,7 +176,7 @@ "}"); String errorMessage = "String may not depend on the production executor"; - CompilerTests.daggerCompiler(moduleFile, producerModuleFile, componentFile) + CompilerTests.daggerCompiler(EXECUTOR_MODULE, producerModuleFile, componentFile) .withProcessingOptions(compilerMode.processorOptions()) .compile( subject -> { @@ -415,4 +417,223 @@ subject.generatedSource(goldenFileRule.goldenSource("test/DaggerParent")); }); } + + @Test + public void requestProducerNodeWithProvider_failsWithNotSupportedError() { + Source producerModuleFile = + CompilerTests.javaSource( + "test.SimpleModule", + "package test;", + "", + "import dagger.producers.ProducerModule;", + "import dagger.producers.Produces;", + "import javax.inject.Provider;", + "import java.util.concurrent.Executor;", + "import dagger.producers.Production;", + "", + "@ProducerModule", + "final class SimpleModule {", + " @Produces String str(Provider<Integer> num) {", + " return \"\";", + " }", + " @Produces Integer num() { return 1; }", + "}"); + Source componentFile = + CompilerTests.javaSource( + "test.SimpleComponent", + "package test;", + "", + "import com.google.common.util.concurrent.ListenableFuture;", + "import dagger.producers.ProductionComponent;", + "", + "@ProductionComponent(modules = {ExecutorModule.class, SimpleModule.class})", + "interface SimpleComponent {", + " ListenableFuture<String> str();", + "", + " @ProductionComponent.Builder", + " interface Builder {", + " SimpleComponent build();", + " }", + "}"); + + CompilerTests.daggerCompiler(EXECUTOR_MODULE, producerModuleFile, componentFile) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "request kind PROVIDER cannot be satisfied by production binding"); + }); + } + + @Test + public void productionBindingKind_failsIfScoped() { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import com.google.common.util.concurrent.ListenableFuture;", + "import dagger.producers.ProductionComponent;", + "", + "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})", + "interface TestComponent {", + " ListenableFuture<String> str();", + "}"); + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.producers.ProducerModule;", + "import dagger.producers.Produces;", + "import dagger.producers.ProductionScope;", + "import javax.inject.Provider;", + "import java.util.concurrent.Executor;", + "import dagger.producers.Production;", + "", + "@ProducerModule", + "interface TestModule {", + " @ProductionScope", + " @Produces", + " static String provideString() { return \"\"; }", + "}"); + + CompilerTests.daggerCompiler(component, module, EXECUTOR_MODULE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining("@Produces methods cannot be scoped"); + }); + } + + @Test + public void delegateToProductionBindingKind_failsIfScoped() { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import com.google.common.util.concurrent.ListenableFuture;", + "import dagger.producers.ProductionComponent;", + "", + "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})", + "interface TestComponent {", + " ListenableFuture<Foo> foo();", + "}"); + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Binds;", + "import dagger.producers.ProducerModule;", + "import dagger.producers.Produces;", + "import dagger.producers.ProductionScope;", + "import javax.inject.Provider;", + "import java.util.concurrent.Executor;", + "import dagger.producers.Production;", + "", + "@ProducerModule", + "interface TestModule {", + " @ProductionScope", + " @Binds", + " Foo bind(FooImpl impl);", + "", + " @Produces", + " static FooImpl fooImpl() { return new FooImpl(); }", + "}"); + Source foo = + CompilerTests.javaSource( + "test.Foo", + "package test;", + "", + "interface Foo {}"); + Source fooImpl = + CompilerTests.javaSource( + "test.FooImpl", + "package test;", + "", + "final class FooImpl implements Foo {}"); + + CompilerTests.daggerCompiler(component, module, foo, fooImpl, EXECUTOR_MODULE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "@ProductionScope @Binds Foo TestModule.bind(FooImpl) cannot be scoped " + + "because it delegates to an @Produces method"); + }); + } + + @Test + public void multipleDelegatesToProductionBindingKind_failsIfScoped() { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import com.google.common.util.concurrent.ListenableFuture;", + "import dagger.producers.ProductionComponent;", + "", + "@ProductionComponent(modules = {ExecutorModule.class, TestModule.class})", + "interface TestComponent {", + " ListenableFuture<FooSuper> fooSuper();", + "}"); + Source module = + CompilerTests.javaSource( + "test.TestModule", + "package test;", + "", + "import dagger.Binds;", + "import dagger.producers.ProducerModule;", + "import dagger.producers.Produces;", + "import dagger.producers.ProductionScope;", + "import javax.inject.Provider;", + "import java.util.concurrent.Executor;", + "import dagger.producers.Production;", + "", + "@ProducerModule", + "interface TestModule {", + " @ProductionScope", + " @Binds", + " FooSuper bindFooSuper(Foo impl);", + "", + " @Binds", + " Foo bindFoo(FooImpl impl);", + "", + " @Produces", + " static FooImpl fooImpl() { return new FooImpl(); }", + "}"); + Source fooSuper = + CompilerTests.javaSource( + "test.FooSuper", + "package test;", + "", + "interface FooSuper {}"); + Source foo = + CompilerTests.javaSource( + "test.Foo", + "package test;", + "", + "interface Foo extends FooSuper {}"); + Source fooImpl = + CompilerTests.javaSource( + "test.FooImpl", + "package test;", + "", + "final class FooImpl implements Foo {}"); + + CompilerTests.daggerCompiler(component, module, fooSuper, foo, fooImpl, EXECUTOR_MODULE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(1); + subject.hasErrorContaining( + "@ProductionScope @Binds FooSuper TestModule.bindFooSuper(Foo) cannot be scoped " + + "because it delegates to an @Produces method"); + }); + } }
diff --git a/javatests/dagger/internal/codegen/ScopingValidationTest.java b/javatests/dagger/internal/codegen/ScopingValidationTest.java index fe112a2..4d811b9 100644 --- a/javatests/dagger/internal/codegen/ScopingValidationTest.java +++ b/javatests/dagger/internal/codegen/ScopingValidationTest.java
@@ -78,7 +78,7 @@ "MyComponent (unscoped) may not reference scoped bindings:", " @Singleton class ScopedType", " ScopedType is requested at", - " MyComponent.string()", + " [MyComponent] MyComponent.string()", "", " @Provides @Singleton String ScopedModule.string()")); }); @@ -242,7 +242,7 @@ + "different scopes:", " @PerTest class ScopedType", " ScopedType is requested at", - " MyComponent.string()", + " [MyComponent] MyComponent.string()", "", " @Provides @PerTest String ScopedModule.string()", "",
diff --git a/javatests/dagger/internal/codegen/SetMultibindingValidationTest.java b/javatests/dagger/internal/codegen/SetMultibindingValidationTest.java new file mode 100644 index 0000000..5933a43 --- /dev/null +++ b/javatests/dagger/internal/codegen/SetMultibindingValidationTest.java
@@ -0,0 +1,212 @@ +/* + * 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 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 SetMultibindingValidationTest { + @Parameters(name = "{0}") + public static ImmutableList<Object[]> parameters() { + return CompilerMode.TEST_PARAMETERS; + } + + private final CompilerMode compilerMode; + + public SetMultibindingValidationTest(CompilerMode compilerMode) { + this.compilerMode = compilerMode; + } + + @Test + public void setBindingOfProduced_provides() { + Source providesModule = + CompilerTests.javaSource( + "test.SetModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.IntoSet;", + "import dagger.producers.Produced;", + "", + "@Module", + "abstract class SetModule {", + "", + " @Provides", + " @IntoSet", + " static Produced<String> provideProducer() {", + " return null;", + " }", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source providesComponent = component(""); + + CompilerTests.daggerCompiler(providesModule, providesComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Provides methods with @IntoSet/@ElementsIntoSet must not return framework " + + "types"); + subject.hasErrorContaining("test.SetModule has errors") + .onSource(providesComponent) + .onLineContaining("@Component(modules = {SetModule.class})"); + }); + } + + @Test + public void setBindingOfProduced_binds() { + + Source bindsModule = + CompilerTests.javaSource( + "test.SetModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Binds;", + "import dagger.multibindings.IntoSet;", + "import dagger.producers.Produced;", + "", + "@Module", + "abstract class SetModule {", + "", + " @Binds", + " @IntoSet", + " abstract Produced<String> provideProvider(Produced<String> impl);", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source bindsComponent = component(""); + + CompilerTests.daggerCompiler(bindsModule, bindsComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Binds methods with @IntoSet/@ElementsIntoSet must not return framework types"); + subject.hasErrorContaining("test.SetModule has errors") + .onSource(bindsComponent) + .onLineContaining("@Component(modules = {SetModule.class})"); + }); + } + + @Test + public void elementsIntoSetBindingOfProduced_provides() { + Source providesModule = + CompilerTests.javaSource( + "test.SetModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Provides;", + "import dagger.multibindings.ElementsIntoSet;", + "import dagger.producers.Produced;", + "import java.util.Set;", + "", + "@Module", + "abstract class SetModule {", + "", + " @Provides", + " @ElementsIntoSet", + " static Set<Produced<String>> provideProducer() {", + " return null;", + " }", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source providesComponent = component(""); + + CompilerTests.daggerCompiler(providesModule, providesComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Provides methods with @IntoSet/@ElementsIntoSet must not return framework " + + "types"); + subject.hasErrorContaining("test.SetModule has errors") + .onSource(providesComponent) + .onLineContaining("@Component(modules = {SetModule.class})"); + }); + } + + @Test + public void elementsIntoSetBindingOfProduced_binds() { + + Source bindsModule = + CompilerTests.javaSource( + "test.SetModule", + "package test;", + "", + "import dagger.Module;", + "import dagger.Binds;", + "import dagger.multibindings.ElementsIntoSet;", + "import dagger.producers.Produced;", + "import java.util.Set;", + "", + "@Module", + "abstract class SetModule {", + "", + " @Binds", + " @ElementsIntoSet", + " abstract Set<Produced<String>> provideProvider(Set<Produced<String>> impl);", + "}"); + + // Entry points aren't needed because the check we care about here is a module validation + Source bindsComponent = component(""); + + CompilerTests.daggerCompiler(bindsModule, bindsComponent) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(2); + subject.hasErrorContaining( + "@Binds methods with @IntoSet/@ElementsIntoSet must not return framework types"); + subject.hasErrorContaining("test.SetModule has errors") + .onSource(bindsComponent) + .onLineContaining("@Component(modules = {SetModule.class})"); + }); + } + + private static Source component(String... entryPoints) { + return CompilerTests.javaSource( + "test.TestComponent", + ImmutableList.<String>builder() + .add( + "package test;", + "", + "import dagger.Component;", + "import dagger.producers.Producer;", + "import java.util.Set;", + "import javax.inject.Provider;", + "", + "@Component(modules = {SetModule.class})", + "interface TestComponent {") + .add(entryPoints) + .add("}") + .build()); + } +}
diff --git a/javatests/dagger/internal/codegen/SourceFilesTest.java b/javatests/dagger/internal/codegen/SourceFilesTest.java index c2f7dfd6..55e4ce5 100644 --- a/javatests/dagger/internal/codegen/SourceFilesTest.java +++ b/javatests/dagger/internal/codegen/SourceFilesTest.java
@@ -17,9 +17,8 @@ package dagger.internal.codegen; import static com.google.common.truth.Truth.assertThat; -import static dagger.internal.codegen.binding.SourceFiles.simpleVariableName; -import com.squareup.javapoet.ClassName; +import androidx.room.compiler.codegen.XClassName; import dagger.internal.codegen.binding.SourceFiles; import java.util.List; import org.junit.Test; @@ -34,15 +33,15 @@ @Test public void testSimpleVariableName_typeCollisions() { // a handful of boxed types - assertThat(simpleVariableName(ClassName.get(Long.class))).isEqualTo("l"); - assertThat(simpleVariableName(ClassName.get(Double.class))).isEqualTo("d"); + assertThat(simpleVariableName(Long.class)).isEqualTo("l"); + assertThat(simpleVariableName(Double.class)).isEqualTo("d"); // not a boxed type type, but a custom type might collide - assertThat(simpleVariableName(ClassName.get(Int.class))).isEqualTo("i"); + assertThat(simpleVariableName(Int.class)).isEqualTo("i"); // void is the weird pseudo-boxed type - assertThat(simpleVariableName(ClassName.get(Void.class))).isEqualTo("v"); + assertThat(simpleVariableName(Void.class)).isEqualTo("v"); // reflective types - assertThat(simpleVariableName(ClassName.get(Class.class))).isEqualTo("clazz"); - assertThat(simpleVariableName(ClassName.get(Package.class))).isEqualTo("pkg"); + assertThat(simpleVariableName(Class.class)).isEqualTo("clazz"); + assertThat(simpleVariableName(Package.class)).isEqualTo("pkg"); } private static final class For {} @@ -51,13 +50,18 @@ @Test public void testSimpleVariableName_randomKeywords() { - assertThat(simpleVariableName(ClassName.get(For.class))).isEqualTo("for_"); - assertThat(simpleVariableName(ClassName.get(Goto.class))).isEqualTo("goto_"); + assertThat(simpleVariableName(For.class)).isEqualTo("for_"); + assertThat(simpleVariableName(Goto.class)).isEqualTo("goto_"); } @Test public void testSimpleVariableName() { - assertThat(simpleVariableName(ClassName.get(Object.class))).isEqualTo("object"); - assertThat(simpleVariableName(ClassName.get(List.class))).isEqualTo("list"); + assertThat(simpleVariableName(Object.class)).isEqualTo("object"); + assertThat(simpleVariableName(List.class)).isEqualTo("list"); + } + + private static String simpleVariableName(Class<?> clazz) { + return SourceFiles.simpleVariableName( + XClassName.Companion.get(clazz.getPackageName(), clazz.getSimpleName())); } }
diff --git a/javatests/dagger/internal/codegen/XTypesStripTypeNameTest.java b/javatests/dagger/internal/codegen/XTypesStripTypeNameTest.java index 3a3da57..8c23102 100644 --- a/javatests/dagger/internal/codegen/XTypesStripTypeNameTest.java +++ b/javatests/dagger/internal/codegen/XTypesStripTypeNameTest.java
@@ -16,21 +16,15 @@ package dagger.internal.codegen; -import static androidx.room.compiler.processing.util.ProcessorTestExtKt.runProcessorTest; import static com.google.common.truth.Truth.assertThat; import static dagger.internal.codegen.extension.DaggerCollectors.onlyElement; import static dagger.internal.codegen.xprocessing.XTypes.stripVariances; import androidx.room.compiler.processing.XMethodElement; -import androidx.room.compiler.processing.XProcessingEnvConfig; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.util.Source; -import androidx.room.compiler.processing.util.XTestInvocation; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.squareup.javapoet.TypeName; import dagger.testing.compile.CompilerTests; -import java.util.function.Function; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -149,53 +143,39 @@ @Test public void typeVariableSameVariableName() { - runTest( + CompilerTests.invocationCompiler( CompilerTests.javaSource( - "Subject", - "interface Subject {", - " <T extends Bar> Foo<T> method1();", - " <T extends Baz> Foo<T> method2();", - "", - " interface Foo<T> {}", - " interface Bar {}", - " interface Baz {}", - "}"), - invocation -> { - XTypeElement subject = invocation.getProcessingEnv().requireTypeElement("Subject"); - TypeName method1ReturnTypeName = - getDeclaredMethod(subject, "method1").getReturnType().getTypeName(); - TypeName method2ReturnTypeName = - getDeclaredMethod(subject, "method2").getReturnType().getTypeName(); - assertThat(method1ReturnTypeName).isEqualTo(method2ReturnTypeName); - return null; - }); + "Subject", + "interface Subject {", + " <T extends Bar> Foo<T> method1();", + " <T extends Baz> Foo<T> method2();", + "", + " interface Foo<T> {}", + " interface Bar {}", + " interface Baz {}", + "}")) + .compile( + invocation -> { + XTypeElement subject = invocation.getProcessingEnv().requireTypeElement("Subject"); + TypeName method1ReturnTypeName = + getDeclaredMethod(subject, "method1").getReturnType().getTypeName(); + TypeName method2ReturnTypeName = + getDeclaredMethod(subject, "method2").getReturnType().getTypeName(); + assertThat(method1ReturnTypeName).isEqualTo(method2ReturnTypeName); + }); } private static void assertStrippedWildcardTypeNameEquals(Source source, String strippedTypeName) { - runTest( - source, - invocation -> { - XTypeElement subject = invocation.getProcessingEnv().requireTypeElement("Subject"); - TypeName returnTypeName = - getDeclaredMethod(subject, "method").getReturnType().getTypeName(); - assertThat(stripVariances(returnTypeName).toString().replace("Subject.", "")) - .isEqualTo(strippedTypeName); - return null; - }); - } - - private static void runTest(Source source, Function<XTestInvocation, Void> handler) { - runProcessorTest( - ImmutableList.of(source), - /* classpath = */ ImmutableList.of(), - /* options = */ ImmutableMap.of(), - /* javacArguments = */ ImmutableList.of(), - /* kotlincArguments = */ ImmutableList.of(), - /* config = */ new XProcessingEnvConfig.Builder().build(), - /* handler = */ invocation -> { - handler.apply(invocation); - return null; - }); + CompilerTests.invocationCompiler(source) + .compile( + invocation -> { + XTypeElement subject = invocation.getProcessingEnv().requireTypeElement("Subject"); + TypeName returnTypeName = + getDeclaredMethod(subject, "method").getReturnType().getTypeName(); + assertThat(stripVariances(returnTypeName).toString().replace("Subject.", "")) + .isEqualTo(strippedTypeName); + } + ); } private static XMethodElement getDeclaredMethod(XTypeElement typeElement, String jvmName) {
diff --git a/javatests/dagger/internal/codegen/bindinggraphvalidation/BUILD b/javatests/dagger/internal/codegen/bindinggraphvalidation/BUILD index ce7197a..0a1873c 100644 --- a/javatests/dagger/internal/codegen/bindinggraphvalidation/BUILD +++ b/javatests/dagger/internal/codegen/bindinggraphvalidation/BUILD
@@ -25,6 +25,7 @@ srcs = glob(["*.java"]), functional = False, javacopts = DOCLINT_HTML_AND_SYNTAX, + shard_count = 3, deps = [ "//java/dagger/internal/codegen/bindinggraphvalidation", "//java/dagger/internal/codegen/xprocessing",
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 ebea812..0f119c2 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 f522a42..34b0dfe 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 bdd35a5..00ee294 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 2d5efe6..cf3e61c 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 ebea812..0f119c2 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 db44f08..7ab24dd 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0ae501c..23c6cff 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
@@ -1,10 +1,11 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Foo_Factory { private final Provider<Bar> argProvider; @@ -31,6 +34,10 @@ return newInstance(argProvider.get(), argProvider2); } + public static Foo_Factory create(javax.inject.Provider<Bar> argProvider) { + return new Foo_Factory(Providers.asDaggerProvider(argProvider)); + } + public static Foo_Factory create(Provider<Bar> argProvider) { return new Foo_Factory(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 0ae501c..23c6cff 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
@@ -1,10 +1,11 @@ package test; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Foo_Factory { private final Provider<Bar> argProvider; @@ -31,6 +34,10 @@ return newInstance(argProvider.get(), argProvider2); } + public static Foo_Factory create(javax.inject.Provider<Bar> argProvider) { + return new Foo_Factory(Providers.asDaggerProvider(argProvider)); + } + public static Foo_Factory create(Provider<Bar> argProvider) { return new Foo_Factory(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 index b3fc316..b2e2831 100644 --- a/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_DEFAULT_MODE_test.DaggerMyComponent +++ b/javatests/dagger/internal/codegen/goldens/AssistedFactoryTest_testMultipleAssistedFactoryInDifferentComponents_DEFAULT_MODE_test.DaggerMyComponent
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerMyComponent { private DaggerMyComponent() {
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 index 68c5a77..2a23645 100644 --- 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerMyComponent { private DaggerMyComponent() {
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 f94d608..daaf665 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 0726e0f..41faaab 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7aed6ce..e2576ae 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7aed6ce..e2576ae 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 384875a..a4a94cb 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b4fa619..6df65af 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 384875a..a4a94cb 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b4fa619..6df65af 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 510db53..ee2e44d 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c31b4ab..17364a3 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 510db53..ee2e44d 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c31b4ab..17364a3 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 77058c3..133f141 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6583a23..ebc41b7 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 77058c3..133f141 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6583a23..ebc41b7 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 5040a78..325c101 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 10bc365..4910ba9 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 5040a78..325c101 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 10bc365..4910ba9 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 ac6ba38..a0178c5 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 ac6ba38..a0178c5 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 dc3a6e7..59ce365 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 87aba7d..10beda6 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0626b32..19f49ac 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 26b5f28..990d8ca 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 66af8f5..95c8773 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
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 4ce6af3..23bf006 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
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 2f1124b..df9d533 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7d9a5d3..e38e8f3 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 03fcd70..70d58b2 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 03fcd70..70d58b2 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 8d8ddad..70c1303 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 8d8ddad..70c1303 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b79b07d..97f27e4 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
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 e89783c..f3255ca 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
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 a2d1d85..a983d5a 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 42a0386..a595a98 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b284dbd..009e4e8 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b284dbd..009e4e8 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 898e877..af5d9b1 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 898e877..af5d9b1 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d991e42..c0b1ee8 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d991e42..c0b1ee8 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 dd93201..4ce5ae9 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 dd93201..4ce5ae9 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 872646f..8e94a54 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 872646f..8e94a54 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b9a27eb..7cadd4d 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 4caa6e1..501fd25 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_PrimitiveIntegerFactory implements Factory<Integer> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final TestModule_PrimitiveIntegerFactory INSTANCE = new TestModule_PrimitiveIntegerFactory(); + static final TestModule_PrimitiveIntegerFactory INSTANCE = new TestModule_PrimitiveIntegerFactory(); } }
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 b9a27eb..7cadd4d 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 4caa6e1..501fd25 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_PrimitiveIntegerFactory implements Factory<Integer> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final TestModule_PrimitiveIntegerFactory INSTANCE = new TestModule_PrimitiveIntegerFactory(); + static final TestModule_PrimitiveIntegerFactory INSTANCE = new TestModule_PrimitiveIntegerFactory(); } }
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 54425a7..553c4a2 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 96e8708..2b294e0 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_NonNullableStringFactory implements Factory<String> { @Override @@ -36,7 +38,7 @@ } private static final class InstanceHolder { - private static final TestModule_NonNullableStringFactory INSTANCE = new TestModule_NonNullableStringFactory(); + static final TestModule_NonNullableStringFactory INSTANCE = new TestModule_NonNullableStringFactory(); } }
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 54425a7..553c4a2 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 96e8708..2b294e0 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_NonNullableStringFactory implements Factory<String> { @Override @@ -36,7 +38,7 @@ } private static final class InstanceHolder { - private static final TestModule_NonNullableStringFactory INSTANCE = new TestModule_NonNullableStringFactory(); + static final TestModule_NonNullableStringFactory INSTANCE = new TestModule_NonNullableStringFactory(); } }
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 c1a2108..aedfabd 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d88c74e..2f5673b 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 73f067b..489e557 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c20b8f0..22f50bc 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 5558c81..7654c52 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e19505d..c9ae9dd 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 48c0f34..9237934 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 48c0f34..9237934 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 22771bb..cdb0fa7 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 22771bb..cdb0fa7 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 1a79810..c107cec 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 1a79810..c107cec 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e1e3f64..7dee796 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 094c1ff..c85bae0 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
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 108b13d..04c2ad5 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 108b13d..04c2ad5 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 108b13d..04c2ad5 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 108b13d..04c2ad5 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c630533..2fd99c4 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 c630533..2fd99c4 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 7b077e7..e21c509 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 7b077e7..e21c509 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 9fcf3dc..7bc733e 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 9fcf3dc..7bc733e 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 a036546..7f85c85 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7defcfc..d7c83f6 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 bbe89b9..1a677ba 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 bbe89b9..1a677ba 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 98ba4b6..fe34d7b 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 98ba4b6..fe34d7b 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 9b39816..353bc44 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 94ebb33..7e27883 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 99caa07..ef794e6 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 99caa07..ef794e6 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent new file mode 100644 index 0000000..e484861 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent
@@ -0,0 +1,43 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(@Nullable Bar argParam) { + + + } + } +} \ No newline at end of file
diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent new file mode 100644 index 0000000..95c1668 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent
@@ -0,0 +1,43 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(@Nullable Bar argParam) { + + + } + } +}
diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent new file mode 100644 index 0000000..95c1668 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent
@@ -0,0 +1,43 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(@Nullable Bar argParam) { + + + } + } +}
diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent new file mode 100644 index 0000000..95c1668 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent
@@ -0,0 +1,43 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(@Nullable Bar argParam) { + + + } + } +}
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 a2c9032..c89184d 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 5d58c6e..8c5c484 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 59a7cae..68ee495 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 9a84c85..7eabde2 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 13f15e0..e71c32a 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 f2a4aa6..effc678 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent index 094c1ff..c85bae0 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testCmdLineOptionEnabledPrecedesAnnotationDisabled_test.DaggerSimpleComponent
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent index 094c1ff..c85bae0 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitEnabledFromAnnotationSucceeded_test.DaggerSimpleComponent
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerSimpleComponent { private DaggerSimpleComponent() {
diff --git a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent index e1e3f64..7dee796 100644 --- a/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent +++ b/javatests/dagger/internal/codegen/goldens/DaggerProcessingOptionsTest_testFastInitaDisabledFromAnnotationSucceeded_test.DaggerSimpleComponent
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0cf470e..8b138de 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f7bd448..8a86532 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d5ebea6..cab6003 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 dda8836..800a764 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 8a2c7de..8eaaaed 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 5c9ce8a..8abc7f8 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 a8ad72f..92b7b32 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerRequestsSubtypeAsProvider { private DaggerRequestsSubtypeAsProvider() {
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 6f6e32c..474db4f 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerRequestsSubtypeAsProvider { private DaggerRequestsSubtypeAsProvider() {
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 9e96fba..683231a 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 059eaab..258ed43 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a8a4aad..6ab9548 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 40dcf73..2ba405b 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 4877c33..fe9cfaf 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 08c5844..c67cc9e 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e04aae6..28b0f8f 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 2ca627d..30d42c8 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e3d5bf6..8cfcdee 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 93973b6..8d0d51e 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 416d9c2..5f66fd2 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 64762bd..3ec2b3b 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 39dc9c5..a8b4832 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 39dc9c5..a8b4832 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d11d1ab..730f7ef 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 acf83f2..40aeab2 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 deleted file mode 100644 index e752840..0000000 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,75 +0,0 @@ -package test; - -import dagger.internal.DaggerGenerated; -import dagger.internal.DelegateFactory; -import dagger.internal.DoubleCheck; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; -import other.OtherEntryPoint; -import other.OtherEntryPoint_Factory; - -@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<Foo> bindProvider; - - @SuppressWarnings("rawtypes") - private Provider fooImplProvider; - - private TestComponentImpl() { - - initialize(); - - } - - private Object fooImpl() { - return FooImpl_Factory.newInstance(bindProvider); - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.bindProvider = new DelegateFactory<>(); - this.fooImplProvider = FooImpl_Factory.create(bindProvider); - DelegateFactory.setDelegate(bindProvider, DoubleCheck.provider((Provider) fooImplProvider)); - } - - @Override - public OtherEntryPoint getOtherEntryPoint() { - return OtherEntryPoint_Factory.newInstance(fooImpl()); - } - } -}
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 7990079..ab10526 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 deleted file mode 100644 index bf80e63..0000000 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoopScoped_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,97 +0,0 @@ -package test; - -import dagger.internal.DaggerGenerated; -import dagger.internal.DelegateFactory; -import dagger.internal.DoubleCheck; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; -import other.OtherEntryPoint; -import other.OtherEntryPoint_Factory; - -@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<Foo> bindProvider; - - @SuppressWarnings("rawtypes") - private Provider fooImplProvider; - - private TestComponentImpl() { - - initialize(); - - } - - private Object fooImpl() { - return FooImpl_Factory.newInstance(bindProvider); - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.bindProvider = new DelegateFactory<>(); - this.fooImplProvider = new SwitchingProvider<Object>(testComponentImpl, 0); - DelegateFactory.setDelegate(bindProvider, DoubleCheck.provider((Provider) fooImplProvider)); - } - - @Override - public OtherEntryPoint getOtherEntryPoint() { - return OtherEntryPoint_Factory.newInstance(fooImpl()); - } - - 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: // other.FooImpl - return (T) FooImpl_Factory.newInstance(testComponentImpl.bindProvider); - - default: throw new AssertionError(id); - } - } - } - } -}
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 f92f558..90c0f4f 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 deleted file mode 100644 index f13d94a..0000000 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,71 +0,0 @@ -package test; - -import dagger.internal.DaggerGenerated; -import dagger.internal.DelegateFactory; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; -import other.OtherEntryPoint; -import other.OtherEntryPoint_Factory; - -@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; - - @SuppressWarnings("rawtypes") - private Provider fooImplProvider; - - private TestComponentImpl() { - - initialize(); - - } - - private Object fooImpl() { - return FooImpl_Factory.newInstance(fooImplProvider); - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.fooImplProvider = new DelegateFactory<>(); - DelegateFactory.setDelegate(fooImplProvider, FooImpl_Factory.create(fooImplProvider)); - } - - @Override - public OtherEntryPoint getOtherEntryPoint() { - return OtherEntryPoint_Factory.newInstance(fooImpl()); - } - } -}
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 30be4f1..048e7ee 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 deleted file mode 100644 index 27a30fb..0000000 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_inaccessibleTypeBoundInALoop_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,93 +0,0 @@ -package test; - -import dagger.internal.DaggerGenerated; -import dagger.internal.DelegateFactory; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; -import other.OtherEntryPoint; -import other.OtherEntryPoint_Factory; - -@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; - - @SuppressWarnings("rawtypes") - private Provider fooImplProvider; - - private TestComponentImpl() { - - initialize(); - - } - - private Object fooImpl() { - return FooImpl_Factory.newInstance(fooImplProvider); - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.fooImplProvider = new DelegateFactory<>(); - DelegateFactory.setDelegate(fooImplProvider, new SwitchingProvider<Object>(testComponentImpl, 0)); - } - - @Override - public OtherEntryPoint getOtherEntryPoint() { - return OtherEntryPoint_Factory.newInstance(fooImpl()); - } - - 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: // other.FooImpl - return (T) FooImpl_Factory.newInstance(testComponentImpl.fooImplProvider); - - default: throw new AssertionError(id); - } - } - } - } -}
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 7146c06..d004f1b 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 ca51d3f..b45151a 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 deleted file mode 100644 index ce6bcdf..0000000 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,89 +0,0 @@ -package test; - -import dagger.internal.DaggerGenerated; -import dagger.internal.DoubleCheck; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; - -@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; - - @SuppressWarnings("rawtypes") - private Provider fooImplProvider; - - private Provider<Foo> bindProvider; - - private TestComponentImpl() { - - initialize(); - - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.fooImplProvider = new SwitchingProvider<Object>(testComponentImpl, 0); - this.bindProvider = DoubleCheck.provider((Provider) fooImplProvider); - } - - @Override - public Foo getFoo() { - return bindProvider.get(); - } - - 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: // other.FooImpl - return (T) FooImpl_Factory.newInstance(); - - default: throw new AssertionError(id); - } - } - } - } -}
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 c39381b..8709d08 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 8488aba..fc46a0b 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_basicNameCollision_test.InjectConstructor_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<other.pkg.Factory> factoryProvider; @@ -33,6 +36,11 @@ return newInstance(factoryProvider.get()); } + public static InjectConstructor_Factory create( + javax.inject.Provider<other.pkg.Factory> factoryProvider) { + return new InjectConstructor_Factory(Providers.asDaggerProvider(factoryProvider)); + } + public static InjectConstructor_Factory create(Provider<other.pkg.Factory> factoryProvider) { return new InjectConstructor_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 143d1ed..85f3cee 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_boundedGenerics_test.GenericClass_Factory
@@ -2,11 +2,12 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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; @@ -41,6 +44,12 @@ } public static <A extends Number & Comparable<A>, B extends List<? extends String>, C extends List<? super String>> GenericClass_Factory<A, B, C> create( + javax.inject.Provider<A> aProvider, javax.inject.Provider<B> bProvider, + javax.inject.Provider<C> cProvider) { + return new GenericClass_Factory<A, B, C>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider), Providers.asDaggerProvider(cProvider)); + } + + public static <A extends Number & Comparable<A>, B extends List<? extends String>, C extends List<? super String>> GenericClass_Factory<A, B, C> create( Provider<A> aProvider, Provider<B> bProvider, Provider<C> cProvider) { return new GenericClass_Factory<A, B, C>(aProvider, bProvider, cProvider); }
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 ab6d9ae..6e1e620 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_fieldAndMethodGenerics_test.GenericClass_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; @@ -39,6 +42,11 @@ return instance; } + public static <A, B> GenericClass_Factory<A, B> create(javax.inject.Provider<A> aProvider, + javax.inject.Provider<B> bProvider) { + return new GenericClass_Factory<A, B>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + public static <A, B> GenericClass_Factory<A, B> create(Provider<A> aProvider, Provider<B> bProvider) { return new GenericClass_Factory<A, B>(aProvider, bProvider);
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 95e0038..8f16b9a 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_genericClassWithNoDependencies_test.GenericClass_Factory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> { @Override @@ -37,7 +39,7 @@ private static final class InstanceHolder { @SuppressWarnings("rawtypes") - private static final GenericClass_Factory INSTANCE = new GenericClass_Factory(); + static final GenericClass_Factory INSTANCE = new GenericClass_Factory(); } }
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 0c2475c..1558b85 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorAndMembersInjection_test.AllInjections_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class AllInjections_Factory implements Factory<AllInjections> { private final Provider<String> sProvider; @@ -43,6 +46,11 @@ return instance; } + public static AllInjections_Factory create(javax.inject.Provider<String> sProvider, + javax.inject.Provider<String> sProvider2, javax.inject.Provider<String> sProvider3) { + return new AllInjections_Factory(Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(sProvider2), Providers.asDaggerProvider(sProvider3)); + } + public static AllInjections_Factory create(Provider<String> sProvider, Provider<String> sProvider2, Provider<String> sProvider3) { return new AllInjections_Factory(sProvider, sProvider2, sProvider3);
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 6ac47e9..bc48f59 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructorOnGenericClass_test.GenericClass_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_Factory<T> implements Factory<GenericClass<T>> { private final Provider<T> tProvider; @@ -33,6 +36,10 @@ return newInstance(tProvider.get()); } + public static <T> GenericClass_Factory<T> create(javax.inject.Provider<T> tProvider) { + return new GenericClass_Factory<T>(Providers.asDaggerProvider(tProvider)); + } + public static <T> GenericClass_Factory<T> create(Provider<T> tProvider) { return new GenericClass_Factory<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 638815e..8368ed3 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_injectConstructor_test.InjectConstructor_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<String> sProvider; @@ -33,6 +36,10 @@ return newInstance(sProvider.get()); } + public static InjectConstructor_Factory create(javax.inject.Provider<String> sProvider) { + return new InjectConstructor_Factory(Providers.asDaggerProvider(sProvider)); + } + public static InjectConstructor_Factory create(Provider<String> sProvider) { return new InjectConstructor_Factory(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 a5b93b8..687848e 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_multipleSameTypesWithGenericsAndQualifiersAndLazies_test.GenericClass_Factory
@@ -4,10 +4,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata("test.QualifierA") @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; @@ -81,6 +84,17 @@ return newInstance(aProvider.get(), a2Provider.get(), paProvider, qaProvider.get(), DoubleCheck.lazy(laProvider), sProvider.get(), s2Provider.get(), psProvider, qsProvider.get(), DoubleCheck.lazy(lsProvider), bProvider.get(), b2Provider.get(), pbProvider, qbProvider.get(), DoubleCheck.lazy(lbProvider)); } + public static <A, B> GenericClass_Factory<A, B> create(javax.inject.Provider<A> aProvider, + javax.inject.Provider<A> a2Provider, javax.inject.Provider<A> paProvider, + javax.inject.Provider<A> qaProvider, javax.inject.Provider<A> laProvider, + javax.inject.Provider<String> sProvider, javax.inject.Provider<String> s2Provider, + javax.inject.Provider<String> psProvider, javax.inject.Provider<String> qsProvider, + javax.inject.Provider<String> lsProvider, javax.inject.Provider<B> bProvider, + javax.inject.Provider<B> b2Provider, javax.inject.Provider<B> pbProvider, + javax.inject.Provider<B> qbProvider, javax.inject.Provider<B> lbProvider) { + return new GenericClass_Factory<A, B>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(a2Provider), Providers.asDaggerProvider(paProvider), Providers.asDaggerProvider(qaProvider), Providers.asDaggerProvider(laProvider), Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(s2Provider), Providers.asDaggerProvider(psProvider), Providers.asDaggerProvider(qsProvider), Providers.asDaggerProvider(lsProvider), Providers.asDaggerProvider(bProvider), Providers.asDaggerProvider(b2Provider), Providers.asDaggerProvider(pbProvider), Providers.asDaggerProvider(qbProvider), Providers.asDaggerProvider(lbProvider)); + } + public static <A, B> GenericClass_Factory<A, B> create(Provider<A> aProvider, Provider<A> a2Provider, Provider<A> paProvider, Provider<A> qaProvider, Provider<A> laProvider, Provider<String> sProvider, Provider<String> s2Provider, @@ -90,9 +104,9 @@ return new GenericClass_Factory<A, B>(aProvider, a2Provider, paProvider, qaProvider, laProvider, sProvider, s2Provider, psProvider, qsProvider, lsProvider, bProvider, b2Provider, pbProvider, qbProvider, lbProvider); } - public static <A, B> GenericClass<A, B> newInstance(A a, A a2, Provider<A> pa, A qa, Lazy<A> la, - String s, String s2, Provider<String> ps, String qs, Lazy<String> ls, B b, B b2, - Provider<B> pb, B qb, Lazy<B> lb) { + public static <A, B> GenericClass<A, B> newInstance(A a, A a2, javax.inject.Provider<A> pa, A qa, + Lazy<A> la, String s, String s2, javax.inject.Provider<String> ps, String qs, Lazy<String> ls, + B b, B b2, javax.inject.Provider<B> pb, B qb, Lazy<B> lb) { return new GenericClass<A, B>(a, a2, pa, qa, la, s, s2, ps, qs, ls, b, b2, pb, qb, lb); } }
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 f3337a1..0615073 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_nestedNameCollision_test.InjectConstructor_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; import other.pkg.Outer; @ScopeMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<Outer.Factory> factoryProvider; @@ -34,6 +37,11 @@ return newInstance(factoryProvider.get()); } + public static InjectConstructor_Factory create( + javax.inject.Provider<Outer.Factory> factoryProvider) { + return new InjectConstructor_Factory(Providers.asDaggerProvider(factoryProvider)); + } + public static InjectConstructor_Factory create(Provider<Outer.Factory> factoryProvider) { return new InjectConstructor_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 41c6c72..c8d172b 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_noDeps_test.SimpleType_Factory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class SimpleType_Factory implements Factory<SimpleType> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final SimpleType_Factory INSTANCE = new SimpleType_Factory(); + static final SimpleType_Factory INSTANCE = new SimpleType_Factory(); } }
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 f65c9c5..2327674 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_samePackageNameCollision_test.InjectConstructor_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<other.pkg.CommonName> otherPackageProvider; @@ -38,6 +41,12 @@ } public static InjectConstructor_Factory create( + javax.inject.Provider<other.pkg.CommonName> otherPackageProvider, + javax.inject.Provider<CommonName> samePackageProvider) { + return new InjectConstructor_Factory(Providers.asDaggerProvider(otherPackageProvider), Providers.asDaggerProvider(samePackageProvider)); + } + + public static InjectConstructor_Factory create( Provider<other.pkg.CommonName> otherPackageProvider, Provider<CommonName> samePackageProvider) { return new InjectConstructor_Factory(otherPackageProvider, samePackageProvider);
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 424c614..b0c7a56 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class OuterType_A_Factory implements Factory<OuterType.A> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final OuterType_A_Factory INSTANCE = new OuterType_A_Factory(); + static final OuterType_A_Factory INSTANCE = new OuterType_A_Factory(); } }
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 1f00f95..7771f5f 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata("test.FooBaseConstructorQualifier") @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FooBase_Factory implements Factory<FooBase> { private final Provider<Integer> iProvider; @@ -43,6 +46,11 @@ return instance; } + public static FooBase_Factory create(javax.inject.Provider<Integer> iProvider, + javax.inject.Provider<String> injectFieldProvider, javax.inject.Provider<Float> fProvider) { + return new FooBase_Factory(Providers.asDaggerProvider(iProvider), Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + public static FooBase_Factory create(Provider<Integer> iProvider, Provider<String> injectFieldProvider, Provider<Float> fProvider) { return new FooBase_Factory(iProvider, injectFieldProvider, fProvider);
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 5e865ff..be0404b 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.FooBase_MembersInjector
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata({ "test.FooBaseFieldQualifier", @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FooBase_MembersInjector implements MembersInjector<FooBase> { private final Provider<String> injectFieldProvider; @@ -38,6 +41,11 @@ return new FooBase_MembersInjector(injectFieldProvider, fProvider); } + public static MembersInjector<FooBase> create(javax.inject.Provider<String> injectFieldProvider, + javax.inject.Provider<Float> fProvider) { + return new FooBase_MembersInjector(Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + @Override public void injectMembers(FooBase instance) { injectInjectField(instance, injectFieldProvider.get());
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 48d9102..7b4c1d6 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata("test.FooConstructorQualifier") @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Foo_Factory implements Factory<Foo> { private final Provider<Integer> iProvider; @@ -47,6 +50,12 @@ return instance; } + public static Foo_Factory create(javax.inject.Provider<Integer> iProvider, + javax.inject.Provider<String> injectFieldProvider, + javax.inject.Provider<String> injectFieldProvider2, javax.inject.Provider<Float> fProvider) { + return new Foo_Factory(Providers.asDaggerProvider(iProvider), Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(injectFieldProvider2), Providers.asDaggerProvider(fProvider)); + } + public static Foo_Factory create(Provider<Integer> iProvider, Provider<String> injectFieldProvider, Provider<String> injectFieldProvider2, Provider<Float> fProvider) {
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 7485836..5352370 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testBaseClassQualifierMetadata_test.Foo_MembersInjector
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata({ "test.FooFieldQualifier", @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Foo_MembersInjector implements MembersInjector<Foo> { private final Provider<String> injectFieldProvider; @@ -42,6 +45,11 @@ return new Foo_MembersInjector(injectFieldProvider, injectFieldProvider2, fProvider); } + public static MembersInjector<Foo> create(javax.inject.Provider<String> injectFieldProvider, + javax.inject.Provider<String> injectFieldProvider2, javax.inject.Provider<Float> fProvider) { + return new Foo_MembersInjector(Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(injectFieldProvider2), Providers.asDaggerProvider(fProvider)); + } + @Override public void injectMembers(Foo instance) { FooBase_MembersInjector.injectInjectField(instance, injectFieldProvider.get());
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 2d100f6..4d0c734 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata({ @@ -22,7 +23,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class SomeBinding_Factory implements Factory<SomeBinding> { private final Provider<String> str1Provider; @@ -49,6 +52,12 @@ return instance; } + public static SomeBinding_Factory create(javax.inject.Provider<String> str1Provider, + javax.inject.Provider<String> str2Provider, javax.inject.Provider<String> injectFieldProvider, + javax.inject.Provider<Float> fProvider) { + return new SomeBinding_Factory(Providers.asDaggerProvider(str1Provider), Providers.asDaggerProvider(str2Provider), Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + public static SomeBinding_Factory create(Provider<String> str1Provider, Provider<String> str2Provider, Provider<String> injectFieldProvider, Provider<Float> fProvider) {
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 a5707af..63ba30f 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testComplexQualifierMetadata_test.SomeBinding_MembersInjector
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata({ "test.QualifierWithValue", @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class SomeBinding_MembersInjector implements MembersInjector<SomeBinding> { private final Provider<String> injectFieldProvider; @@ -39,6 +42,11 @@ return new SomeBinding_MembersInjector(injectFieldProvider, fProvider); } + public static MembersInjector<SomeBinding> create( + javax.inject.Provider<String> injectFieldProvider, javax.inject.Provider<Float> fProvider) { + return new SomeBinding_MembersInjector(Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + @Override public void injectMembers(SomeBinding instance) { injectInjectField(instance, injectFieldProvider.get());
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 40690b3..441131f 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata("test.ConstructorParameterQualifier") @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class SomeBinding_Factory implements Factory<SomeBinding> { private final Provider<Double> dProvider; @@ -43,6 +46,11 @@ return instance; } + public static SomeBinding_Factory create(javax.inject.Provider<Double> dProvider, + javax.inject.Provider<String> injectFieldProvider, javax.inject.Provider<Float> fProvider) { + return new SomeBinding_Factory(Providers.asDaggerProvider(dProvider), Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + public static SomeBinding_Factory create(Provider<Double> dProvider, Provider<String> injectFieldProvider, Provider<Float> fProvider) { return new SomeBinding_Factory(dProvider, injectFieldProvider, fProvider);
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 a8ca780..aa14719 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testQualifierMetadata_test.SomeBinding_MembersInjector
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata({ "test.FieldQualifier", @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class SomeBinding_MembersInjector implements MembersInjector<SomeBinding> { private final Provider<String> injectFieldProvider; @@ -39,6 +42,11 @@ return new SomeBinding_MembersInjector(injectFieldProvider, fProvider); } + public static MembersInjector<SomeBinding> create( + javax.inject.Provider<String> injectFieldProvider, javax.inject.Provider<Float> fProvider) { + return new SomeBinding_MembersInjector(Providers.asDaggerProvider(injectFieldProvider), Providers.asDaggerProvider(fProvider)); + } + @Override public void injectMembers(SomeBinding instance) { injectInjectField(instance, injectFieldProvider.get());
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 d949bdd..d031232 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadataWithCustomScope_test.ScopedBinding_Factory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ScopedBinding_Factory implements Factory<ScopedBinding> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final ScopedBinding_Factory INSTANCE = new ScopedBinding_Factory(); + static final ScopedBinding_Factory INSTANCE = new ScopedBinding_Factory(); } }
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 5682bb0..3368c1a 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_testScopedMetadata_test.ScopedBinding_Factory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ScopedBinding_Factory implements Factory<ScopedBinding> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final ScopedBinding_Factory INSTANCE = new ScopedBinding_Factory(); + static final ScopedBinding_Factory INSTANCE = new ScopedBinding_Factory(); } }
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 116df17..9c722dc 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_twoGenericTypes_test.GenericClass_Factory
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_Factory<A, B> implements Factory<GenericClass<A, B>> { private final Provider<A> aProvider; @@ -36,6 +39,11 @@ return newInstance(aProvider.get(), bProvider.get()); } + public static <A, B> GenericClass_Factory<A, B> create(javax.inject.Provider<A> aProvider, + javax.inject.Provider<B> bProvider) { + return new GenericClass_Factory<A, B>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + public static <A, B> GenericClass_Factory<A, B> create(Provider<A> aProvider, Provider<B> bProvider) { return new GenericClass_Factory<A, B>(aProvider, bProvider);
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 681a4b6..bdafd5f 100644 --- a/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory +++ b/javatests/dagger/internal/codegen/goldens/InjectConstructorFactoryGeneratorTest_wildcardDependency_test.InjectConstructor_Factory
@@ -2,11 +2,12 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectConstructor_Factory implements Factory<InjectConstructor> { private final Provider<List<?>> objectsProvider; @@ -34,6 +37,10 @@ return newInstance(objectsProvider.get()); } + public static InjectConstructor_Factory create(javax.inject.Provider<List<?>> objectsProvider) { + return new InjectConstructor_Factory(Providers.asDaggerProvider(objectsProvider)); + } + public static InjectConstructor_Factory create(Provider<List<?>> objectsProvider) { return new InjectConstructor_Factory(objectsProvider); }
diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent similarity index 61% rename from javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent rename to javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent index 01ffe86..7cbc139 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_DEFAULT_MODE_test.DaggerTestComponent
@@ -1,10 +1,10 @@ package test; +import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.DoubleCheck; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; +import dagger.internal.LazyClassKeyMap; +import java.util.Map; +import javax.annotation.processing.Generated; @DaggerGenerated @Generated( @@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -42,22 +44,15 @@ private static final class TestComponentImpl implements TestComponent { private final TestComponentImpl testComponentImpl = this; - private Provider<Foo> bindProvider; - private TestComponentImpl() { - initialize(); } - @SuppressWarnings("unchecked") - private void initialize() { - this.bindProvider = DoubleCheck.provider((Provider) FooImpl_Factory.create()); - } - @Override - public Foo getFoo() { - return bindProvider.get(); + public Map<Class<?>, Integer> classKey() { + return LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(MapKeyBindingsModule_ClassKey_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey(), MapKeyBindingsModule_ClassKey2_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey2())); } } } +
diff --git a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent similarity index 61% copy from javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent copy to javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent index 01ffe86..7cbc139 100644 --- a/javatests/dagger/internal/codegen/goldens/InaccessibleTypeBindsTest_scopedInaccessibleTypeBound_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_lazyClassKeySimilarQualifiedName_doesNotConflict_FAST_INIT_MODE_test.DaggerTestComponent
@@ -1,10 +1,10 @@ package test; +import com.google.common.collect.ImmutableMap; import dagger.internal.DaggerGenerated; -import dagger.internal.DoubleCheck; -import dagger.internal.Provider; -import javax.annotation.Generated; -import other.FooImpl_Factory; +import dagger.internal.LazyClassKeyMap; +import java.util.Map; +import javax.annotation.processing.Generated; @DaggerGenerated @Generated( @@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -42,22 +44,15 @@ private static final class TestComponentImpl implements TestComponent { private final TestComponentImpl testComponentImpl = this; - private Provider<Foo> bindProvider; - private TestComponentImpl() { - initialize(); } - @SuppressWarnings("unchecked") - private void initialize() { - this.bindProvider = DoubleCheck.provider((Provider) FooImpl_Factory.create()); - } - @Override - public Foo getFoo() { - return bindProvider.get(); + public Map<Class<?>, Integer> classKey() { + return LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(MapKeyBindingsModule_ClassKey_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey(), MapKeyBindingsModule_ClassKey2_LazyMapKey.lazyClassKeyName, MapKeyBindingsModule.classKey2())); } } } +
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 index 63a07ab..929342a 100644 --- 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MapModule_ClassKeyMapKey { @KeepFieldType
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 index 3e00ffd..b0115fc 100644 --- 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() {
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 index eff6a40..44f0045 100644 --- a/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent +++ b/javatests/dagger/internal/codegen/goldens/LazyClassKeyMapBindingComponentProcessorTest_mapBindingsWithInaccessibleKeys_DEFAULT_MODE_test.DaggerTestComponent
@@ -2,7 +2,6 @@ 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; @@ -11,6 +10,7 @@ import mapkeys.MapKeys; import mapkeys.MapModule; import mapkeys.MapModule_ClassKeyFactory; +import mapkeys.MapModule_ClassKey_LazyMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueFactory; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueFactory; @@ -28,7 +28,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -66,13 +68,13 @@ @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.mapOfClassOfAndIntegerProvider = LazyClassKeyMap.MapFactory.<Integer>of(MapFactory.<String, Integer>builder(1).put(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, 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())); + return LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, MapModule.classKey())); } @Override @@ -89,11 +91,6 @@ 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 index 63a07ab..929342a 100644 --- 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MapModule_ClassKeyMapKey { @KeepFieldType
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 index 3e00ffd..b0115fc 100644 --- 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey { private MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey() {
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 index 478b010..363be57 100644 --- 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
@@ -2,13 +2,13 @@ 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_ClassKey_LazyMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleAnnotationValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleArrayValueMapKey; import mapkeys.MapModule_ComplexKeyWithInaccessibleValueMapKey; @@ -23,7 +23,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -100,7 +102,7 @@ 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())); + return (T) LazyClassKeyMap.<Integer>of(ImmutableMap.<String, Integer>of(MapModule_ClassKey_LazyMapKey.lazyClassKeyName, 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()); @@ -109,11 +111,6 @@ } } } - - @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 b348b61..602ccff 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b348b61..602ccff 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 dbffedd..6370b02 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 54f6250..ec0efd9 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -110,10 +112,10 @@ case 0: // java.util.Map<test.PathEnum,javax.inject.Provider<test.Handler>> 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 + case 1: // java.util.Map<test.PathEnum,test.Handler> test.MapModuleOne#provideAdminHandler return (T) MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(testComponentImpl.mapModuleOne); - case 2: // java.util.Map<test.PathEnum,javax.inject.Provider<test.Handler>> test.MapModuleTwo#provideLoginHandler + case 2: // java.util.Map<test.PathEnum,test.Handler> test.MapModuleTwo#provideLoginHandler return (T) MapModuleTwo_ProvideLoginHandlerFactory.provideLoginHandler(testComponentImpl.mapModuleTwo); default: throw new AssertionError(id);
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 209220e..d66dad1 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f65280b..4485b14 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 2b35d46..fd01938 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
@@ -29,7 +29,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 209220e..d66dad1 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f65280b..4485b14 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 2b35d46..fd01938 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
@@ -29,7 +29,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 e2d93ec..70573d2 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 c3f0578..21caca8 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 cd24892..c8d2b01 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 47a7d8b..e497c98 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -110,10 +112,10 @@ case 0: // java.util.Map<java.lang.String,javax.inject.Provider<test.Handler>> 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 + case 1: // java.util.Map<java.lang.String,test.Handler> test.MapModuleOne#provideAdminHandler return (T) MapModuleOne_ProvideAdminHandlerFactory.provideAdminHandler(testComponentImpl.mapModuleOne); - case 2: // java.util.Map<java.lang.String,javax.inject.Provider<test.Handler>> test.MapModuleTwo#provideLoginHandler + case 2: // java.util.Map<java.lang.String,test.Handler> test.MapModuleTwo#provideLoginHandler return (T) MapModuleTwo_ProvideLoginHandlerFactory.provideLoginHandler(testComponentImpl.mapModuleTwo); default: throw new AssertionError(id);
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 bbba316..9674b0b 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 d057b50..89a4c43 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 37bbf79..175cd39 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 37bbf79..175cd39 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f47f081..dc4158c 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0acd7f1..d24c78b 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -109,16 +111,16 @@ @Override public T get() { switch (id) { - case 0: // java.util.Map<java.lang.Integer,javax.inject.Provider<java.lang.Integer>> test.MapModule#provideInt + case 0: // java.util.Map<java.lang.Integer,java.lang.Integer> test.MapModule#provideInt return (T) (Integer) MapModule.provideInt(); - case 1: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong0 + case 1: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong0 return (T) (Long) MapModule.provideLong0(); - case 2: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong1 + case 2: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong1 return (T) (Long) MapModule.provideLong1(); - case 3: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong2 + case 3: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong2 return (T) (Long) MapModule.provideLong2(); default: throw new AssertionError(id);
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 8ae5d82..0c598e4 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 8ae5d82..0c598e4 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f4f6564..13f9890 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f4f6564..13f9890 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 24c5619..3f40b31 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 24c5619..3f40b31 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 5520281..e00a7fa 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 12346c8..ffa1646 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -91,13 +93,13 @@ @Override public T get() { switch (id) { - case 0: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.SubcomponentMapModule#provideLong3 + case 0: // java.util.Map<java.lang.Long,java.lang.Long> test.SubcomponentMapModule#provideLong3 return (T) (Long) SubcomponentMapModule.provideLong3(); - case 1: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.SubcomponentMapModule#provideLong4 + case 1: // java.util.Map<java.lang.Long,java.lang.Long> test.SubcomponentMapModule#provideLong4 return (T) (Long) SubcomponentMapModule.provideLong4(); - case 2: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.SubcomponentMapModule#provideLong5 + case 2: // java.util.Map<java.lang.Long,java.lang.Long> test.SubcomponentMapModule#provideLong5 return (T) (Long) SubcomponentMapModule.provideLong5(); default: throw new AssertionError(id); @@ -180,16 +182,16 @@ @Override public T get() { switch (id) { - case 0: // java.util.Map<java.lang.Integer,javax.inject.Provider<java.lang.Integer>> test.MapModule#provideInt + case 0: // java.util.Map<java.lang.Integer,java.lang.Integer> test.MapModule#provideInt return (T) (Integer) MapModule.provideInt(); - case 1: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong0 + case 1: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong0 return (T) (Long) MapModule.provideLong0(); - case 2: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong1 + case 2: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong1 return (T) (Long) MapModule.provideLong1(); - case 3: // java.util.Map<java.lang.Long,javax.inject.Provider<java.lang.Long>> test.MapModule#provideLong2 + case 3: // java.util.Map<java.lang.Long,java.lang.Long> test.MapModule#provideLong2 return (T) (Long) MapModule.provideLong2(); default: throw new AssertionError(id);
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 dc29708..7d54ce0 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 dc29708..7d54ce0 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0ac6e9f..aad298b 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0ac6e9f..aad298b 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 cc45f79..f051e2a 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Inaccessible_MembersInjector implements MembersInjector<Inaccessible> { private final Provider<Foo> fooProvider; @@ -35,6 +38,11 @@ return new Inaccessible_MembersInjector(fooProvider, fooProvider2); } + public static MembersInjector<Inaccessible> create(javax.inject.Provider<Foo> fooProvider, + javax.inject.Provider<Foo> fooProvider2) { + return new Inaccessible_MembersInjector(Providers.asDaggerProvider(fooProvider), Providers.asDaggerProvider(fooProvider2)); + } + @Override public void injectMembers(Inaccessible instance) { injectFoo(instance, fooProvider.get());
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 5f232b1..63a1650 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 cc45f79..f051e2a 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Inaccessible_MembersInjector implements MembersInjector<Inaccessible> { private final Provider<Foo> fooProvider; @@ -35,6 +38,11 @@ return new Inaccessible_MembersInjector(fooProvider, fooProvider2); } + public static MembersInjector<Inaccessible> create(javax.inject.Provider<Foo> fooProvider, + javax.inject.Provider<Foo> fooProvider2) { + return new Inaccessible_MembersInjector(Providers.asDaggerProvider(fooProvider), Providers.asDaggerProvider(fooProvider2)); + } + @Override public void injectMembers(Inaccessible instance) { injectFoo(instance, fooProvider.get());
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 5f232b1..63a1650 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c17dea0..7a20d14 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
@@ -21,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 854a429..bc1ffbe 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
@@ -21,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 5b4932f..d2b3141 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; @@ -31,6 +34,10 @@ return new OuterType_B_MembersInjector(aProvider); } + public static MembersInjector<OuterType.B> create(javax.inject.Provider<OuterType.A> aProvider) { + return new OuterType_B_MembersInjector(Providers.asDaggerProvider(aProvider)); + } + @Override public void injectMembers(OuterType.B instance) { injectA(instance, aProvider.get());
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 5b4932f..d2b3141 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; @@ -31,6 +34,10 @@ return new OuterType_B_MembersInjector(aProvider); } + public static MembersInjector<OuterType.B> create(javax.inject.Provider<OuterType.A> aProvider) { + return new OuterType_B_MembersInjector(Providers.asDaggerProvider(aProvider)); + } + @Override public void injectMembers(OuterType.B instance) { injectA(instance, aProvider.get());
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 70415a8..5c1efb9 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_MembersInjector<A, B> implements MembersInjector<GenericClass<A, B>> { private final Provider<A> aProvider; @@ -35,6 +38,11 @@ return new GenericClass_MembersInjector<A, B>(aProvider, bProvider); } + public static <A, B> MembersInjector<GenericClass<A, B>> create( + javax.inject.Provider<A> aProvider, javax.inject.Provider<B> bProvider) { + return new GenericClass_MembersInjector<A, B>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + @Override public void injectMembers(GenericClass<A, B> instance) { injectA(instance, aProvider.get());
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 70415a8..5c1efb9 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class GenericClass_MembersInjector<A, B> implements MembersInjector<GenericClass<A, B>> { private final Provider<A> aProvider; @@ -35,6 +38,11 @@ return new GenericClass_MembersInjector<A, B>(aProvider, bProvider); } + public static <A, B> MembersInjector<GenericClass<A, B>> create( + javax.inject.Provider<A> aProvider, javax.inject.Provider<B> bProvider) { + return new GenericClass_MembersInjector<A, B>(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + @Override public void injectMembers(GenericClass<A, B> instance) { injectA(instance, aProvider.get());
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 2f69706..abd1246 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Child_MembersInjector implements MembersInjector<Child> { private final Provider<Foo> objectProvider; @@ -35,6 +38,11 @@ return new Child_MembersInjector(objectProvider, objectProvider2); } + public static MembersInjector<Child> create(javax.inject.Provider<Foo> objectProvider, + javax.inject.Provider<Bar> objectProvider2) { + return new Child_MembersInjector(Providers.asDaggerProvider(objectProvider), Providers.asDaggerProvider(objectProvider2)); + } + @Override public void injectMembers(Child instance) { Parent_MembersInjector.injectObject(instance, objectProvider.get());
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 2f69706..abd1246 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Child_MembersInjector implements MembersInjector<Child> { private final Provider<Foo> objectProvider; @@ -35,6 +38,11 @@ return new Child_MembersInjector(objectProvider, objectProvider2); } + public static MembersInjector<Child> create(javax.inject.Provider<Foo> objectProvider, + javax.inject.Provider<Bar> objectProvider2) { + return new Child_MembersInjector(Providers.asDaggerProvider(objectProvider), Providers.asDaggerProvider(objectProvider2)); + } + @Override public void injectMembers(Child instance) { Parent_MembersInjector.injectObject(instance, objectProvider.get());
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 46faeb8..e5f2745 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
@@ -3,10 +3,11 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; import javax.inject.Named; -import javax.inject.Provider; @QualifierMetadata("javax.inject.Named") @DaggerGenerated @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FieldInjectionWithQualifier_MembersInjector implements MembersInjector<FieldInjectionWithQualifier> { private final Provider<String> aProvider; @@ -37,6 +40,11 @@ return new FieldInjectionWithQualifier_MembersInjector(aProvider, bProvider); } + public static MembersInjector<FieldInjectionWithQualifier> create( + javax.inject.Provider<String> aProvider, javax.inject.Provider<String> bProvider) { + return new FieldInjectionWithQualifier_MembersInjector(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + @Override public void injectMembers(FieldInjectionWithQualifier instance) { injectA(instance, aProvider.get());
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 46faeb8..e5f2745 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
@@ -3,10 +3,11 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; import javax.inject.Named; -import javax.inject.Provider; @QualifierMetadata("javax.inject.Named") @DaggerGenerated @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FieldInjectionWithQualifier_MembersInjector implements MembersInjector<FieldInjectionWithQualifier> { private final Provider<String> aProvider; @@ -37,6 +40,11 @@ return new FieldInjectionWithQualifier_MembersInjector(aProvider, bProvider); } + public static MembersInjector<FieldInjectionWithQualifier> create( + javax.inject.Provider<String> aProvider, javax.inject.Provider<String> bProvider) { + return new FieldInjectionWithQualifier_MembersInjector(Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider)); + } + @Override public void injectMembers(FieldInjectionWithQualifier instance) { injectA(instance, aProvider.get());
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 b0af865..ebb9deb 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
@@ -5,9 +5,10 @@ import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { private final Provider<String> stringProvider; @@ -41,6 +44,12 @@ return new FieldInjection_MembersInjector(stringProvider, stringProvider2, stringProvider3); } + public static MembersInjector<FieldInjection> create(javax.inject.Provider<String> stringProvider, + javax.inject.Provider<String> stringProvider2, + javax.inject.Provider<String> stringProvider3) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(stringProvider2), Providers.asDaggerProvider(stringProvider3)); + } + @Override public void injectMembers(FieldInjection instance) { injectString(instance, stringProvider.get()); @@ -59,7 +68,8 @@ } @InjectedFieldSignature("test.FieldInjection.stringProvider") - public static void injectStringProvider(Object instance, Provider<String> stringProvider) { + public static void injectStringProvider(Object instance, + javax.inject.Provider<String> stringProvider) { ((FieldInjection) instance).stringProvider = 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 b0af865..ebb9deb 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
@@ -5,9 +5,10 @@ import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { private final Provider<String> stringProvider; @@ -41,6 +44,12 @@ return new FieldInjection_MembersInjector(stringProvider, stringProvider2, stringProvider3); } + public static MembersInjector<FieldInjection> create(javax.inject.Provider<String> stringProvider, + javax.inject.Provider<String> stringProvider2, + javax.inject.Provider<String> stringProvider3) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(stringProvider2), Providers.asDaggerProvider(stringProvider3)); + } + @Override public void injectMembers(FieldInjection instance) { injectString(instance, stringProvider.get()); @@ -59,7 +68,8 @@ } @InjectedFieldSignature("test.FieldInjection.stringProvider") - public static void injectStringProvider(Object instance, Provider<String> stringProvider) { + public static void injectStringProvider(Object instance, + javax.inject.Provider<String> stringProvider) { ((FieldInjection) instance).stringProvider = 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 0c67f59..34fcdd4 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class AllInjections_MembersInjector implements MembersInjector<AllInjections> { private final Provider<String> sProvider; @@ -35,6 +38,11 @@ return new AllInjections_MembersInjector(sProvider, sProvider2); } + public static MembersInjector<AllInjections> create(javax.inject.Provider<String> sProvider, + javax.inject.Provider<String> sProvider2) { + return new AllInjections_MembersInjector(Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(sProvider2)); + } + @Override public void injectMembers(AllInjections instance) { injectS(instance, sProvider.get());
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 0c67f59..34fcdd4 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class AllInjections_MembersInjector implements MembersInjector<AllInjections> { private final Provider<String> sProvider; @@ -35,6 +38,11 @@ return new AllInjections_MembersInjector(sProvider, sProvider2); } + public static MembersInjector<AllInjections> create(javax.inject.Provider<String> sProvider, + javax.inject.Provider<String> sProvider2) { + return new AllInjections_MembersInjector(Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(sProvider2)); + } + @Override public void injectMembers(AllInjections instance) { injectS(instance, sProvider.get());
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 b63c408..458ce48 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
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectedType_Factory implements Factory<InjectedType> { private final Provider<Integer> primitiveIntProvider; @@ -40,6 +43,11 @@ return instance; } + public static InjectedType_Factory create(javax.inject.Provider<Integer> primitiveIntProvider, + javax.inject.Provider<Integer> boxedIntProvider) { + return new InjectedType_Factory(Providers.asDaggerProvider(primitiveIntProvider), Providers.asDaggerProvider(boxedIntProvider)); + } + public static InjectedType_Factory create(Provider<Integer> primitiveIntProvider, Provider<Integer> boxedIntProvider) { return new InjectedType_Factory(primitiveIntProvider, boxedIntProvider);
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 f288697..cc58fd5 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectedType_MembersInjector implements MembersInjector<InjectedType> { private final Provider<Integer> primitiveIntProvider; @@ -36,6 +39,12 @@ return new InjectedType_MembersInjector(primitiveIntProvider, boxedIntProvider); } + public static MembersInjector<InjectedType> create( + javax.inject.Provider<Integer> primitiveIntProvider, + javax.inject.Provider<Integer> boxedIntProvider) { + return new InjectedType_MembersInjector(Providers.asDaggerProvider(primitiveIntProvider), Providers.asDaggerProvider(boxedIntProvider)); + } + @Override public void injectMembers(InjectedType instance) { injectPrimitiveInt(instance, primitiveIntProvider.get());
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 b63c408..458ce48 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
@@ -2,10 +2,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectedType_Factory implements Factory<InjectedType> { private final Provider<Integer> primitiveIntProvider; @@ -40,6 +43,11 @@ return instance; } + public static InjectedType_Factory create(javax.inject.Provider<Integer> primitiveIntProvider, + javax.inject.Provider<Integer> boxedIntProvider) { + return new InjectedType_Factory(Providers.asDaggerProvider(primitiveIntProvider), Providers.asDaggerProvider(boxedIntProvider)); + } + public static InjectedType_Factory create(Provider<Integer> primitiveIntProvider, Provider<Integer> boxedIntProvider) { return new InjectedType_Factory(primitiveIntProvider, boxedIntProvider);
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 f288697..cc58fd5 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class InjectedType_MembersInjector implements MembersInjector<InjectedType> { private final Provider<Integer> primitiveIntProvider; @@ -36,6 +39,12 @@ return new InjectedType_MembersInjector(primitiveIntProvider, boxedIntProvider); } + public static MembersInjector<InjectedType> create( + javax.inject.Provider<Integer> primitiveIntProvider, + javax.inject.Provider<Integer> boxedIntProvider) { + return new InjectedType_MembersInjector(Providers.asDaggerProvider(primitiveIntProvider), Providers.asDaggerProvider(boxedIntProvider)); + } + @Override public void injectMembers(InjectedType instance) { injectPrimitiveInt(instance, primitiveIntProvider.get());
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_DEFAULT_MODE_test.MyClass_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_DEFAULT_MODE_test.MyClass_MembersInjector new file mode 100644 index 0000000..17f220a --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_DEFAULT_MODE_test.MyClass_MembersInjector
@@ -0,0 +1,65 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; +import org.jetbrains.annotations.Nullable; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class MyClass_MembersInjector implements MembersInjector<MyClass> { + private final Provider<String> nullableStringProvider; + + private final Provider<Object> nullableObjectProvider; + + public MyClass_MembersInjector(Provider<String> nullableStringProvider, + Provider<Object> nullableObjectProvider) { + this.nullableStringProvider = nullableStringProvider; + this.nullableObjectProvider = nullableObjectProvider; + } + + public static MembersInjector<MyClass> create(Provider<String> nullableStringProvider, + Provider<Object> nullableObjectProvider) { + return new MyClass_MembersInjector(nullableStringProvider, nullableObjectProvider); + } + + public static MembersInjector<MyClass> create( + javax.inject.Provider<String> nullableStringProvider, + javax.inject.Provider<Object> nullableObjectProvider) { + return new MyClass_MembersInjector(Providers.asDaggerProvider(nullableStringProvider), Providers.asDaggerProvider(nullableObjectProvider)); + } + + @Override + public void injectMembers(MyClass instance) { + injectNullableString(instance, nullableStringProvider.get()); + injectNullableObject(instance, nullableObjectProvider.get()); + } + + @InjectedFieldSignature("test.MyClass.nullableString") + public static void injectNullableString(MyClass instance, @Nullable String nullableString) { + instance.nullableString = nullableString; + } + + @InjectedFieldSignature("test.MyClass.nullableObject") + public static void injectNullableObject(MyClass instance, @Nullable Object nullableObject) { + instance.nullableObject = nullableObject; + } +} +
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_FAST_INIT_MODE_test.MyClass_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_FAST_INIT_MODE_test.MyClass_MembersInjector new file mode 100644 index 0000000..17f220a --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_kotlinNullableFieldInjection_FAST_INIT_MODE_test.MyClass_MembersInjector
@@ -0,0 +1,65 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; +import org.jetbrains.annotations.Nullable; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class MyClass_MembersInjector implements MembersInjector<MyClass> { + private final Provider<String> nullableStringProvider; + + private final Provider<Object> nullableObjectProvider; + + public MyClass_MembersInjector(Provider<String> nullableStringProvider, + Provider<Object> nullableObjectProvider) { + this.nullableStringProvider = nullableStringProvider; + this.nullableObjectProvider = nullableObjectProvider; + } + + public static MembersInjector<MyClass> create(Provider<String> nullableStringProvider, + Provider<Object> nullableObjectProvider) { + return new MyClass_MembersInjector(nullableStringProvider, nullableObjectProvider); + } + + public static MembersInjector<MyClass> create( + javax.inject.Provider<String> nullableStringProvider, + javax.inject.Provider<Object> nullableObjectProvider) { + return new MyClass_MembersInjector(Providers.asDaggerProvider(nullableStringProvider), Providers.asDaggerProvider(nullableObjectProvider)); + } + + @Override + public void injectMembers(MyClass instance) { + injectNullableString(instance, nullableStringProvider.get()); + injectNullableObject(instance, nullableObjectProvider.get()); + } + + @InjectedFieldSignature("test.MyClass.nullableString") + public static void injectNullableString(MyClass instance, @Nullable String nullableString) { + instance.nullableString = nullableString; + } + + @InjectedFieldSignature("test.MyClass.nullableObject") + public static void injectNullableObject(MyClass instance, @Nullable Object nullableObject) { + instance.nullableObject = nullableObject; + } +} +
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 9d11248..1b1e71f 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
@@ -4,9 +4,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MethodInjection_MembersInjector implements MembersInjector<MethodInjection> { private final Provider<String> stringProvider; @@ -45,6 +48,13 @@ return new MethodInjection_MembersInjector(stringProvider, stringProvider2, stringProvider3, stringProvider4); } + public static MembersInjector<MethodInjection> create( + javax.inject.Provider<String> stringProvider, javax.inject.Provider<String> stringProvider2, + javax.inject.Provider<String> stringProvider3, + javax.inject.Provider<String> stringProvider4) { + return new MethodInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(stringProvider2), Providers.asDaggerProvider(stringProvider3), Providers.asDaggerProvider(stringProvider4)); + } + @Override public void injectMembers(MethodInjection instance) { injectNoArgs(instance); @@ -61,7 +71,7 @@ } public static void injectManyArgs(Object instance, String string, Lazy<String> lazyString, - Provider<String> stringProvider) { + javax.inject.Provider<String> stringProvider) { ((MethodInjection) instance).manyArgs(string, lazyString, 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 9d11248..1b1e71f 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
@@ -4,9 +4,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.DoubleCheck; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -19,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MethodInjection_MembersInjector implements MembersInjector<MethodInjection> { private final Provider<String> stringProvider; @@ -45,6 +48,13 @@ return new MethodInjection_MembersInjector(stringProvider, stringProvider2, stringProvider3, stringProvider4); } + public static MembersInjector<MethodInjection> create( + javax.inject.Provider<String> stringProvider, javax.inject.Provider<String> stringProvider2, + javax.inject.Provider<String> stringProvider3, + javax.inject.Provider<String> stringProvider4) { + return new MethodInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(stringProvider2), Providers.asDaggerProvider(stringProvider3), Providers.asDaggerProvider(stringProvider4)); + } + @Override public void injectMembers(MethodInjection instance) { injectNoArgs(instance); @@ -61,7 +71,7 @@ } public static void injectManyArgs(Object instance, String string, Lazy<String> lazyString, - Provider<String> stringProvider) { + javax.inject.Provider<String> stringProvider) { ((MethodInjection) instance).manyArgs(string, lazyString, 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 86589c7..5158593 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueCProvider; @@ -35,6 +38,11 @@ return new A_MembersInjector(valueCProvider, valueAProvider); } + public static MembersInjector<A> create(javax.inject.Provider<String> valueCProvider, + javax.inject.Provider<String> valueAProvider) { + return new A_MembersInjector(Providers.asDaggerProvider(valueCProvider), Providers.asDaggerProvider(valueAProvider)); + } + @Override public void injectMembers(A instance) { C_MembersInjector.injectValueC(instance, valueCProvider.get());
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 9c18178..8fc09d0 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class C_MembersInjector implements MembersInjector<C> { private final Provider<String> valueCProvider; @@ -31,6 +34,10 @@ return new C_MembersInjector(valueCProvider); } + public static MembersInjector<C> create(javax.inject.Provider<String> valueCProvider) { + return new C_MembersInjector(Providers.asDaggerProvider(valueCProvider)); + } + @Override public void injectMembers(C instance) { injectValueC(instance, valueCProvider.get());
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 86589c7..5158593 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueCProvider; @@ -35,6 +38,11 @@ return new A_MembersInjector(valueCProvider, valueAProvider); } + public static MembersInjector<A> create(javax.inject.Provider<String> valueCProvider, + javax.inject.Provider<String> valueAProvider) { + return new A_MembersInjector(Providers.asDaggerProvider(valueCProvider), Providers.asDaggerProvider(valueAProvider)); + } + @Override public void injectMembers(A instance) { C_MembersInjector.injectValueC(instance, valueCProvider.get());
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 9c18178..8fc09d0 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class C_MembersInjector implements MembersInjector<C> { private final Provider<String> valueCProvider; @@ -31,6 +34,10 @@ return new C_MembersInjector(valueCProvider); } + public static MembersInjector<C> create(javax.inject.Provider<String> valueCProvider) { + return new C_MembersInjector(Providers.asDaggerProvider(valueCProvider)); + } + @Override public void injectMembers(C instance) { injectValueC(instance, valueCProvider.get());
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 ba590b8..c968dd6 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MixedMemberInjection_MembersInjector implements MembersInjector<MixedMemberInjection> { private final Provider<String> stringProvider; @@ -42,6 +45,12 @@ return new MixedMemberInjection_MembersInjector(stringProvider, objectProvider, sProvider, oProvider); } + public static MembersInjector<MixedMemberInjection> create( + javax.inject.Provider<String> stringProvider, javax.inject.Provider<Object> objectProvider, + javax.inject.Provider<String> sProvider, javax.inject.Provider<Object> oProvider) { + return new MixedMemberInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(objectProvider), Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(oProvider)); + } + @Override public void injectMembers(MixedMemberInjection instance) { injectString(instance, stringProvider.get());
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 ba590b8..c968dd6 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MixedMemberInjection_MembersInjector implements MembersInjector<MixedMemberInjection> { private final Provider<String> stringProvider; @@ -42,6 +45,12 @@ return new MixedMemberInjection_MembersInjector(stringProvider, objectProvider, sProvider, oProvider); } + public static MembersInjector<MixedMemberInjection> create( + javax.inject.Provider<String> stringProvider, javax.inject.Provider<Object> objectProvider, + javax.inject.Provider<String> sProvider, javax.inject.Provider<Object> oProvider) { + return new MixedMemberInjection_MembersInjector(Providers.asDaggerProvider(stringProvider), Providers.asDaggerProvider(objectProvider), Providers.asDaggerProvider(sProvider), Providers.asDaggerProvider(oProvider)); + } + @Override public void injectMembers(MixedMemberInjection instance) { injectString(instance, stringProvider.get());
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector new file mode 100644 index 0000000..23ab444 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector
@@ -0,0 +1,52 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { + private final Provider<String> stringProvider; + + public FieldInjection_MembersInjector(Provider<String> stringProvider) { + this.stringProvider = stringProvider; + } + + public static MembersInjector<FieldInjection> create(Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(stringProvider); + } + + public static MembersInjector<FieldInjection> create( + javax.inject.Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider)); + } + + @Override + public void injectMembers(FieldInjection instance) { + injectString(instance, stringProvider.get()); + } + + @InjectedFieldSignature("test.FieldInjection.string") + public static void injectString(Object instance, @Nullable String string) { + ((FieldInjection) instance).string = string; + } +} +
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector new file mode 100644 index 0000000..23ab444 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_nonTypeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector
@@ -0,0 +1,52 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { + private final Provider<String> stringProvider; + + public FieldInjection_MembersInjector(Provider<String> stringProvider) { + this.stringProvider = stringProvider; + } + + public static MembersInjector<FieldInjection> create(Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(stringProvider); + } + + public static MembersInjector<FieldInjection> create( + javax.inject.Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider)); + } + + @Override + public void injectMembers(FieldInjection instance) { + injectString(instance, stringProvider.get()); + } + + @InjectedFieldSignature("test.FieldInjection.string") + public static void injectString(Object instance, @Nullable String string) { + ((FieldInjection) instance).string = string; + } +} +
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 88e7fa5..c957ad7 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 88e7fa5..c957ad7 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c4c4b07..b2fc405 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c4c4b07..b2fc405 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 04a4131..8b5855e 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 04a4131..8b5855e 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 5b4932f..d2b3141 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; @@ -31,6 +34,10 @@ return new OuterType_B_MembersInjector(aProvider); } + public static MembersInjector<OuterType.B> create(javax.inject.Provider<OuterType.A> aProvider) { + return new OuterType_B_MembersInjector(Providers.asDaggerProvider(aProvider)); + } + @Override public void injectMembers(OuterType.B instance) { injectA(instance, aProvider.get());
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 5b4932f..d2b3141 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class OuterType_B_MembersInjector implements MembersInjector<OuterType.B> { private final Provider<OuterType.A> aProvider; @@ -31,6 +34,10 @@ return new OuterType_B_MembersInjector(aProvider); } + public static MembersInjector<OuterType.B> create(javax.inject.Provider<OuterType.A> aProvider) { + return new OuterType_B_MembersInjector(Providers.asDaggerProvider(aProvider)); + } + @Override public void injectMembers(OuterType.B instance) { injectA(instance, aProvider.get());
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 6040966..e744215 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Child_MembersInjector<T> implements MembersInjector<Child<T>> { private final Provider<T> xProvider; @@ -45,6 +48,12 @@ return new Child_MembersInjector<T>(xProvider, yProvider, a2Provider, aProvider, tProvider); } + public static <T> MembersInjector<Child<T>> create(javax.inject.Provider<T> xProvider, + javax.inject.Provider<A> yProvider, javax.inject.Provider<A2> a2Provider, + javax.inject.Provider<A> aProvider, javax.inject.Provider<T> tProvider) { + return new Child_MembersInjector<T>(Providers.asDaggerProvider(xProvider), Providers.asDaggerProvider(yProvider), Providers.asDaggerProvider(a2Provider), Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(tProvider)); + } + @Override public void injectMembers(Child<T> instance) { Parent_MembersInjector.injectX(instance, xProvider.get());
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 6040966..e744215 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class Child_MembersInjector<T> implements MembersInjector<Child<T>> { private final Provider<T> xProvider; @@ -45,6 +48,12 @@ return new Child_MembersInjector<T>(xProvider, yProvider, a2Provider, aProvider, tProvider); } + public static <T> MembersInjector<Child<T>> create(javax.inject.Provider<T> xProvider, + javax.inject.Provider<A> yProvider, javax.inject.Provider<A2> a2Provider, + javax.inject.Provider<A> aProvider, javax.inject.Provider<T> tProvider) { + return new Child_MembersInjector<T>(Providers.asDaggerProvider(xProvider), Providers.asDaggerProvider(yProvider), Providers.asDaggerProvider(a2Provider), Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(tProvider)); + } + @Override public void injectMembers(Child<T> instance) { Parent_MembersInjector.injectX(instance, xProvider.get());
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 01f787b..175f9d6 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> sProvider; @@ -31,6 +34,10 @@ return new B_MembersInjector(sProvider); } + public static MembersInjector<B> create(javax.inject.Provider<String> sProvider) { + return new B_MembersInjector(Providers.asDaggerProvider(sProvider)); + } + @Override public void injectMembers(B instance) { injectS(instance, sProvider.get());
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 01f787b..175f9d6 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> sProvider; @@ -31,6 +34,10 @@ return new B_MembersInjector(sProvider); } + public static MembersInjector<B> create(javax.inject.Provider<String> sProvider) { + return new B_MembersInjector(Providers.asDaggerProvider(sProvider)); + } + @Override public void injectMembers(B instance) { injectS(instance, sProvider.get());
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 f126251..dafed92 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
@@ -2,9 +2,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -17,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueBProvider; @@ -30,6 +33,10 @@ return new A_MembersInjector(valueBProvider); } + public static MembersInjector<A> create(javax.inject.Provider<String> valueBProvider) { + return new A_MembersInjector(Providers.asDaggerProvider(valueBProvider)); + } + @Override public void injectMembers(A instance) { B_MembersInjector.injectValueB(instance, valueBProvider.get());
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 192947e..e9b2888 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> valueBProvider; @@ -31,6 +34,10 @@ return new B_MembersInjector(valueBProvider); } + public static MembersInjector<B> create(javax.inject.Provider<String> valueBProvider) { + return new B_MembersInjector(Providers.asDaggerProvider(valueBProvider)); + } + @Override public void injectMembers(B instance) { injectValueB(instance, valueBProvider.get());
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 f126251..dafed92 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
@@ -2,9 +2,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -17,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class A_MembersInjector implements MembersInjector<A> { private final Provider<String> valueBProvider; @@ -30,6 +33,10 @@ return new A_MembersInjector(valueBProvider); } + public static MembersInjector<A> create(javax.inject.Provider<String> valueBProvider) { + return new A_MembersInjector(Providers.asDaggerProvider(valueBProvider)); + } + @Override public void injectMembers(A instance) { B_MembersInjector.injectValueB(instance, valueBProvider.get());
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 192947e..e9b2888 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
@@ -3,9 +3,10 @@ import dagger.MembersInjector; import dagger.internal.DaggerGenerated; import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @QualifierMetadata @DaggerGenerated @@ -18,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class B_MembersInjector implements MembersInjector<B> { private final Provider<String> valueBProvider; @@ -31,6 +34,10 @@ return new B_MembersInjector(valueBProvider); } + public static MembersInjector<B> create(javax.inject.Provider<String> valueBProvider) { + return new B_MembersInjector(Providers.asDaggerProvider(valueBProvider)); + } + @Override public void injectMembers(B instance) { injectValueB(instance, valueBProvider.get());
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 c563a1a..12767ba 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c563a1a..12767ba 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 72140b3..ee72487 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 72140b3..ee72487 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class DaggerMyComponent { private DaggerMyComponent() {
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_DEFAULT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_DEFAULT_MODE_test.DaggerMyComponent new file mode 100644 index 0000000..d47c1f2 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_DEFAULT_MODE_test.DaggerMyComponent
@@ -0,0 +1,58 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class DaggerMyComponent { + private DaggerMyComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static MyComponent create() { + return new Builder().build(); + } + + public static final class Builder { + private Builder() { + } + + public MyComponent build() { + return new MyComponentImpl(); + } + } + + private static final class MyComponentImpl implements MyComponent { + private final MyComponentImpl myComponentImpl = this; + + private MyComponentImpl() { + + + } + + @Override + public void inject(Foo foo) { + } + + @Override + public Foo injectAndReturn(Foo foo) { + return foo; + } + } +} \ No newline at end of file
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_FAST_INIT_MODE_test.DaggerMyComponent b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_FAST_INIT_MODE_test.DaggerMyComponent new file mode 100644 index 0000000..d47c1f2 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_testMembersInjectionBindingWithNoInjectionSites_FAST_INIT_MODE_test.DaggerMyComponent
@@ -0,0 +1,58 @@ +package test; + +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", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class DaggerMyComponent { + private DaggerMyComponent() { + } + + public static Builder builder() { + return new Builder(); + } + + public static MyComponent create() { + return new Builder().build(); + } + + public static final class Builder { + private Builder() { + } + + public MyComponent build() { + return new MyComponentImpl(); + } + } + + private static final class MyComponentImpl implements MyComponent { + private final MyComponentImpl myComponentImpl = this; + + private MyComponentImpl() { + + + } + + @Override + public void inject(Foo foo) { + } + + @Override + public Foo injectAndReturn(Foo foo) { + return foo; + } + } +} \ No newline at end of file
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector new file mode 100644 index 0000000..ff27f6f --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_DEFAULT_MODE_test.FieldInjection_MembersInjector
@@ -0,0 +1,52 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { + private final Provider<String> stringProvider; + + public FieldInjection_MembersInjector(Provider<String> stringProvider) { + this.stringProvider = stringProvider; + } + + public static MembersInjector<FieldInjection> create(Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(stringProvider); + } + + public static MembersInjector<FieldInjection> create( + javax.inject.Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider)); + } + + @Override + public void injectMembers(FieldInjection instance) { + injectString(instance, stringProvider.get()); + } + + @InjectedFieldSignature("test.FieldInjection.string") + public static void injectString(Object instance, String string) { + ((FieldInjection) instance).string = string; + } +} +
diff --git a/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector new file mode 100644 index 0000000..ff27f6f --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/MembersInjectionTest_typeUseNullableFieldInjection_FAST_INIT_MODE_test.FieldInjection_MembersInjector
@@ -0,0 +1,52 @@ +package test; + +import dagger.MembersInjector; +import dagger.internal.DaggerGenerated; +import dagger.internal.InjectedFieldSignature; +import dagger.internal.Provider; +import dagger.internal.Providers; +import dagger.internal.QualifierMetadata; +import javax.annotation.processing.Generated; + +@QualifierMetadata +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" +}) +public final class FieldInjection_MembersInjector implements MembersInjector<FieldInjection> { + private final Provider<String> stringProvider; + + public FieldInjection_MembersInjector(Provider<String> stringProvider) { + this.stringProvider = stringProvider; + } + + public static MembersInjector<FieldInjection> create(Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(stringProvider); + } + + public static MembersInjector<FieldInjection> create( + javax.inject.Provider<String> stringProvider) { + return new FieldInjection_MembersInjector(Providers.asDaggerProvider(stringProvider)); + } + + @Override + public void injectMembers(FieldInjection instance) { + injectString(instance, stringProvider.get()); + } + + @InjectedFieldSignature("test.FieldInjection.string") + public static void injectString(Object instance, String string) { + ((FieldInjection) instance).string = string; + } +} +
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 8b9a451..8489308 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildIntegerModule_ProvideIntegerFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d662cc6..84152fe 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ChildNumberModule_ProvideNumberFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 d669e2a..69932bc 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBElementFactory
@@ -3,10 +3,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ParentModule_ProvideBElementFactory<A extends CharSequence, B, C extends Number & Comparable<C>> implements Factory<B> { private final ParentModule<A, B, C> module; @@ -38,6 +41,11 @@ } public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideBElementFactory<A, B, C> create( + ParentModule<A, B, C> module, javax.inject.Provider<B> bProvider) { + return new ParentModule_ProvideBElementFactory<A, B, C>(module, Providers.asDaggerProvider(bProvider)); + } + + public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideBElementFactory<A, B, C> create( ParentModule<A, B, C> module, Provider<B> bProvider) { return new ParentModule_ProvideBElementFactory<A, B, C>(module, bProvider); }
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 35052f4..2834c39 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideBEntryFactory
@@ -3,10 +3,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ParentModule_ProvideBEntryFactory<A extends CharSequence, B, C extends Number & Comparable<C>> implements Factory<B> { private final ParentModule<A, B, C> module; @@ -38,6 +41,11 @@ } public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideBEntryFactory<A, B, C> create( + ParentModule<A, B, C> module, javax.inject.Provider<B> bProvider) { + return new ParentModule_ProvideBEntryFactory<A, B, C>(module, Providers.asDaggerProvider(bProvider)); + } + + public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideBEntryFactory<A, B, C> create( ParentModule<A, B, C> module, Provider<B> bProvider) { return new ParentModule_ProvideBEntryFactory<A, B, C>(module, bProvider); }
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 a36bf26..72f9488 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_genericSubclassedModule_test.ParentModule_ProvideListBFactory
@@ -3,11 +3,12 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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; @@ -39,6 +42,11 @@ } public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideListBFactory<A, B, C> create( + ParentModule<A, B, C> module, javax.inject.Provider<B> bProvider) { + return new ParentModule_ProvideListBFactory<A, B, C>(module, Providers.asDaggerProvider(bProvider)); + } + + public static <A extends CharSequence, B, C extends Number & Comparable<C>> ParentModule_ProvideListBFactory<A, B, C> create( ParentModule<A, B, C> module, Provider<B> bProvider) { return new ParentModule_ProvideListBFactory<A, B, C>(module, bProvider); }
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 63ae5bf..a5f7daa 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_multipleProvidesMethods_test.TestModule_ProvideObjectsFactory
@@ -4,11 +4,12 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import java.util.List; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata({ @@ -25,7 +26,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_ProvideObjectsFactory implements Factory<List<Object>> { private final TestModule module; @@ -50,6 +53,12 @@ } public static TestModule_ProvideObjectsFactory create(TestModule module, + javax.inject.Provider<Object> aProvider, javax.inject.Provider<Object> bProvider, + javax.inject.Provider<MembersInjector<X>> xInjectorProvider) { + return new TestModule_ProvideObjectsFactory(module, Providers.asDaggerProvider(aProvider), Providers.asDaggerProvider(bProvider), Providers.asDaggerProvider(xInjectorProvider)); + } + + public static TestModule_ProvideObjectsFactory create(TestModule module, Provider<Object> aProvider, Provider<Object> bProvider, Provider<MembersInjector<X>> xInjectorProvider) { return new TestModule_ProvideObjectsFactory(module, aProvider, bProvider, xInjectorProvider);
diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nonTypeUseNullableProvides_test.TestModule_ProvideStringFactory similarity index 92% rename from javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory rename to javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nonTypeUseNullableProvides_test.TestModule_ProvideStringFactory index 8e3b1cd..b2048a8 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nonTypeUseNullableProvides_test.TestModule_ProvideStringFactory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_ProvideStringFactory implements Factory<String> { private final TestModule module; @@ -41,5 +43,4 @@ public static String provideString(TestModule instance) { return instance.provideString(); } -} - +} \ No newline at end of file
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 9185ad3..e57b3a2 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideMapStringNumberFactory
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ParameterizedModule_ProvideMapStringNumberFactory implements Factory<Map<String, Number>> { @Override @@ -37,7 +39,7 @@ } private static final class InstanceHolder { - private static final ParameterizedModule_ProvideMapStringNumberFactory INSTANCE = new ParameterizedModule_ProvideMapStringNumberFactory(); + static final ParameterizedModule_ProvideMapStringNumberFactory INSTANCE = new ParameterizedModule_ProvideMapStringNumberFactory(); } }
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 29bea60..4c8f2ae 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ParameterizedModule_ProvideNonGenericTypeFactory implements Factory<Object> { @Override @@ -36,7 +38,7 @@ } private static final class InstanceHolder { - private static final ParameterizedModule_ProvideNonGenericTypeFactory INSTANCE = new ParameterizedModule_ProvideNonGenericTypeFactory(); + static final ParameterizedModule_ProvideNonGenericTypeFactory INSTANCE = new ParameterizedModule_ProvideNonGenericTypeFactory(); } }
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 4f91376..f0b0873 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_parameterizedModuleWithStaticProvidesMethodOfGenericType_test.ParameterizedModule_ProvideNonGenericTypeWithDepsFactory
@@ -3,10 +3,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata @@ -20,7 +21,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class ParameterizedModule_ProvideNonGenericTypeWithDepsFactory implements Factory<String> { private final Provider<Object> oProvider; @@ -35,6 +38,11 @@ } public static ParameterizedModule_ProvideNonGenericTypeWithDepsFactory create( + javax.inject.Provider<Object> oProvider) { + return new ParameterizedModule_ProvideNonGenericTypeWithDepsFactory(Providers.asDaggerProvider(oProvider)); + } + + public static ParameterizedModule_ProvideNonGenericTypeWithDepsFactory create( Provider<Object> oProvider) { return new ParameterizedModule_ProvideNonGenericTypeWithDepsFactory(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 6fabfaa..491bafd 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElementWildcard_test.TestModule_ProvideWildcardListFactory
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6675a41..36dfacf 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetElement_test.TestModule_ProvideStringFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 240620f..5f22922 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_providesSetValues_test.TestModule_ProvideStringsFactory
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 9250da8..a21af1c 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_CreateFactory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_CreateFactory implements Factory<Boolean> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final TestModule_CreateFactory INSTANCE = new TestModule_CreateFactory(); + static final TestModule_CreateFactory INSTANCE = new TestModule_CreateFactory(); } }
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 52eb228..244868a 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_proxyMethodsConflictWithOtherFactoryMethods_test.TestModule_GetFactory
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_GetFactory implements Factory<Integer> { @Override @@ -35,7 +37,7 @@ } private static final class InstanceHolder { - private static final TestModule_GetFactory INSTANCE = new TestModule_GetFactory(); + static final TestModule_GetFactory INSTANCE = new TestModule_GetFactory(); } }
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 9755887..17fedfa 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6675a41..36dfacf 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_singleProvidesMethodNoArgs_test.TestModule_ProvideStringFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e62e7b9..a760296 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testQualifierMetadataOnProvides_test.MyModule_ProvideStringFactory
@@ -3,10 +3,11 @@ import dagger.internal.DaggerGenerated; import dagger.internal.Factory; import dagger.internal.Preconditions; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.internal.QualifierMetadata; import dagger.internal.ScopeMetadata; import javax.annotation.processing.Generated; -import javax.inject.Provider; @ScopeMetadata @QualifierMetadata({ @@ -23,7 +24,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MyModule_ProvideStringFactory implements Factory<String> { private final Provider<Integer> iProvider; @@ -37,6 +40,10 @@ return provideString(iProvider.get()); } + public static MyModule_ProvideStringFactory create(javax.inject.Provider<Integer> iProvider) { + return new MyModule_ProvideStringFactory(Providers.asDaggerProvider(iProvider)); + } + public static MyModule_ProvideStringFactory create(Provider<Integer> iProvider) { return new MyModule_ProvideStringFactory(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 8ec360d..689e523 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopeMetadataWithCustomScope_test.MyModule_ProvideStringFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MyModule_ProvideStringFactory implements Factory<String> { @Override @@ -36,7 +38,7 @@ } private static final class InstanceHolder { - private static final MyModule_ProvideStringFactory INSTANCE = new MyModule_ProvideStringFactory(); + static final MyModule_ProvideStringFactory INSTANCE = new MyModule_ProvideStringFactory(); } }
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 e5a04c5..2e42d1f 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnNonStaticProvides_test.MyModule_ProvideStringFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 b88b3e3..cf42878 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_testScopedMetadataOnStaticProvides_test.MyModule_ProvideStringFactory
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class MyModule_ProvideStringFactory implements Factory<String> { @Override @@ -36,7 +38,7 @@ } private static final class InstanceHolder { - private static final MyModule_ProvideStringFactory INSTANCE = new MyModule_ProvideStringFactory(); + static final MyModule_ProvideStringFactory INSTANCE = new MyModule_ProvideStringFactory(); } }
diff --git a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_typeUseNullableProvides_test.TestModule_ProvideStringFactory similarity index 81% copy from javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory copy to javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_typeUseNullableProvides_test.TestModule_ProvideStringFactory index 8e3b1cd..7440fb8 100644 --- a/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_nullableProvides_test.TestModule_ProvideStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ModuleFactoryGeneratorTest_typeUseNullableProvides_test.TestModule_ProvideStringFactory
@@ -18,9 +18,11 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) -public final class TestModule_ProvideStringFactory implements Factory<String> { +public final class TestModule_ProvideStringFactory implements Factory<@Nullable String> { private final TestModule module; public TestModule_ProvideStringFactory(TestModule module) { @@ -28,8 +30,7 @@ } @Override - @Nullable - public String get() { + public @Nullable String get() { return provideString(module); } @@ -37,9 +38,7 @@ return new TestModule_ProvideStringFactory(module); } - @Nullable - public static String provideString(TestModule instance) { + public static @Nullable String provideString(TestModule instance) { return instance.provideString(); } } -
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 deleted file mode 100644 index 37c1bb8..0000000 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,75 +0,0 @@ -package test; - -import com.google.common.base.Optional; -import dagger.Lazy; -import dagger.internal.DaggerGenerated; -import dagger.internal.ProviderOfLazy; -import javax.annotation.Generated; -import javax.inject.Provider; -import other.DefinitelyNot; -import other.Maybe; -import other.Maybe_MaybeModule_ProvideMaybeFactory; - -@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 TestComponentImpl() { - - - } - - @Override - public Optional<Maybe> maybe() { - return Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe()); - } - - @Override - public Optional<Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { - return (Optional) Optional.of(ProviderOfLazy.create(Maybe_MaybeModule_ProvideMaybeFactory.create())); - } - - @Override - public Optional<DefinitelyNot> definitelyNot() { - return Optional.<DefinitelyNot>absent(); - } - - @Override - public Optional<Provider<Lazy<DefinitelyNot>>> providerOfLazyOfDefinitelyNot() { - 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 0884286..02c758a 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 deleted file mode 100644 index f1ab214..0000000 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_inlinedOptionalBindings_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,105 +0,0 @@ -package test; - -import com.google.common.base.Optional; -import dagger.Lazy; -import dagger.internal.DaggerGenerated; -import dagger.internal.Provider; -import dagger.internal.ProviderOfLazy; -import javax.annotation.Generated; -import other.DefinitelyNot; -import other.Maybe; -import other.Maybe_MaybeModule_ProvideMaybeFactory; - -@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<Maybe> provideMaybeProvider; - - private TestComponentImpl() { - - initialize(); - - } - - @SuppressWarnings("unchecked") - private void initialize() { - this.provideMaybeProvider = new SwitchingProvider<Maybe>(testComponentImpl, 0); - } - - @Override - public Optional<Maybe> maybe() { - return Optional.of(provideMaybeProvider.get()); - } - - @Override - public Optional<javax.inject.Provider<Lazy<Maybe>>> providerOfLazyOfMaybe() { - return (Optional) Optional.of(ProviderOfLazy.create(provideMaybeProvider)); - } - - @Override - public Optional<DefinitelyNot> definitelyNot() { - return Optional.<DefinitelyNot>absent(); - } - - @Override - 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> { - 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: // other.Maybe - return (T) Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe(); - - default: throw new AssertionError(id); - } - } - } - } -} -
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 83b8f81..c92f61f 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 deleted file mode 100644 index 9d278cb..0000000 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_DEFAULT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,71 +0,0 @@ -package test; - -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.producers.internal.CancellationListener; -import javax.annotation.Generated; -import other.DefinitelyNot; -import other.Maybe; -import other.Maybe_MaybeModule_ProvideMaybeFactory; - -@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, CancellationListener { - private final TestComponentImpl testComponentImpl = this; - - private TestComponentImpl() { - - - } - - @Override - public ListenableFuture<Optional<Maybe>> maybe() { - return Futures.immediateFuture(Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe())); - } - - @Override - public ListenableFuture<Optional<DefinitelyNot>> definitelyNot() { - return Futures.immediateFuture(Optional.<DefinitelyNot>absent()); - } - - @Override - public void onProducerFutureCancelled(boolean mayInterruptIfRunning) { - - - } - } -} -
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 e6e1d5a..3dc568f 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 deleted file mode 100644 index 9d278cb..0000000 --- a/javatests/dagger/internal/codegen/goldens/OptionalBindingRequestFulfillmentTest_requestForFuture_FAST_INIT_JAVA7_MODE_test.DaggerTestComponent +++ /dev/null
@@ -1,71 +0,0 @@ -package test; - -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.producers.internal.CancellationListener; -import javax.annotation.Generated; -import other.DefinitelyNot; -import other.Maybe; -import other.Maybe_MaybeModule_ProvideMaybeFactory; - -@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, CancellationListener { - private final TestComponentImpl testComponentImpl = this; - - private TestComponentImpl() { - - - } - - @Override - public ListenableFuture<Optional<Maybe>> maybe() { - return Futures.immediateFuture(Optional.of(Maybe_MaybeModule_ProvideMaybeFactory.provideMaybe())); - } - - @Override - public ListenableFuture<Optional<DefinitelyNot>> definitelyNot() { - return Futures.immediateFuture(Optional.<DefinitelyNot>absent()); - } - - @Override - public void onProducerFutureCancelled(boolean mayInterruptIfRunning) { - - - } - } -} -
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 e6e1d5a..3dc568f 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
@@ -20,7 +20,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 048cdc8..7b625c9 100644 --- a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFutureWithProducerName_test.TestModule_ProduceStringFactory
@@ -3,12 +3,13 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.producers.internal.AbstractProducesMethodProducer; import dagger.producers.monitoring.ProducerToken; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.Executor; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_ProduceStringFactory extends AbstractProducesMethodProducer<Void, String> { private final TestModule module; @@ -38,6 +41,12 @@ return new TestModule_ProduceStringFactory(module, executorProvider, productionComponentMonitorProvider); } + public static TestModule_ProduceStringFactory create(TestModule module, + javax.inject.Provider<Executor> executorProvider, + javax.inject.Provider<ProductionComponentMonitor> productionComponentMonitorProvider) { + return new TestModule_ProduceStringFactory(module, Providers.asDaggerProvider(executorProvider), Providers.asDaggerProvider(productionComponentMonitorProvider)); + } + @Override protected ListenableFuture<Void> collectDependencies() { return Futures.<Void>immediateFuture(null);
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 248ceb1..3125538 100644 --- a/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory +++ b/javatests/dagger/internal/codegen/goldens/ProducerModuleFactoryGeneratorTest_singleProducesMethodNoArgsFuture_test.TestModule_ProduceStringFactory
@@ -3,12 +3,13 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import dagger.internal.DaggerGenerated; +import dagger.internal.Provider; +import dagger.internal.Providers; import dagger.producers.internal.AbstractProducesMethodProducer; import dagger.producers.monitoring.ProducerToken; import dagger.producers.monitoring.ProductionComponentMonitor; import java.util.concurrent.Executor; import javax.annotation.processing.Generated; -import javax.inject.Provider; @DaggerGenerated @Generated( @@ -21,7 +22,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) public final class TestModule_ProduceStringFactory extends AbstractProducesMethodProducer<Void, String> { private final TestModule module; @@ -38,6 +41,12 @@ return new TestModule_ProduceStringFactory(module, executorProvider, productionComponentMonitorProvider); } + public static TestModule_ProduceStringFactory create(TestModule module, + javax.inject.Provider<Executor> executorProvider, + javax.inject.Provider<ProductionComponentMonitor> productionComponentMonitorProvider) { + return new TestModule_ProduceStringFactory(module, Providers.asDaggerProvider(executorProvider), Providers.asDaggerProvider(productionComponentMonitorProvider)); + } + @Override protected ListenableFuture<Void> collectDependencies() { return Futures.<Void>immediateFuture(null);
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 3b72cd4..16c1916 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 ab89bab..60be601 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6146004..e1b2656 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
@@ -24,7 +24,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c5df7dc..f7f665b 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
@@ -24,7 +24,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 988302c..eacd584 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 988302c..eacd584 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
@@ -19,7 +19,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f56f0e6..94ee40b 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 f56f0e6..94ee40b 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e69fffe..8ffdd23 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 e69fffe..8ffdd23 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 2ffdfd2..301a2ad 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 2ffdfd2..301a2ad 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 1d16978..043ea3f 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 1d16978..043ea3f 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a6836ce..ceaaa81 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a6836ce..ceaaa81 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e2ff2df..2f5fdb9 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 e2ff2df..2f5fdb9 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 9b03019..8f07d5b 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 9b03019..8f07d5b 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParent { private DaggerParent() {
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 a2352f6..dc1cbbd 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a0c7080..0d73ecb 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a2352f6..dc1cbbd 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a0c7080..0d73ecb 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 3a24c10..be66b6a 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 4cbe543..4f15c13 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerParentComponent { private DaggerParentComponent() { @@ -113,9 +115,9 @@ } @CanIgnoreReturnValue - private Dep2 injectDep2(Dep2 instance) { - Dep2_MembersInjector.injectDep2Method(instance); - return instance; + private Dep2 injectDep2(Dep2 instance2) { + Dep2_MembersInjector.injectDep2Method(instance2); + return instance2; } private static final class SwitchingProvider<T> implements Provider<T> {
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 245871b..8984fcd 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 245871b..8984fcd 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c866218..b07408c 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 c866218..b07408c 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a778a05..e104079 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 a778a05..e104079 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e2c98e3..72e4ca3 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e2c98e3..72e4ca3 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7b47466..248f63b 100644 --- a/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent +++ b/javatests/dagger/internal/codegen/goldens/SubcomponentValidationTest_subcomponentSimpleNamesDisambiguatedInRoot_DEFAULT_MODE_DaggerParentComponent
@@ -11,7 +11,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 7b47466..248f63b 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
@@ -11,7 +11,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6a9942d..80a1c20 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 6a9942d..80a1c20 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
@@ -13,7 +13,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0ac7a6d..63269bd 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 0ac7a6d..63269bd 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
@@ -18,7 +18,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 db768e1..b03b718 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 db768e1..b03b718 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 c474dc4..6adde95 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
@@ -17,7 +17,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { /**
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 54d032d..9998715 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
@@ -16,7 +16,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { /**
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 ab66d4e..9c4c841 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 0a7cdb2..18ccb9c 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
@@ -15,7 +15,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 ade9e53..48520b4 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) 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 e225c47..70d0364 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() { @@ -246,6 +248,9 @@ initialize(); initialize2(); + initialize3(); + initialize4(); + initialize5(); } @@ -276,6 +281,10 @@ this.binding22Provider = new SwitchingProvider<>(testComponentImpl, 22); this.binding23Provider = new SwitchingProvider<>(testComponentImpl, 23); this.binding24Provider = new SwitchingProvider<>(testComponentImpl, 24); + } + + @SuppressWarnings("unchecked") + private void initialize2() { this.binding25Provider = new SwitchingProvider<>(testComponentImpl, 25); this.binding26Provider = new SwitchingProvider<>(testComponentImpl, 26); this.binding27Provider = new SwitchingProvider<>(testComponentImpl, 27); @@ -301,6 +310,10 @@ this.binding47Provider = new SwitchingProvider<>(testComponentImpl, 47); this.binding48Provider = new SwitchingProvider<>(testComponentImpl, 48); this.binding49Provider = new SwitchingProvider<>(testComponentImpl, 49); + } + + @SuppressWarnings("unchecked") + private void initialize3() { this.binding50Provider = new SwitchingProvider<>(testComponentImpl, 50); this.binding51Provider = new SwitchingProvider<>(testComponentImpl, 51); this.binding52Provider = new SwitchingProvider<>(testComponentImpl, 52); @@ -326,6 +339,10 @@ this.binding72Provider = new SwitchingProvider<>(testComponentImpl, 72); this.binding73Provider = new SwitchingProvider<>(testComponentImpl, 73); this.binding74Provider = new SwitchingProvider<>(testComponentImpl, 74); + } + + @SuppressWarnings("unchecked") + private void initialize4() { this.binding75Provider = new SwitchingProvider<>(testComponentImpl, 75); this.binding76Provider = new SwitchingProvider<>(testComponentImpl, 76); this.binding77Provider = new SwitchingProvider<>(testComponentImpl, 77); @@ -354,7 +371,7 @@ } @SuppressWarnings("unchecked") - private void initialize2() { + private void initialize5() { this.binding100Provider = new SwitchingProvider<>(testComponentImpl, 100); } @@ -876,304 +893,304 @@ @SuppressWarnings("unchecked") private T get0() { switch (id) { - case 0: // test.Binding0 + case 0: // test.Binding0 return (T) new Binding0(); - case 1: // test.Binding1 + case 1: // test.Binding1 return (T) new Binding1(); - case 2: // test.Binding2 + case 2: // test.Binding2 return (T) new Binding2(); - case 3: // test.Binding3 + case 3: // test.Binding3 return (T) new Binding3(); - case 4: // test.Binding4 + case 4: // test.Binding4 return (T) new Binding4(); - case 5: // test.Binding5 + case 5: // test.Binding5 return (T) new Binding5(); - case 6: // test.Binding6 + case 6: // test.Binding6 return (T) new Binding6(); - case 7: // test.Binding7 + case 7: // test.Binding7 return (T) new Binding7(); - case 8: // test.Binding8 + case 8: // test.Binding8 return (T) new Binding8(); - case 9: // test.Binding9 + case 9: // test.Binding9 return (T) new Binding9(); - case 10: // test.Binding10 + case 10: // test.Binding10 return (T) new Binding10(); - case 11: // test.Binding11 + case 11: // test.Binding11 return (T) new Binding11(); - case 12: // test.Binding12 + case 12: // test.Binding12 return (T) new Binding12(); - case 13: // test.Binding13 + case 13: // test.Binding13 return (T) new Binding13(); - case 14: // test.Binding14 + case 14: // test.Binding14 return (T) new Binding14(); - case 15: // test.Binding15 + case 15: // test.Binding15 return (T) new Binding15(); - case 16: // test.Binding16 + case 16: // test.Binding16 return (T) new Binding16(); - case 17: // test.Binding17 + case 17: // test.Binding17 return (T) new Binding17(); - case 18: // test.Binding18 + case 18: // test.Binding18 return (T) new Binding18(); - case 19: // test.Binding19 + case 19: // test.Binding19 return (T) new Binding19(); - case 20: // test.Binding20 + case 20: // test.Binding20 return (T) new Binding20(); - case 21: // test.Binding21 + case 21: // test.Binding21 return (T) new Binding21(); - case 22: // test.Binding22 + case 22: // test.Binding22 return (T) new Binding22(); - case 23: // test.Binding23 + case 23: // test.Binding23 return (T) new Binding23(); - case 24: // test.Binding24 + case 24: // test.Binding24 return (T) new Binding24(); - case 25: // test.Binding25 + case 25: // test.Binding25 return (T) new Binding25(); - case 26: // test.Binding26 + case 26: // test.Binding26 return (T) new Binding26(); - case 27: // test.Binding27 + case 27: // test.Binding27 return (T) new Binding27(); - case 28: // test.Binding28 + case 28: // test.Binding28 return (T) new Binding28(); - case 29: // test.Binding29 + case 29: // test.Binding29 return (T) new Binding29(); - case 30: // test.Binding30 + case 30: // test.Binding30 return (T) new Binding30(); - case 31: // test.Binding31 + case 31: // test.Binding31 return (T) new Binding31(); - case 32: // test.Binding32 + case 32: // test.Binding32 return (T) new Binding32(); - case 33: // test.Binding33 + case 33: // test.Binding33 return (T) new Binding33(); - case 34: // test.Binding34 + case 34: // test.Binding34 return (T) new Binding34(); - case 35: // test.Binding35 + case 35: // test.Binding35 return (T) new Binding35(); - case 36: // test.Binding36 + case 36: // test.Binding36 return (T) new Binding36(); - case 37: // test.Binding37 + case 37: // test.Binding37 return (T) new Binding37(); - case 38: // test.Binding38 + case 38: // test.Binding38 return (T) new Binding38(); - case 39: // test.Binding39 + case 39: // test.Binding39 return (T) new Binding39(); - case 40: // test.Binding40 + case 40: // test.Binding40 return (T) new Binding40(); - case 41: // test.Binding41 + case 41: // test.Binding41 return (T) new Binding41(); - case 42: // test.Binding42 + case 42: // test.Binding42 return (T) new Binding42(); - case 43: // test.Binding43 + case 43: // test.Binding43 return (T) new Binding43(); - case 44: // test.Binding44 + case 44: // test.Binding44 return (T) new Binding44(); - case 45: // test.Binding45 + case 45: // test.Binding45 return (T) new Binding45(); - case 46: // test.Binding46 + case 46: // test.Binding46 return (T) new Binding46(); - case 47: // test.Binding47 + case 47: // test.Binding47 return (T) new Binding47(); - case 48: // test.Binding48 + case 48: // test.Binding48 return (T) new Binding48(); - case 49: // test.Binding49 + case 49: // test.Binding49 return (T) new Binding49(); - case 50: // test.Binding50 + case 50: // test.Binding50 return (T) new Binding50(); - case 51: // test.Binding51 + case 51: // test.Binding51 return (T) new Binding51(); - case 52: // test.Binding52 + case 52: // test.Binding52 return (T) new Binding52(); - case 53: // test.Binding53 + case 53: // test.Binding53 return (T) new Binding53(); - case 54: // test.Binding54 + case 54: // test.Binding54 return (T) new Binding54(); - case 55: // test.Binding55 + case 55: // test.Binding55 return (T) new Binding55(); - case 56: // test.Binding56 + case 56: // test.Binding56 return (T) new Binding56(); - case 57: // test.Binding57 + case 57: // test.Binding57 return (T) new Binding57(); - case 58: // test.Binding58 + case 58: // test.Binding58 return (T) new Binding58(); - case 59: // test.Binding59 + case 59: // test.Binding59 return (T) new Binding59(); - case 60: // test.Binding60 + case 60: // test.Binding60 return (T) new Binding60(); - case 61: // test.Binding61 + case 61: // test.Binding61 return (T) new Binding61(); - case 62: // test.Binding62 + case 62: // test.Binding62 return (T) new Binding62(); - case 63: // test.Binding63 + case 63: // test.Binding63 return (T) new Binding63(); - case 64: // test.Binding64 + case 64: // test.Binding64 return (T) new Binding64(); - case 65: // test.Binding65 + case 65: // test.Binding65 return (T) new Binding65(); - case 66: // test.Binding66 + case 66: // test.Binding66 return (T) new Binding66(); - case 67: // test.Binding67 + case 67: // test.Binding67 return (T) new Binding67(); - case 68: // test.Binding68 + case 68: // test.Binding68 return (T) new Binding68(); - case 69: // test.Binding69 + case 69: // test.Binding69 return (T) new Binding69(); - case 70: // test.Binding70 + case 70: // test.Binding70 return (T) new Binding70(); - case 71: // test.Binding71 + case 71: // test.Binding71 return (T) new Binding71(); - case 72: // test.Binding72 + case 72: // test.Binding72 return (T) new Binding72(); - case 73: // test.Binding73 + case 73: // test.Binding73 return (T) new Binding73(); - case 74: // test.Binding74 + case 74: // test.Binding74 return (T) new Binding74(); - case 75: // test.Binding75 + case 75: // test.Binding75 return (T) new Binding75(); - case 76: // test.Binding76 + case 76: // test.Binding76 return (T) new Binding76(); - case 77: // test.Binding77 + case 77: // test.Binding77 return (T) new Binding77(); - case 78: // test.Binding78 + case 78: // test.Binding78 return (T) new Binding78(); - case 79: // test.Binding79 + case 79: // test.Binding79 return (T) new Binding79(); - case 80: // test.Binding80 + case 80: // test.Binding80 return (T) new Binding80(); - case 81: // test.Binding81 + case 81: // test.Binding81 return (T) new Binding81(); - case 82: // test.Binding82 + case 82: // test.Binding82 return (T) new Binding82(); - case 83: // test.Binding83 + case 83: // test.Binding83 return (T) new Binding83(); - case 84: // test.Binding84 + case 84: // test.Binding84 return (T) new Binding84(); - case 85: // test.Binding85 + case 85: // test.Binding85 return (T) new Binding85(); - case 86: // test.Binding86 + case 86: // test.Binding86 return (T) new Binding86(); - case 87: // test.Binding87 + case 87: // test.Binding87 return (T) new Binding87(); - case 88: // test.Binding88 + case 88: // test.Binding88 return (T) new Binding88(); - case 89: // test.Binding89 + case 89: // test.Binding89 return (T) new Binding89(); - case 90: // test.Binding90 + case 90: // test.Binding90 return (T) new Binding90(); - case 91: // test.Binding91 + case 91: // test.Binding91 return (T) new Binding91(); - case 92: // test.Binding92 + case 92: // test.Binding92 return (T) new Binding92(); - case 93: // test.Binding93 + case 93: // test.Binding93 return (T) new Binding93(); - case 94: // test.Binding94 + case 94: // test.Binding94 return (T) new Binding94(); - case 95: // test.Binding95 + case 95: // test.Binding95 return (T) new Binding95(); - case 96: // test.Binding96 + case 96: // test.Binding96 return (T) new Binding96(); - case 97: // test.Binding97 + case 97: // test.Binding97 return (T) new Binding97(); - case 98: // test.Binding98 + case 98: // test.Binding98 return (T) new Binding98(); - case 99: // test.Binding99 + case 99: // test.Binding99 return (T) new Binding99(); default: throw new AssertionError(id); @@ -1183,7 +1200,7 @@ @SuppressWarnings("unchecked") private T get1() { switch (id) { - case 100: // test.Binding100 + case 100: // test.Binding100 return (T) new Binding100(); default: throw new AssertionError(id);
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 b2933ae..8566133 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
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 eef5afc..4980ee3 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
@@ -14,7 +14,9 @@ "rawtypes", "KotlinInternal", "KotlinInternalInJava", - "cast" + "cast", + "deprecation", + "nullness:initialization.field.uninitialized" }) final class DaggerTestComponent { private DaggerTestComponent() {
diff --git a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java index 20a57f1..9cf99cf 100644 --- a/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java +++ b/javatests/dagger/internal/codegen/kotlin/KspComponentProcessorTest.java
@@ -39,58 +39,60 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "package test;", - "", - "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 DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private Builder() {", - " }", - "", - " public MyComponent build() {", - " return new MyComponentImpl();", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private MyComponentImpl() {", - "", - "", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "package test;", + "", + "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\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private Builder() {", + " }", + "", + " public MyComponent build() {", + " return new MyComponentImpl();", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl() {", + "", + "", + " }", + " }", + "}")); + }); } @Test @@ -143,63 +145,65 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "package test;", - "", - "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 DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private Builder() {", - " }", - "", - " public MyComponent build() {", - " return new MyComponentImpl();", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private MyComponentImpl() {", - "", - "", - " }", - "", - " @Override", - " public Foo foo() {", - " return new Foo(new Bar());", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "package test;", + "", + "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\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private Builder() {", + " }", + "", + " public MyComponent build() {", + " return new MyComponentImpl();", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl() {", + "", + "", + " }", + "", + " @Override", + " public Foo foo() {", + " return new Foo(new Bar());", + " }", + " }", + "}")); + }); } @Test @@ -225,73 +229,75 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "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\"", - "})", - "public final class DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private Builder() {", - " }", - "", - " public MyComponent build() {", - " return new MyComponentImpl();", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private Provider<Foo> fooProvider;", - "", - " private MyComponentImpl() {", - "", - " initialize();", - "", - " }", - "", - " @SuppressWarnings(\"unchecked\")", - " private void initialize() {", - " this.fooProvider = " - + "Foo_Factory.create(Bar_Factory.create(), Bar_Factory.create());", - " }", - "", - " @Override", - " public javax.inject.Provider<Foo> foo() {", - " return fooProvider;", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "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\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private Builder() {", + " }", + "", + " public MyComponent build() {", + " return new MyComponentImpl();", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private Provider<Foo> fooProvider;", + "", + " private MyComponentImpl() {", + "", + " initialize();", + "", + " }", + "", + " @SuppressWarnings(\"unchecked\")", + " private void initialize() {", + " this.fooProvider = " + + "Foo_Factory.create(Bar_Factory.create(), Bar_Factory.create());", + " }", + "", + " @Override", + " public javax.inject.Provider<Foo> foo() {", + " return fooProvider;", + " }", + " }", + "}")); + }); } @Test @@ -326,77 +332,79 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "package test;", - "", - "import dagger.internal.DaggerGenerated;", - "import dagger.internal.Preconditions;", - "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 DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private MyModule myModule;", - "", - " private Builder() {", - " }", - "", - " public Builder myModule(MyModule myModule) {", - " this.myModule = Preconditions.checkNotNull(myModule);", - " return this;", - " }", - "", - " public MyComponent build() {", - " if (myModule == null) {", - " this.myModule = new MyModule();", - " }", - " return new MyComponentImpl(myModule);", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyModule myModule;", - "", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private MyComponentImpl(MyModule myModuleParam) {", - " this.myModule = myModuleParam;", - "", - " }", - "", - " @Override", - " public Foo foo() {", - " return MyModule_ProvideFooFactory.provideFoo(" - + "myModule, MyModule_ProvideBarFactory.provideBar(myModule));", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "package test;", + "", + "import dagger.internal.DaggerGenerated;", + "import dagger.internal.Preconditions;", + "import javax.annotation.processing.Generated;", + "", + "@DaggerGenerated", + "@Generated(", + " value = \"dagger.internal.codegen.ComponentProcessor\",", + " comments = \"https://dagger.dev\"", + ")", + "@SuppressWarnings({", + " \"unchecked\",", + " \"rawtypes\",", + " \"KotlinInternal\",", + " \"KotlinInternalInJava\",", + " \"cast\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private MyModule myModule;", + "", + " private Builder() {", + " }", + "", + " public Builder myModule(MyModule myModule) {", + " this.myModule = Preconditions.checkNotNull(myModule);", + " return this;", + " }", + "", + " public MyComponent build() {", + " if (myModule == null) {", + " this.myModule = new MyModule();", + " }", + " return new MyComponentImpl(myModule);", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyModule myModule;", + "", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl(MyModule myModuleParam) {", + " this.myModule = myModuleParam;", + "", + " }", + "", + " @Override", + " public Foo foo() {", + " return MyModule_ProvideFooFactory.provideFoo(" + + "myModule, MyModule_ProvideBarFactory.provideBar(myModule));", + " }", + " }", + "}")); + }); } @Test @@ -432,84 +440,86 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "package test;", - "", - "import com.google.errorprone.annotations.CanIgnoreReturnValue;", - "import dagger.internal.DaggerGenerated;", - "import dagger.internal.Preconditions;", - "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 DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private MyModule myModule;", - "", - " private Builder() {", - " }", - "", - " public Builder myModule(MyModule myModule) {", - " this.myModule = Preconditions.checkNotNull(myModule);", - " return this;", - " }", - "", - " public MyComponent build() {", - " if (myModule == null) {", - " this.myModule = new MyModule();", - " }", - " return new MyComponentImpl(myModule);", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyModule myModule;", - "", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private MyComponentImpl(MyModule myModuleParam) {", - " this.myModule = myModuleParam;", - "", - " }", - "", - " @Override", - " public void injectFoo(Foo foo) {", - " injectFoo2(foo);", - " }", - "", - " @CanIgnoreReturnValue", - " private Foo injectFoo2(Foo instance) {", - " Foo_MembersInjector.injectBar(" - + "instance, MyModule_ProvideBarFactory.provideBar(myModule));", - " return instance;", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "package test;", + "", + "import com.google.errorprone.annotations.CanIgnoreReturnValue;", + "import dagger.internal.DaggerGenerated;", + "import dagger.internal.Preconditions;", + "import javax.annotation.processing.Generated;", + "", + "@DaggerGenerated", + "@Generated(", + " value = \"dagger.internal.codegen.ComponentProcessor\",", + " comments = \"https://dagger.dev\"", + ")", + "@SuppressWarnings({", + " \"unchecked\",", + " \"rawtypes\",", + " \"KotlinInternal\",", + " \"KotlinInternalInJava\",", + " \"cast\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private MyModule myModule;", + "", + " private Builder() {", + " }", + "", + " public Builder myModule(MyModule myModule) {", + " this.myModule = Preconditions.checkNotNull(myModule);", + " return this;", + " }", + "", + " public MyComponent build() {", + " if (myModule == null) {", + " this.myModule = new MyModule();", + " }", + " return new MyComponentImpl(myModule);", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyModule myModule;", + "", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl(MyModule myModuleParam) {", + " this.myModule = myModuleParam;", + "", + " }", + "", + " @Override", + " public void injectFoo(Foo foo) {", + " injectFoo2(foo);", + " }", + "", + " @CanIgnoreReturnValue", + " private Foo injectFoo2(Foo instance) {", + " Foo_MembersInjector.injectBar(" + + "instance, MyModule_ProvideBarFactory.provideBar(myModule));", + " return instance;", + " }", + " }", + "}")); + }); } @Test @@ -545,83 +555,85 @@ CompilerTests.daggerCompiler(componentSrc) .compile( subject -> { - subject.hasErrorCount(0); - subject.generatedSource( - CompilerTests.javaSource( - "test/DaggerMyComponent", - "package test;", - "", - "import com.google.errorprone.annotations.CanIgnoreReturnValue;", - "import dagger.internal.DaggerGenerated;", - "import dagger.internal.Preconditions;", - "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 DaggerMyComponent {", - " private DaggerMyComponent() {", - " }", - "", - " public static Builder builder() {", - " return new Builder();", - " }", - "", - " public static MyComponent create() {", - " return new Builder().build();", - " }", - "", - " public static final class Builder {", - " private MyModule myModule;", - "", - " private Builder() {", - " }", - "", - " public Builder myModule(MyModule myModule) {", - " this.myModule = Preconditions.checkNotNull(myModule);", - " return this;", - " }", - "", - " public MyComponent build() {", - " if (myModule == null) {", - " this.myModule = new MyModule();", - " }", - " return new MyComponentImpl(myModule);", - " }", - " }", - "", - " private static final class MyComponentImpl implements MyComponent {", - " private final MyModule myModule;", - "", - " private final MyComponentImpl myComponentImpl = this;", - "", - " private MyComponentImpl(MyModule myModuleParam) {", - " this.myModule = myModuleParam;", - "", - " }", - "", - " @Override", - " public Foo foo() {", - " return injectFoo(Foo_Factory.newInstance());", - " }", - "", - " @CanIgnoreReturnValue", - " private Foo injectFoo(Foo instance) {", - " Foo_MembersInjector.injectBar(" - + "instance, MyModule_ProvideBarFactory.provideBar(myModule));", - " return instance;", - " }", - " }", - "}")); - }); + subject.hasErrorCount(0); + subject.generatedSource( + CompilerTests.javaSource( + "test/DaggerMyComponent", + "package test;", + "", + "import com.google.errorprone.annotations.CanIgnoreReturnValue;", + "import dagger.internal.DaggerGenerated;", + "import dagger.internal.Preconditions;", + "import javax.annotation.processing.Generated;", + "", + "@DaggerGenerated", + "@Generated(", + " value = \"dagger.internal.codegen.ComponentProcessor\",", + " comments = \"https://dagger.dev\"", + ")", + "@SuppressWarnings({", + " \"unchecked\",", + " \"rawtypes\",", + " \"KotlinInternal\",", + " \"KotlinInternalInJava\",", + " \"cast\",", + " \"deprecation\",", + " \"nullness:initialization.field.uninitialized\"", + "})", + "public final class DaggerMyComponent {", + " private DaggerMyComponent() {", + " }", + "", + " public static Builder builder() {", + " return new Builder();", + " }", + "", + " public static MyComponent create() {", + " return new Builder().build();", + " }", + "", + " public static final class Builder {", + " private MyModule myModule;", + "", + " private Builder() {", + " }", + "", + " public Builder myModule(MyModule myModule) {", + " this.myModule = Preconditions.checkNotNull(myModule);", + " return this;", + " }", + "", + " public MyComponent build() {", + " if (myModule == null) {", + " this.myModule = new MyModule();", + " }", + " return new MyComponentImpl(myModule);", + " }", + " }", + "", + " private static final class MyComponentImpl implements MyComponent {", + " private final MyModule myModule;", + "", + " private final MyComponentImpl myComponentImpl = this;", + "", + " private MyComponentImpl(MyModule myModuleParam) {", + " this.myModule = myModuleParam;", + "", + " }", + "", + " @Override", + " public Foo foo() {", + " return injectFoo(Foo_Factory.newInstance());", + " }", + "", + " @CanIgnoreReturnValue", + " private Foo injectFoo(Foo instance) {", + " Foo_MembersInjector.injectBar(" + + "instance, MyModule_ProvideBarFactory.provideBar(myModule));", + " return instance;", + " }", + " }", + "}")); + }); } }
diff --git a/javatests/dagger/lint/BUILD b/javatests/dagger/lint/BUILD index 4252cca..21e1331 100644 --- a/javatests/dagger/lint/BUILD +++ b/javatests/dagger/lint/BUILD
@@ -15,7 +15,7 @@ # Description: # Tests for the Dagger Lint Rules -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_test") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") package(default_visibility = ["//:src"])
diff --git a/javatests/dagger/spi/BUILD b/javatests/dagger/spi/BUILD index ef1dca0..c69c00f 100644 --- a/javatests/dagger/spi/BUILD +++ b/javatests/dagger/spi/BUILD
@@ -15,12 +15,12 @@ # Description: # Tests for the Dagger SPI -load("//:test_defs.bzl", "GenJavaTests") load( "//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES", ) +load("//:test_defs.bzl", "GenJavaTests") package(default_visibility = ["//:src"])
diff --git a/javatests/dagger/spi/SpiPluginTest.java b/javatests/dagger/spi/SpiPluginTest.java index 3d8e586..d011d65 100644 --- a/javatests/dagger/spi/SpiPluginTest.java +++ b/javatests/dagger/spi/SpiPluginTest.java
@@ -101,7 +101,7 @@ message( "[FailingPlugin] Bad Binding: @Inject test.Foo()", " test.Foo is requested at", - " test.TestComponent.foo()")) + " [test.TestComponent] test.TestComponent.foo()")) .inFile(component) .onLineContaining("interface TestComponent"); } @@ -189,7 +189,7 @@ message( "[FailingPlugin] Bad Dependency: test.TestComponent.entryPoint() (entry point)", " test.EntryPoint is requested at", - " test.TestComponent.entryPoint()")) + " [test.TestComponent] test.TestComponent.entryPoint()")) .inFile(component) .onLineContaining("interface TestComponent"); assertThat(compilationFactory.compilationWithErrorOnDependency("dup1")) @@ -197,9 +197,9 @@ message( "[FailingPlugin] Bad Dependency: test.EntryPoint(…, dup1, …)", " test.Duplicated is injected at", - " test.EntryPoint(…, dup1, …)", + " [test.TestComponent] test.EntryPoint(…, dup1, …)", " test.EntryPoint is requested at", - " test.TestComponent.entryPoint()")) + " [test.TestComponent] test.TestComponent.entryPoint()")) .inFile(component) .onLineContaining("interface TestComponent"); assertThat(compilationFactory.compilationWithErrorOnDependency("dup2")) @@ -207,9 +207,9 @@ message( "[FailingPlugin] Bad Dependency: test.EntryPoint(…, dup2)", " test.Duplicated is injected at", - " test.EntryPoint(…, dup2)", + " [test.TestComponent] test.EntryPoint(…, dup2)", " test.EntryPoint is requested at", - " test.TestComponent.entryPoint()")) + " [test.TestComponent] test.TestComponent.entryPoint()")) .inFile(component) .onLineContaining("interface TestComponent"); @@ -220,11 +220,11 @@ message( "[FailingPlugin] Bad Dependency: test.Foo(inFooDep)", " test.Duplicated is injected at", - " test.Foo(inFooDep)", + " [test.TestComponent] test.Foo(inFooDep)", " test.Foo is injected at", - " test.EntryPoint(foo, …)", + " [test.TestComponent] test.EntryPoint(foo, …)", " test.EntryPoint is requested at", - " test.TestComponent.entryPoint()", + " [test.TestComponent] test.TestComponent.entryPoint()", "The following other entry points also depend on it:", " test.TestComponent.chain()")) .inFile(component) @@ -284,7 +284,7 @@ "[FailingPlugin] Bad Dependency: " + "test.TestSubcomponent.childEntryPoint() (entry point)", " test.EntryPoint is requested at", - " test.TestSubcomponent.childEntryPoint()" + " [test.TestSubcomponent] test.TestSubcomponent.childEntryPoint()" + " [test.TestComponent → test.TestSubcomponent]")) .inFile(component) .onLineContaining("interface TestComponent"); @@ -297,9 +297,9 @@ message( "[FailingPlugin] Bad Dependency: test.EntryPoint(foo)", " test.Foo is injected at", - " test.EntryPoint(foo)", + " [test.TestSubcomponent] test.EntryPoint(foo)", " test.EntryPoint is requested at", - " test.TestSubcomponent.childEntryPoint() " + " [test.TestSubcomponent] test.TestSubcomponent.childEntryPoint() " + "[test.TestComponent → test.TestSubcomponent]")) .inFile(component) .onLineContaining("interface TestComponent"); @@ -470,13 +470,13 @@ message( "[FailingPlugin] Bad Binding: @Inject test.ExposedOnSubcomponent()", " test.ExposedOnSubcomponent is injected at", - " test.Chain3(exposedOnSubcomponent)", + " [test.TestComponent] test.Chain3(exposedOnSubcomponent)", " test.Chain3 is injected at", - " test.Chain2(chain)", + " [test.TestComponent] test.Chain2(chain)", " test.Chain2 is injected at", - " test.Chain1(chain)", + " [test.TestComponent] test.Chain1(chain)", " test.Chain1 is requested at", - " test.TestComponent.chain()", + " [test.TestComponent] test.TestComponent.chain()", "The following other entry points also depend on it:", " test.TestSubcomponent.exposedOnSubcomponent() " + "[test.TestComponent → test.TestSubcomponent]"))
diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..c9bbf35 --- /dev/null +++ b/settings.gradle.kts
@@ -0,0 +1,23 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "dagger-parent" + +fun includeProject(name: String, path: String) { + include(name) + project(name).projectDir = File(path) +} + +includeProject(":dagger", "gradle-projects/dagger-runtime")
diff --git a/test_defs.bzl b/test_defs.bzl index 3b13626..ea8fbf5 100644 --- a/test_defs.bzl +++ b/test_defs.bzl
@@ -17,7 +17,7 @@ load("@rules_java//java:defs.bzl", "java_library", "java_test") load("//:build_defs.bzl", "JAVA_RELEASE_MIN") load( - "@io_bazel_rules_kotlin//kotlin:kotlin.bzl", + "@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library", "kt_jvm_test", ) @@ -27,7 +27,6 @@ _NON_FUNCTIONAL_BUILD_VARIANTS = {None: []} _FUNCTIONAL_BUILD_VARIANTS = { None: [], # The default build variant (no javacopts). - "ExtendsComponent": ["-Adagger.generatedClassExtendsComponent=enabled"], "Shards": ["-Adagger.keysPerComponentShard=2"], "FastInit": ["-Adagger.fastInit=enabled"], "FastInit_Shards": ["-Adagger.fastInit=enabled", "-Adagger.keysPerComponentShard=2"], @@ -208,7 +207,9 @@ build_variants = _FUNCTIONAL_BUILD_VARIANTS if functional else _NON_FUNCTIONAL_BUILD_VARIANTS for (variant_name, variant_javacopts) in build_variants.items(): + merged_javacopts = javacopts + variant_javacopts for is_ksp in (True, False): + merged_plugins = plugins if variant_name: suffix = "_" + variant_name tags = [variant_name] @@ -233,8 +234,8 @@ srcs = supporting_files, tags = tags, deps = deps + variant_deps, - plugins = plugins, - javacopts = javacopts + variant_javacopts, + plugins = merged_plugins, + javacopts = merged_javacopts, functional = functional, require_jdk7_syntax = require_jdk7_syntax, ) @@ -242,6 +243,7 @@ for test_file in test_files: test_name = test_file.rsplit(".", 1)[0] + _GenTestWithVariant( library_rule_type = library_rule_type, test_rule_type = test_rule_type, @@ -249,8 +251,8 @@ srcs = [test_file], tags = tags, deps = test_deps + variant_deps, - plugins = plugins, - javacopts = javacopts + variant_javacopts, + plugins = merged_plugins, + javacopts = merged_javacopts, shard_count = shard_count, jvm_flags = jvm_flags, functional = functional,
diff --git a/third_party/java/auto/BUILD b/third_party/java/auto/BUILD index 93e7e5b..48ad091 100644 --- a/third_party/java/auto/BUILD +++ b/third_party/java/auto/BUILD
@@ -26,7 +26,6 @@ java_plugin( name = "auto_value_processor", processor_class = "com.google.auto.value.processor.AutoValueProcessor", - visibility = ["//visibility:private"], deps = [ ":common", ":service",
diff --git a/third_party/kotlin/build_extensions/rules.bzl b/third_party/kotlin/build_extensions/rules.bzl index f1d9b7c..14aa4ef 100644 --- a/third_party/kotlin/build_extensions/rules.bzl +++ b/third_party/kotlin/build_extensions/rules.bzl
@@ -14,7 +14,7 @@ """Convenience wrapper for kt_android_library.""" -load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", io_kt_android_library = "kt_android_library") +load("@io_bazel_rules_kotlin//kotlin:android.bzl", io_kt_android_library = "kt_android_library") def kt_android_library(**kwargs): io_kt_android_library(**kwargs)
diff --git a/third_party/kotlin/kotlin_metadata_jvm/BUILD b/third_party/kotlin/kotlin_metadata_jvm/BUILD new file mode 100644 index 0000000..6f19a2d --- /dev/null +++ b/third_party/kotlin/kotlin_metadata_jvm/BUILD
@@ -0,0 +1,22 @@ +# 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. + +# BUILD rules for https://github.com/square/kotlinpoet + +package(default_visibility = ["//:src"]) + +alias( + name = "kotlin_metadata_jvm", + actual = "@maven//:org_jetbrains_kotlin_kotlin_metadata_jvm", +)
diff --git a/tools/BUILD b/tools/BUILD index 83d5048..035bdba 100644 --- a/tools/BUILD +++ b/tools/BUILD
@@ -16,28 +16,9 @@ # Tools for Dagger load("@bazel_skylib//:bzl_library.bzl", "bzl_library") -load(":maven_info.bzl", "maven_info_tests") package(default_visibility = ["//:src"]) -maven_info_tests() - -exports_files([ - "pom-template.xml", -]) - -bzl_library( - name = "maven_bzl", - srcs = ["maven.bzl"], - deps = [":maven_info_bzl"], -) - -bzl_library( - name = "maven_info_bzl", - srcs = ["maven_info.bzl"], - deps = ["@bazel_skylib//lib:unittest"], -) - bzl_library( name = "dejetify_bzl", srcs = ["dejetify.bzl"],
diff --git a/tools/bazel.rc b/tools/bazel.rc deleted file mode 100644 index 2707c1c..0000000 --- a/tools/bazel.rc +++ /dev/null
@@ -1,11 +0,0 @@ -# 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/bazel_compat.bzl b/tools/bazel_compat.bzl index bc8b04a..9660588 100644 --- a/tools/bazel_compat.bzl +++ b/tools/bazel_compat.bzl
@@ -12,14 +12,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Macros for building with Bazel. -""" +# Description: +# Macros for building with Bazel. load("//third_party/kotlin/build_extensions:rules.bzl", "kt_android_library") +load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") def compat_kt_android_library(name, **kwargs): bazel_kt_android_library(name, kwargs) +def compat_kt_jvm_library(name, **kwargs): + bazel_kt_jvm_library(name, kwargs) + def bazel_kt_android_library(name, kwargs): """A macro that wraps Bazel's kt_android_library. @@ -63,3 +67,24 @@ name = "lib{}-src.jar".format(name), actual = ":{}_internal_kt-sources.jar".format(name), ) + +def bazel_kt_jvm_library(name, kwargs): + """A macro that wraps Bazel's kt_jvm_library. + + This macro wraps Bazel's kt_jvm_library to output the jars files + in the expected locations (https://github.com/bazelbuild/rules_kotlin/issues/324). + + Args: + name: the name of the library. + kwargs: Additional arguments of the library. + """ + + kt_jvm_library( + name = name, + **kwargs + ) + + native.alias( + name = "lib{}-src.jar".format(name), + actual = ":{}-sources.jar".format(name), + )
diff --git a/tools/jarjar/BUILD b/tools/jarjar/BUILD new file mode 100644 index 0000000..6bcfba0 --- /dev/null +++ b/tools/jarjar/BUILD
@@ -0,0 +1,50 @@ +# 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. + +# Starlark rules for using jarjar + +load("@rules_java//java:defs.bzl", "java_binary") + +package(default_visibility = ["//:src"]) + +java_binary( + name = "jarjar", + main_class = "org.pantsbuild.jarjar.Main", + visibility = ["//visibility:public"], + runtime_deps = [ + "//third_party/java/asm", + "//third_party/java/asm:asm-commons", + "//third_party/java/asm:asm-tree", + "//third_party/java/jsr250_annotations", + "//third_party/java/jsr330_inject", + "@maven//:javax_enterprise_cdi_api", + "@maven//:org_apache_ant_ant", + "@maven//:org_apache_ant_ant_launcher", + "@maven//:org_apache_maven_maven_artifact", + "@maven//:org_apache_maven_maven_model", + "@maven//:org_apache_maven_maven_plugin_api", + "@maven//:org_codehaus_plexus_plexus_classworlds", + "@maven//:org_codehaus_plexus_plexus_component_annotations", + "@maven//:org_codehaus_plexus_plexus_utils", + "@maven//:org_eclipse_sisu_org_eclipse_sisu_inject", + "@maven//:org_eclipse_sisu_org_eclipse_sisu_plexus", + "@maven//:org_pantsbuild_jarjar", + ], +) + +sh_binary( + name = "jarjar_runner", + srcs = ["jarjar_runner.sh"], + visibility = ["//visibility:public"], +)
diff --git a/tools/jarjar/jarjar.bzl b/tools/jarjar/jarjar.bzl new file mode 100644 index 0000000..2fa6554 --- /dev/null +++ b/tools/jarjar/jarjar.bzl
@@ -0,0 +1,92 @@ +# 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. + +"""Skylark rules for jarjar. See https://github.com/pantsbuild/jarjar +""" + +load("@rules_java//java:defs.bzl", "java_common") + +def _jarjar_library(ctx): + ctx.actions.write( + output = ctx.outputs._rules_file, + content = "\n".join(ctx.attr.rules), + ) + + jar_files = depset(transitive = [jar.files for jar in ctx.attr.jars]).to_list() + + command = """ + export JAVA_HOME="{java_home}" + export MERGE_META_INF_FILES="{merge_meta_inf_files}" + export JARJAR="{jarjar}" + export RULES_FILE="{rules_file}" + export OUTFILE="{outfile}" + "{jarjar_runner}" {jars} + """.format( + java_home = str(ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home), + merge_meta_inf_files = " ".join(ctx.attr.merge_meta_inf_files), + jarjar = ctx.executable._jarjar.path, + rules_file = ctx.outputs._rules_file.path, + outfile = ctx.outputs.jar.path, + jarjar_runner = ctx.executable._jarjar_runner.path, + jars = " ".join([jar.path for jar in jar_files]), + ) + + ctx.actions.run_shell( + command = command, + inputs = [ctx.outputs._rules_file] + jar_files + ctx.files._jdk, + outputs = [ctx.outputs.jar], + tools = [ctx.executable._jarjar, ctx.executable._jarjar_runner], + ) + +_jarjar_library_attrs = { + "rules": attr.string_list(), + "jars": attr.label_list( + allow_files = [".jar"], + ), + "merge_meta_inf_files": attr.string_list( + allow_empty = True, + default = [], + mandatory = False, + doc = """A list of regular expressions that match files relative to the + META-INF directory that will be merged into the output jar, in addition + to files in META-INF/services. To add all files in META-INF/foo, for + example, use "foo/.*".""", + ), +} + +_jarjar_library_attrs.update({ + "_jarjar": attr.label( + default = Label("//tools/jarjar"), + executable = True, + cfg = "exec", + ), + "_jarjar_runner": attr.label( + default = Label("//tools/jarjar:jarjar_runner"), + executable = True, + cfg = "exec", + ), + "_jdk": attr.label( + default = Label("@bazel_tools//tools/jdk:current_java_runtime"), + providers = [java_common.JavaRuntimeInfo], + ), +}) + +jarjar_library = rule( + attrs = _jarjar_library_attrs, + outputs = { + "jar": "%{name}.jar", + "_rules_file": "%{name}.jarjar_rules", + }, + implementation = _jarjar_library, +)
diff --git a/tools/jarjar/jarjar_runner.sh b/tools/jarjar/jarjar_runner.sh new file mode 100755 index 0000000..502fea0 --- /dev/null +++ b/tools/jarjar/jarjar_runner.sh
@@ -0,0 +1,70 @@ +#!/bin/bash +# 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. + +JAVA_HOME="$(cd "${JAVA_HOME}" && pwd)" # this is used outside of the root + +TMPDIR="$(mktemp -d)" +for jar in "$@"; do + unzip -qq -B "${jar}" -d "${TMPDIR}" +done + +pushd "${TMPDIR}" &>/dev/null + +find=(find) +if [[ "$(uname -s)" == "Darwin" ]]; then + # Mac uses BSD find, which requires extra args for regex matching. + find+=(-E) + suffix='(~[0-9]*)?' +else + # Default to GNU find, which must escape parentheses. + suffix='\(~[0-9]*\)?' +fi + +# Concatenate similar files in META-INF that allow it. +for meta_inf_pattern in services/.* ${MERGE_META_INF_FILES}; do + regex="META-INF/${meta_inf_pattern}${suffix}" + for file in $("${find[@]}" META-INF -regex "${regex}"); do + original="$(sed s/"~[0-9]*$"// <<< "${file}")" + if [[ "${file}" != "${original}" ]]; then + cat "${file}" >> "${original}" + rm "${file}" + fi + done +done + +# build-data.properties is emitted by Bazel with target information that can +# cause conflicts. Delete it since it doesn't make sense to keep in the merged +# jar anyway. +rm build-data.properties* +rm META-INF/MANIFEST.MF* +rm -rf META-INF/maven/ +duplicate_files="$(find * -type f -regex '.*~[0-9]*$')" +if [[ -n "${duplicate_files}" ]]; then + echo "Error: duplicate files in merged jar: ${duplicate_files}" + exit 1 +fi +"${JAVA_HOME}/bin/jar" cf combined.jar * + +popd &>/dev/null + +# If the RULES_FILE exists and is not empty then run jarjar. +# Otherwise, we're done so just copy the combined jar to the output file. +if [[ -f "${RULES_FILE}" && -s "${RULES_FILE}" ]]; then + "${JARJAR}" process "${RULES_FILE}" "${TMPDIR}/combined.jar" "${OUTFILE}" +else + cp $TMPDIR/combined.jar $OUTFILE +fi + +rm -rf "${TMPDIR}"
diff --git a/tools/jarjar/test/BUILD b/tools/jarjar/test/BUILD new file mode 100644 index 0000000..42659e6 --- /dev/null +++ b/tools/jarjar/test/BUILD
@@ -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. + +# Starlark tests for jarjar + +load("//tools/jarjar:jarjar.bzl", "jarjar_library") + +# Test target used for validating rule. +jarjar_library( + name = "test_target", + testonly = 1, + jars = [ + ":test-library1.jar", + ":test-library2.jar", + ], + merge_meta_inf_files = ["utilities/libs.dep"], +) + +# Test that validates jarjar with merged META-INF files. +sh_test( + name = "validate_test_target", + srcs = [":jarjar_validator.sh"], + args = [ + "$(location :test_target.jar)", + "utilities/libs.dep", + "$(location :expected_libs.dep)", + ], + data = [ + ":expected_libs.dep", + ":test_target.jar", + ], +)
diff --git a/tools/jarjar/test/expected_libs.dep b/tools/jarjar/test/expected_libs.dep new file mode 100644 index 0000000..5e34c37 --- /dev/null +++ b/tools/jarjar/test/expected_libs.dep
@@ -0,0 +1,2 @@ +Library2 +Library1
diff --git a/tools/jarjar/test/jarjar_validator.sh b/tools/jarjar/test/jarjar_validator.sh new file mode 100755 index 0000000..ca64f9d --- /dev/null +++ b/tools/jarjar/test/jarjar_validator.sh
@@ -0,0 +1,8 @@ +#!/bin/bash +if diff <(unzip -p "$1" "META-INF/$2") "$3"; then + echo Passed + exit 0 +else + echo Failed + exit 1 +fi
diff --git a/tools/jarjar/test/test-library1.jar b/tools/jarjar/test/test-library1.jar new file mode 100644 index 0000000..418894f --- /dev/null +++ b/tools/jarjar/test/test-library1.jar Binary files differ
diff --git a/tools/jarjar/test/test-library2.jar b/tools/jarjar/test/test-library2.jar new file mode 100644 index 0000000..072cb62 --- /dev/null +++ b/tools/jarjar/test/test-library2.jar Binary files differ
diff --git a/tools/javadoc/BUILD b/tools/javadoc/BUILD new file mode 100644 index 0000000..9355350 --- /dev/null +++ b/tools/javadoc/BUILD
@@ -0,0 +1,17 @@ +# 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. + +# Starlark rules for generating Javadoc + +package(default_visibility = ["//:src"])
diff --git a/tools/javadoc/javadoc.bzl b/tools/javadoc/javadoc.bzl new file mode 100644 index 0000000..db7eccd --- /dev/null +++ b/tools/javadoc/javadoc.bzl
@@ -0,0 +1,156 @@ +# 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. + +"""See javadoc_library.""" + +load("@rules_java//java:defs.bzl", "JavaInfo", "java_common") + +def _android_jar(android_api_level): + if android_api_level == -1: + return None + return Label("@androidsdk//:platforms/android-%s/android.jar" % android_api_level) + +def _javadoc_library(ctx): + transitive_deps = [] + for dep in ctx.attr.deps: + if JavaInfo in dep: + transitive_deps.append(dep[JavaInfo].transitive_compile_time_jars) + + if ctx.attr._android_jar: + transitive_deps.append(ctx.attr._android_jar.files) + + classpath = depset([], transitive = transitive_deps).to_list() + + java_home = str(ctx.attr._jdk[java_common.JavaRuntimeInfo].java_home) + + output_dir = ctx.actions.declare_directory("%s_javadoc" % ctx.attr.name) + + javadoc_arguments = ctx.actions.args() + javadoc_arguments.use_param_file("@%s", use_always = True) + javadoc_arguments.set_param_file_format("multiline") + + javadoc_command = java_home + "/bin/javadoc" + + javadoc_arguments.add("-use") + javadoc_arguments.add("-encoding", "UTF8") + javadoc_arguments.add_joined("-classpath", classpath, join_with = ":") + javadoc_arguments.add("-notimestamp") + javadoc_arguments.add("-d", output_dir.path) + javadoc_arguments.add("-Xdoclint:-missing") + javadoc_arguments.add("-quiet") + + # Documentation for the javadoc command + # https://docs.oracle.com/javase/9/javadoc/javadoc-command.htm + if ctx.attr.root_packages: + # TODO(b/167433657): Reevaluate the utility of root_packages + # 1. Find the first directory under the working directory named '*java'. + # 2. Assume all files to document can be found by appending a root_package name + # to that directory, or a subdirectory, replacing dots with slashes. + javadoc_command += ' -sourcepath $(find * -type d -name "*java" -print0 | tr "\\0" :) ' + javadoc_arguments.add_all(ctx.attr.root_packages) + javadoc_arguments.add_joined("-subpackages", ctx.attr.root_packages, join_with = ":") + else: + # Document exactly the code in the specified source files. + javadoc_arguments.add_all(ctx.files.srcs) + + if ctx.attr.doctitle: + javadoc_arguments.add("-doctitle", ctx.attr.doctitle, format = '"%s"') + + if ctx.attr.groups: + groups = [] + for k, v in ctx.attr.groups.items(): + groups.append("-group \"%s\" \"%s\"" % (k, ":".join(v))) + javadoc_arguments.add_all(groups) + + javadoc_arguments.add_joined("-exclude", ctx.attr.exclude_packages, join_with = ":") + + javadoc_arguments.add_all( + ctx.attr.external_javadoc_links, + map_each = _format_linkoffline_value, + ) + + if ctx.attr.bottom_text: + javadoc_arguments.add("-bottom", ctx.attr.bottom_text, format = '"%s"') + + # TODO(ronshapiro): Should we be using a different tool that doesn't include + # timestamp info? + jar_command = "%s/bin/jar cf %s -C %s ." % (java_home, ctx.outputs.jar.path, output_dir.path) + + srcs = depset(transitive = [src.files for src in ctx.attr.srcs]).to_list() + ctx.actions.run_shell( + inputs = srcs + classpath + ctx.files._jdk, + command = "%s $@ && %s" % (javadoc_command, jar_command), + arguments = [javadoc_arguments], + outputs = [output_dir, ctx.outputs.jar], + ) + +def _format_linkoffline_value(link): + return "-linkoffline {0} {0}".format(link) + +javadoc_library = rule( + attrs = { + "srcs": attr.label_list( + allow_empty = False, + allow_files = True, + doc = "Source files to generate Javadoc for.", + ), + "deps": attr.label_list( + doc = """ +Targets that contain references to other types referenced in Javadoc. These can +be the java_library/android_library target(s) for the same sources. +""", + ), + "doctitle": attr.string( + default = "", + doc = "Title for generated index.html. See javadoc -doctitle.", + ), + "groups": attr.string_list_dict( + doc = "Groups specified packages together in overview page. See javadoc -groups.", + ), + "root_packages": attr.string_list( + doc = """ +Java packages to include in generated Javadoc. Any subpackages not listed in +exclude_packages will be included as well. If none are provided, each file in +`srcs` is processed. +""", + ), + "exclude_packages": attr.string_list( + doc = "Java packages to exclude from generated Javadoc.", + ), + "android_api_level": attr.int( + default = -1, + doc = """ +If Android APIs are used, the API level to compile against to generate Javadoc. +""", + ), + "bottom_text": attr.string( + default = "", + doc = "Text passed to Javadoc's `-bottom` flag.", + ), + "external_javadoc_links": attr.string_list( + doc = "URLs passed to Javadoc's `-linkoffline` flag.", + ), + "_android_jar": attr.label( + default = _android_jar, + allow_single_file = True, + ), + "_jdk": attr.label( + default = Label("@bazel_tools//tools/jdk:current_java_runtime"), + providers = [java_common.JavaRuntimeInfo], + ), + }, + outputs = {"jar": "%{name}.jar"}, + doc = "Generates a Javadoc jar path/to/target/<name>.jar.", + implementation = _javadoc_library, +)
diff --git a/tools/maven/BUILD b/tools/maven/BUILD new file mode 100644 index 0000000..d92397e --- /dev/null +++ b/tools/maven/BUILD
@@ -0,0 +1,45 @@ +# 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. + +# Starlark rules for generating Maven pom files + +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") +load(":maven_info.bzl", "maven_info_tests") +load(":pom_file.bzl", "pom_file_tests") + +package(default_visibility = ["//:src"]) + +exports_files(["pom-template.xml"]) + +bzl_library( + name = "maven_bzl", + srcs = ["maven.bzl"], + deps = [ + ":maven_info_bzl", + "@rules_java//java:rules", + ], +) + +bzl_library( + name = "maven_info_bzl", + srcs = ["maven_info.bzl"], + deps = [ + "@bazel_skylib//lib:unittest", + "@rules_java//java:rules", + ], +) + +maven_info_tests() + +pom_file_tests()
diff --git a/tools/maven.bzl b/tools/maven/maven.bzl similarity index 97% rename from tools/maven.bzl rename to tools/maven/maven.bzl index 4fba1a5..3177344 100644 --- a/tools/maven.bzl +++ b/tools/maven/maven.bzl
@@ -11,29 +11,29 @@ # 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. - """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("@rules_java//java:defs.bzl", "java_binary") +load("//tools/jarjar:jarjar.bzl", "jarjar_library") +load("//tools/javadoc:javadoc.bzl", "javadoc_library") load(":maven_info.bzl", "MavenInfo", "collect_maven_info") +load(":pom_file.bzl", "pom_file") SHADED_MAVEN_DEPS = [ "com.google.auto:auto-common", - "org.jetbrains.kotlinx:kotlinx-metadata-jvm", + "org.jetbrains.kotlin:kotlin-metadata-jvm", ] -def pom_file(name, targets, artifact_name, artifact_id, packaging = None, **kwargs): - default_pom_file( +def dagger_pom_file(name, targets, artifact_name, artifact_id, packaging = None, **kwargs): + pom_file( name = name, targets = targets, preferred_group_ids = [ "com.google.dagger", "com.google", ], - template_file = "//tools:pom-template.xml", + template_file = "//tools/maven:pom-template.xml", substitutions = { "{artifact_name}": artifact_name, "{artifact_id}": artifact_id, @@ -174,7 +174,7 @@ ] artifact_id = artifact_coordinates.split(":")[1] - pom_file( + dagger_pom_file( name = pom_name, testonly = testonly, artifact_id = artifact_id, @@ -290,7 +290,7 @@ # Build an empty javadoc because Sonatype requires javadocs # even if the jar is empty. # https://central.sonatype.org/pages/requirements.html#supply-javadoc-and-sources - native.java_binary( + java_binary( name = name + "-javadoc", )
diff --git a/tools/maven_info.bzl b/tools/maven/maven_info.bzl similarity index 98% rename from tools/maven_info.bzl rename to tools/maven/maven_info.bzl index 5ebed3f..c215d88 100644 --- a/tools/maven_info.bzl +++ b/tools/maven/maven_info.bzl
@@ -14,6 +14,7 @@ """Skylark rules to collect Maven artifacts information. """ +load("@rules_java//java:defs.bzl", "java_library") load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") # TODO(b/142057516): Unfork this file once we've settled on a more general API. @@ -105,7 +106,7 @@ outs = src_file, cmd = "echo 'package pkg; class %s {}' > $@" % name, ) - native.java_library( + java_library( name = name, srcs = src_file, tags = ["maven_coordinates=%s:_:_" % name] if is_artifact else [],
diff --git a/tools/pom-template.xml b/tools/maven/pom-template.xml similarity index 100% rename from tools/pom-template.xml rename to tools/maven/pom-template.xml
diff --git a/tools/maven/pom_file.bzl b/tools/maven/pom_file.bzl new file mode 100644 index 0000000..52d32b1 --- /dev/null +++ b/tools/maven/pom_file.bzl
@@ -0,0 +1,361 @@ +# 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. +"""Skylark rules to make publishing Maven artifacts simpler. +""" + +load("@rules_java//java:defs.bzl", "java_library") +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") + +MavenInfo = provider( + fields = { + "maven_artifacts": """ + The Maven coordinates for the artifacts that are exported by this target: i.e. the target + itself and its transitively exported targets. + """, + "maven_dependencies": """ + The Maven coordinates of the direct dependencies, and the transitively exported targets, of + this target. + """, + }, +) + +_EMPTY_MAVEN_INFO = MavenInfo( + maven_artifacts = depset(), + maven_dependencies = depset(), +) + +_MAVEN_COORDINATES_PREFIX = "maven_coordinates=" + +def _maven_artifacts(targets): + return [target[MavenInfo].maven_artifacts for target in targets if MavenInfo in target] + +def _collect_maven_info_impl(_target, ctx): + tags = getattr(ctx.rule.attr, "tags", []) + deps = getattr(ctx.rule.attr, "deps", []) + exports = getattr(ctx.rule.attr, "exports", []) + runtime_deps = getattr(ctx.rule.attr, "runtime_deps", []) + + maven_artifacts = [] + for tag in tags: + if tag in ("maven:compile_only", "maven:shaded"): + return [_EMPTY_MAVEN_INFO] + if tag.startswith(_MAVEN_COORDINATES_PREFIX): + maven_artifacts.append(tag[len(_MAVEN_COORDINATES_PREFIX):]) + + return [MavenInfo( + maven_artifacts = depset(maven_artifacts, transitive = _maven_artifacts(exports)), + maven_dependencies = depset( + [], + transitive = _maven_artifacts(deps + exports + runtime_deps), + ), + )] + +_collect_maven_info = aspect( + attr_aspects = [ + "deps", + "exports", + "runtime_deps", + ], + doc = """ + Collects the Maven information for targets, their dependencies, and their transitive exports. + """, + implementation = _collect_maven_info_impl, +) + +def _prefix_index_of(item, prefixes): + """Returns the index of the first value in `prefixes` that is a prefix of `item`. + + If none of the prefixes match, return the size of `prefixes`. + + Args: + item: the item to match + prefixes: prefixes to match against + + Returns: + an integer representing the index of the match described above. + """ + for index, prefix in enumerate(prefixes): + if item.startswith(prefix): + return index + return len(prefixes) + +def _sort_artifacts(artifacts, prefixes): + """Sorts `artifacts`, preferring group ids that appear earlier in `prefixes`. + + Values in `prefixes` do not need to be complete group ids. For example, passing `prefixes = + ['io.bazel']` will match `io.bazel.rules:rules-artifact:1.0`. If multiple prefixes match an + artifact, the first one in `prefixes` will be used. + + _Implementation note_: Skylark does not support passing a comparator function to the `sorted()` + builtin, so this constructs a list of tuples with elements: + - `[0]` = an integer corresponding to the index in `prefixes` that matches the artifact (see + `_prefix_index_of`) + - `[1]` = parts of the complete artifact, split on `:`. This is used as a tiebreaker when + multilple artifacts have the same index referenced in `[0]`. The individual parts are used so + that individual artifacts in the same group are sorted correctly - if just the string is used, + the colon that separates the artifact name from the version will sort lower than a longer + name. For example: + - `com.example.project:base:1 + - `com.example.project:extension:1 + "base" sorts lower than "exension". + - `[2]` = the complete artifact. this is a convenience so that after sorting, the artifact can + be returned. + + The `sorted` builtin will first compare the index element and if it needs a tiebreaker, will + recursively compare the contents of the second element. + + Args: + artifacts: artifacts to be sorted + prefixes: the preferred group ids used to sort `artifacts` + + Returns: + A new, sorted list containing the contents of `artifacts`. + """ + indexed = [] + for artifact in artifacts: + parts = artifact.split(":") + indexed.append((_prefix_index_of(parts[0], prefixes), parts, artifact)) + + return [x[-1] for x in sorted(indexed)] + +DEP_BLOCK = """ +<dependency> + <groupId>{0}</groupId> + <artifactId>{1}</artifactId> + <version>{2}</version> +</dependency> +""".strip() + +CLASSIFIER_DEP_BLOCK = """ +<dependency> + <groupId>{0}</groupId> + <artifactId>{1}</artifactId> + <version>{2}</version> + <type>{3}</type> + <classifier>{4}</classifier> +</dependency> +""".strip() + +DEP_PKG_BLOCK = """ +<dependency> + <groupId>{0}</groupId> + <artifactId>{1}</artifactId> + <packaging>{2}</packaging> + <version>{3}</version> +</dependency> +""".strip() + +def _pom_file(ctx): + mvn_deps = depset( + [], + transitive = [target[MavenInfo].maven_dependencies for target in ctx.attr.targets], + ) + + formatted_deps = [] + for dep in _sort_artifacts(mvn_deps.to_list(), ctx.attr.preferred_group_ids): + parts = dep.split(":") + if ":".join(parts[0:2]) in ctx.attr.excluded_artifacts: + continue + if len(parts) == 3: + template = DEP_BLOCK + elif len(parts) == 4: + template = DEP_PKG_BLOCK + elif len(parts) == 5: + template = CLASSIFIER_DEP_BLOCK + else: + fail("Unknown dependency format: %s" % dep) + + formatted_deps.append(template.format(*parts)) + + substitutions = {} + substitutions.update(ctx.attr.substitutions) + substitutions.update({ + "{generated_bzl_deps}": "\n".join(formatted_deps), + "{pom_version}": ctx.var.get("pom_version", "LOCAL-SNAPSHOT"), + }) + + ctx.actions.expand_template( + template = ctx.file.template_file, + output = ctx.outputs.pom_file, + substitutions = substitutions, + ) + +pom_file = rule( + attrs = { + "template_file": attr.label( + allow_single_file = True, + ), + "substitutions": attr.string_dict( + allow_empty = True, + mandatory = False, + ), + "targets": attr.label_list( + mandatory = True, + aspects = [_collect_maven_info], + ), + "preferred_group_ids": attr.string_list(), + "excluded_artifacts": attr.string_list(), + }, + doc = """ + Creates a Maven POM file for `targets`. + + This rule scans the deps, runtime_deps, and exports of `targets` and their transitive exports, + checking each for tags of the form `maven_coordinates=<coords>`. These tags are used to build + the list of Maven dependencies for the generated POM. + + Users should call this rule with a `template_file` that contains a `{generated_bzl_deps}` + placeholder. The rule will replace this with the appropriate XML for all dependencies. + Additional placeholders to replace can be passed via the `substitutions` argument. + + The dependencies included will be sorted alphabetically by groupId, then by artifactId. The + `preferred_group_ids` can be used to specify groupIds (or groupId-prefixes) that should be + sorted ahead of other artifacts. Artifacts in the same group will be sorted alphabetically. + + Args: + name: the name of target. The generated POM file will use this name, with `.xml` appended + targets: a list of build target(s) that represent this POM file + template_file: a pom.xml file that will be used as a template for the generated POM + substitutions: an optional mapping of placeholders to replacement values that will be applied + to the `template_file` (e.g. `{'GROUP_ID': 'com.example.group'}`). `{pom_version}` is + implicitly included in this mapping and can be configured by passing `bazel build + --define=pom_version=<version>`. + preferred_group_ids: an optional list of maven groupIds that will be used to sort the + generated deps. + excluded_artifacts: an optional list of maven artifacts in the format "groupId:artifactId" + that should be excluded from the generated pom file. + """, + outputs = {"pom_file": "%{name}.xml"}, + implementation = _pom_file, +) + +def _fake_java_library(name, deps = None, exports = None, runtime_deps = None): + src_file = ["%s.java" % name] + native.genrule( + name = "%s_source_file" % name, + outs = src_file, + cmd = "echo 'class %s {}' > $@" % name, + ) + java_library( + name = name, + srcs = src_file, + tags = ["maven_coordinates=%s:_:_" % name], + javacopts = ["-Xep:DefaultPackage:OFF"], + deps = deps or [], + exports = exports or [], + runtime_deps = runtime_deps or [], + ) + +def _maven_info_test_impl(ctx): + env = unittest.begin(ctx) + asserts.equals( + env, + expected = sorted(ctx.attr.maven_artifacts), + actual = sorted(ctx.attr.target[MavenInfo].maven_artifacts.to_list()), + msg = "MavenInfo.maven_artifacts", + ) + asserts.equals( + env, + expected = sorted(ctx.attr.maven_dependencies), + actual = sorted(ctx.attr.target[MavenInfo].maven_dependencies.to_list()), + msg = "MavenInfo.maven_dependencies", + ) + return unittest.end(env) + +_maven_info_test = unittest.make( + _maven_info_test_impl, + attrs = { + "target": attr.label(aspects = [_collect_maven_info]), + "maven_artifacts": attr.string_list(), + "maven_dependencies": attr.string_list(), + }, +) + +def pom_file_tests(): + """Tests for `pom_file` and `MavenInfo`. + """ + _fake_java_library(name = "FileA") + _maven_info_test( + name = "FileA_test", + target = ":FileA", + maven_artifacts = ["FileA:_:_"], + maven_dependencies = [], + ) + + _fake_java_library( + name = "DepOnFileA", + deps = [":FileA"], + ) + _maven_info_test( + name = "DepOnFileA_test", + target = ":DepOnFileA", + maven_artifacts = ["DepOnFileA:_:_"], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "RuntimeDepOnFileA", + runtime_deps = [":FileA"], + ) + _maven_info_test( + name = "RuntimeDepOnFileA_test", + target = ":RuntimeDepOnFileA", + maven_artifacts = ["RuntimeDepOnFileA:_:_"], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "ExportsFileA", + exports = [":FileA"], + ) + _maven_info_test( + name = "ExportsFileA_test", + target = ":ExportsFileA", + maven_artifacts = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + maven_dependencies = ["FileA:_:_"], + ) + + _fake_java_library( + name = "TransitiveExportsFileA", + exports = [":ExportsFileA"], + ) + _maven_info_test( + name = "TransitiveExportsFileA_test", + target = ":TransitiveExportsFileA", + maven_artifacts = [ + "TransitiveExportsFileA:_:_", + "ExportsFileA:_:_", + "FileA:_:_", + ], + maven_dependencies = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + ) + + _fake_java_library( + name = "TransitiveDepsFileA", + deps = [":ExportsFileA"], + ) + _maven_info_test( + name = "TransitiveDepsFileA_test", + target = ":TransitiveDepsFileA", + maven_artifacts = ["TransitiveDepsFileA:_:_"], + maven_dependencies = [ + "ExportsFileA:_:_", + "FileA:_:_", + ], + )
diff --git a/tools/shader/gradle/wrapper/gradle-wrapper.properties b/tools/shader/gradle/wrapper/gradle-wrapper.properties index 0f80bbf..e1bef7e 100644 --- a/tools/shader/gradle/wrapper/gradle-wrapper.properties +++ b/tools/shader/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-8.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists
diff --git a/tools/shader/settings.gradle b/tools/shader/settings.gradle new file mode 100644 index 0000000..3edfbdb --- /dev/null +++ b/tools/shader/settings.gradle
@@ -0,0 +1 @@ +rootProject.name = "shader" \ No newline at end of file
diff --git a/util/build-gradle.sh b/util/build-gradle.sh new file mode 100755 index 0000000..c01ce7a --- /dev/null +++ b/util/build-gradle.sh
@@ -0,0 +1,5 @@ +#!/bin/bash + +set -ex + +./gradlew build --no-daemon --stacktrace \ No newline at end of file
diff --git a/util/deploy-dagger.sh b/util/deploy-dagger.sh index b0b68a8..0f258c8 100755 --- a/util/deploy-dagger.sh +++ b/util/deploy-dagger.sh
@@ -52,7 +52,7 @@ "" _deploy \ - "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" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlin.metadata,dagger.spi.internal.shaded.kotlin.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 \ - "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" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlin.metadata,dagger.spi.internal.shaded.kotlin.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 \ @@ -108,7 +108,7 @@ "" _deploy \ - "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" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlin.metadata,dagger.spi.internal.shaded.kotlin.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/artifact-src.jar \
diff --git a/util/deploy-hilt.sh b/util/deploy-hilt.sh index 81b384c..99e314c 100755 --- a/util/deploy-hilt.sh +++ b/util/deploy-hilt.sh
@@ -52,7 +52,7 @@ "" _deploy \ - "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" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlin.metadata,dagger.spi.internal.shaded.kotlin.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 \ - "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" \ + "com.google.auto.common,dagger.spi.internal.shaded.auto.common;androidx.room.compiler,dagger.spi.internal.shaded.androidx.room.compiler;kotlin.metadata,dagger.spi.internal.shaded.kotlin.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/deploy-library.sh b/util/deploy-library.sh index 35c566b..0296294 100755 --- a/util/deploy-library.sh +++ b/util/deploy-library.sh
@@ -33,9 +33,6 @@ library="${library%.*}-shaded.${library##*.}" fi - # Validate that the classes in the library jar begin with expected prefixes. - validate_jar $(bazel_output_file $library) - # TODO(bcorso): Consider moving this into the "gen_maven_artifact" macro, this # requires having the version checked-in for the build system. add_tracking_version \ @@ -101,20 +98,6 @@ fi } -validate_jar() { - local library=$1 - if [[ $library == */gwt/libgwt.jar ]]; then - python $(dirname $0)/validate-jar-entry-prefixes.py \ - $library "dagger/,META-INF/,javax/inject/" - elif [[ $library == */java/dagger/hilt/android/artifact.aar ]]; then - python $(dirname $0)/validate-jar-entry-prefixes.py \ - $library "dagger/,META-INF/,hilt_aggregated_deps/" - else - python $(dirname $0)/validate-jar-entry-prefixes.py \ - $library "dagger/,META-INF/" - fi -} - add_automatic_module_name_manifest_entry() { local library=$1 local module_name=$2
diff --git a/util/run-local-gradle-android-tests.sh b/util/run-local-gradle-android-tests.sh index 9ae56f8..1691313 100755 --- a/util/run-local-gradle-android-tests.sh +++ b/util/run-local-gradle-android-tests.sh
@@ -7,35 +7,23 @@ readonly JAVA_ANDROID_GRADLE_PROJECTS=( "javatests/artifacts/dagger-android/simple" + "javatests/artifacts/dagger-android-ksp" "javatests/artifacts/hilt-android/simple" + "javatests/artifacts/hilt-android/pluginMarker" ) readonly KOTLIN_ANDROID_GRADLE_PROJECTS=( "javatests/artifacts/hilt-android/simpleKotlin" ) -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 +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 testDebugUnitTest --continue $COMMON_GRADLE_ARGS +done -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 +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
diff --git a/util/run-local-gradle-tests.sh b/util/run-local-gradle-tests.sh index bb0c458..fca6882 100755 --- a/util/run-local-gradle-tests.sh +++ b/util/run-local-gradle-tests.sh
@@ -5,7 +5,6 @@ readonly GRADLE_PROJECTS=( "javatests/artifacts/dagger" "javatests/artifacts/dagger-ksp" - "javatests/artifacts/hilt-android/pluginMarker" ) for project in "${GRADLE_PROJECTS[@]}"; do echo "Running gradle tests for $project"
diff --git a/util/run-local-tests.sh b/util/run-local-tests.sh index 2603346..d79c8e4 100755 --- a/util/run-local-tests.sh +++ b/util/run-local-tests.sh
@@ -16,7 +16,6 @@ # Run local gradle tests 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" +util/run-local-gradle-android-tests.sh "8.1.1" # TODO: this script is not up-to-date with Dagger github actions
diff --git a/util/validate-artifacts.sh b/util/validate-artifacts.sh new file mode 100755 index 0000000..b556549 --- /dev/null +++ b/util/validate-artifacts.sh
@@ -0,0 +1,56 @@ +#!/bin/bash + +set -eu + +readonly M2_DAGGER_REPO=~/.m2/repository/com/google/dagger +readonly JDK8="52" + +_validate_jar() { + local artifact_id=$1 + local artifact_jar=$M2_DAGGER_REPO/$1/LOCAL-SNAPSHOT/$1-LOCAL-SNAPSHOT.$2 + local java_language_level=$3 + + # Validate the java language level of the classes in the jar. + python $(dirname $0)/validate-jar-language-level.py \ + $artifact_jar $java_language_level + + # Validate the package prefixes of the files in the jar. + if [[ $artifact_id == "dagger-gwt" ]]; then + python $(dirname $0)/validate-jar-entry-prefixes.py \ + $artifact_jar "dagger/,META-INF/,javax/inject/Inject.gwt.xml,jakarta/inject/Inject.gwt.xml,org/jspecify/Jspecify.gwt.xml" + elif [[ $artifact_id == "hilt-android" ]]; then + python $(dirname $0)/validate-jar-entry-prefixes.py \ + $artifact_jar "dagger/,META-INF/,hilt_aggregated_deps/" + else + python $(dirname $0)/validate-jar-entry-prefixes.py \ + $artifact_jar "dagger/,META-INF/" + fi +} + +# Dagger API artifacts +_validate_jar "dagger-gwt" "jar" $JDK8 +_validate_jar "dagger" "jar" $JDK8 +_validate_jar "dagger-android" "aar" $JDK8 +_validate_jar "dagger-android-legacy" "aar" $JDK8 +_validate_jar "dagger-android-support" "aar" $JDK8 +_validate_jar "dagger-android-support-legacy" "aar" $JDK8 +_validate_jar "dagger-producers" "jar" $JDK8 +_validate_jar "dagger-grpc-server" "jar" $JDK8 +_validate_jar "dagger-grpc-server-annotations" "jar" $JDK8 +_validate_jar "dagger-lint" "jar" $JDK8 +_validate_jar "dagger-lint-aar" "aar" $JDK8 + +# Hilt API artifacts +# TODO(bcorso): reenable hilt-android-gradle-plugin validation. +# _validate_jar "hilt-android-gradle-plugin" "jar" $JDK8 +_validate_jar "hilt-core" "jar" $JDK8 +_validate_jar "hilt-android" "aar" $JDK8 +_validate_jar "hilt-android-testing" "aar" $JDK8 + +# Processor artifacts +_validate_jar "dagger-spi" "jar" $JDK8 +_validate_jar "dagger-compiler" "jar" $JDK8 +_validate_jar "dagger-android-processor" "jar" $JDK8 +_validate_jar "dagger-grpc-server-processor" "jar" $JDK8 +_validate_jar "hilt-compiler" "jar" $JDK8 +_validate_jar "hilt-android-compiler" "jar" $JDK8 \ No newline at end of file
diff --git a/util/validate-jar-language-level.py b/util/validate-jar-language-level.py new file mode 100644 index 0000000..ef8afed --- /dev/null +++ b/util/validate-jar-language-level.py
@@ -0,0 +1,109 @@ +"""Validates classes in the deployed jar have a max java language level . + +Usage: + python validate-jar-language-level.py <jar-file> <max-java-language-level> +""" + +import re +import shutil +import subprocess +import sys +import tempfile +import zipfile + + +_LANGUAGE_LEVEL_PATTERN = re.compile(r'major version: (\d+)') + + +def main(argv): + if len(argv) > 3: + raise ValueError( + 'Expected only two arguments but got {0}'.format(len(argv)) + ) + + jar_file, expected_language_level = argv[-2:] + print( + 'Processing {0} with expected language level {1}...'.format( + jar_file, + expected_language_level + ) + ) + if jar_file.endswith('.jar'): + invalid_entries = _invalid_language_level(jar_file, expected_language_level) + elif jar_file.endswith('.aar'): + dirpath = tempfile.mkdtemp() + with zipfile.ZipFile(jar_file, 'r') as zip_file: + class_file = zip_file.extract('classes.jar', dirpath) + invalid_entries = _invalid_language_level( + class_file, + expected_language_level + ) + shutil.rmtree(dirpath) + else: + raise ValueError('Invalid jar file: {0}'.format(jar_file)) + + if invalid_entries: + raise ValueError( + 'Found invalid entries in {0} that do not match the expected java' + ' language level ({1}):\n {2}'.format( + jar_file, expected_language_level, '\n '.join(invalid_entries) + ) + ) + + +def _invalid_language_level(jar_file, expected_language_level): + """Returns a list of jar entries with invalid language levels.""" + invalid_entries = [] + with zipfile.ZipFile(jar_file, 'r') as zip_file: + class_infolist = [ + info for info in zip_file.infolist() + if ( + not info.is_dir() + and info.filename.endswith('.class') + and not is_shaded_class(info.filename) + ) + ] + num_classes = len(class_infolist) + for i, info in enumerate(class_infolist): + cmd = 'javap -cp {0} -v {1}'.format(jar_file, info.filename[:-6]) + output1 = subprocess.run( + cmd.split(), + stdout=subprocess.PIPE, + text=True, + check=True, + ) + matches = _LANGUAGE_LEVEL_PATTERN.findall(output1.stdout) + if len(matches) != 1: + raise ValueError('Expected exactly one match but found: %s' % matches) + class_language_level = matches[0] + if class_language_level != expected_language_level: + invalid_entries.append( + '{0}: {1}'.format(info.filename, class_language_level) + ) + # This can take a while so print an update. + print( + ' ({0} of {1}) Found language level {2}: {3}'.format( + i + 1, + num_classes, + class_language_level, + info.filename, + ) + ) + + return invalid_entries + + +def is_shaded_class(filename): + # Ignore the shaded deps because we don't really control these classes. + shaded_prefixes = [ + 'dagger/spi/internal/shaded/', + 'dagger/grpc/shaded/', + ] + for shaded_prefix in shaded_prefixes: + if filename.startswith(shaded_prefix): + return True + return False + + +if __name__ == '__main__': + main(sys.argv)