Roll forward with fix of 'Support Kotlin val properties with @BindValue.'

When matching javax.lang elements with Kotlin metadata we rely on descriptors. When generating the descriptor of an element whose type is an error (type is not yet resolved, probably a generated type) a fully modeled type is not needed and instead the ErrorType can be treated as a DeclaredType, using its reference names to generate a descriptor containing the class name in its internal form. The fix here is to do just that instead of defaulting to throwing an error when visiting an ErrorType while generating a descriptor.

PiperOrigin-RevId: 333089177
diff --git a/java/dagger/hilt/android/processor/BUILD b/java/dagger/hilt/android/processor/BUILD
index 5be8dbd..95ccb17 100644
--- a/java/dagger/hilt/android/processor/BUILD
+++ b/java/dagger/hilt/android/processor/BUILD
@@ -51,6 +51,7 @@
         "//java/dagger/hilt/processor/internal:component_descriptor",
         "//java/dagger/hilt/processor/internal:component_names",
         "//java/dagger/hilt/processor/internal:components",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/hilt/processor/internal/aggregateddeps:annotation",
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
index 77bac27..f538448 100644
--- a/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
+++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/AndroidEntryPointMetadata.java
@@ -35,9 +35,10 @@
 import dagger.hilt.processor.internal.BadInputException;
 import dagger.hilt.processor.internal.ClassNames;
 import dagger.hilt.processor.internal.Components;
-import dagger.hilt.processor.internal.KotlinMetadata;
+import dagger.hilt.processor.internal.KotlinMetadataUtils;
 import dagger.hilt.processor.internal.ProcessorErrors;
 import dagger.hilt.processor.internal.Processors;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
 import java.util.LinkedHashSet;
 import java.util.Optional;
 import java.util.stream.Collectors;
@@ -251,11 +252,10 @@
       // If this AndroidEntryPoint is a Kotlin class and its base type is also Kotlin and has
       // default values declared in its constructor then error out because for the short-form
       // usage of @AndroidEntryPoint the bytecode transformation will be done incorrectly.
+      KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil();
       ProcessorErrors.checkState(
-          !KotlinMetadata.of(androidEntryPointElement).isPresent()
-              || !KotlinMetadata.of(baseElement)
-                  .map(KotlinMetadata::containsConstructorWithDefaultParam)
-                  .orElse(false),
+          !metadataUtil.hasMetadata(androidEntryPointElement)
+              || !metadataUtil.containsConstructorWithDefaultParam(baseElement),
           baseElement,
           "The base class, '%s', of the @AndroidEntryPoint, '%s', contains a constructor with "
               + "default parameters. This is currently not supported by the Gradle plugin. Either "
diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD
index ff96498..55e9ddc 100644
--- a/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD
+++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/BUILD
@@ -85,9 +85,11 @@
         "//java/dagger/hilt/android/processor/internal:android_classnames",
         "//java/dagger/hilt/processor/internal:classnames",
         "//java/dagger/hilt/processor/internal:components",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/codegen/kotlin",
         "//java/dagger/internal/guava:base",
         "//java/dagger/internal/guava:collect",
         "@google_bazel_common//third_party/java/auto:value",
diff --git a/java/dagger/hilt/android/processor/internal/bindvalue/BUILD b/java/dagger/hilt/android/processor/internal/bindvalue/BUILD
index 092fe0b..cbc51b3 100644
--- a/java/dagger/hilt/android/processor/internal/bindvalue/BUILD
+++ b/java/dagger/hilt/android/processor/internal/bindvalue/BUILD
@@ -37,9 +37,11 @@
         "//java/dagger/hilt/processor/internal:base_processor",
         "//java/dagger/hilt/processor/internal:classnames",
         "//java/dagger/hilt/processor/internal:components",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/codegen/kotlin",
         "//java/dagger/internal/guava:base",
         "//java/dagger/internal/guava:collect",
         "@google_bazel_common//third_party/java/auto:service",
diff --git a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueGenerator.java b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueGenerator.java
index 39005b7..d18e7c4 100644
--- a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueGenerator.java
+++ b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueGenerator.java
@@ -23,6 +23,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.squareup.javapoet.AnnotationSpec;
 import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
 import com.squareup.javapoet.JavaFile;
 import com.squareup.javapoet.MethodSpec;
 import com.squareup.javapoet.ParameterSpec;
@@ -137,7 +138,11 @@
     } else {
       builder
           .addParameter(testClassName, "test")
-          .addStatement("return test.$L", bindValue.variableElement().getSimpleName());
+          .addStatement(
+              "return $L",
+              bindValue.getterElement().isPresent()
+                  ? CodeBlock.of("test.$L()", bindValue.getterElement().get().getSimpleName())
+                  : CodeBlock.of("test.$L", bindValue.variableElement().getSimpleName()));
     }
 
     ClassName annotationClassName = bindValue.annotationName();
diff --git a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java
index a592429..bf50288 100644
--- a/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java
+++ b/java/dagger/hilt/android/processor/internal/bindvalue/BindValueMetadata.java
@@ -18,19 +18,23 @@
 
 import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
 
+import com.google.auto.common.MoreElements;
 import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import com.squareup.javapoet.ClassName;
 import dagger.hilt.processor.internal.ClassNames;
+import dagger.hilt.processor.internal.KotlinMetadataUtils;
 import dagger.hilt.processor.internal.ProcessorErrors;
 import dagger.hilt.processor.internal.Processors;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
 import java.util.Collection;
 import java.util.Optional;
 import javax.inject.Inject;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
@@ -80,6 +84,8 @@
 
     abstract Optional<AnnotationMirror> mapKey();
 
+    abstract Optional<ExecutableElement> getterElement();
+
     static BindValueElement create(Element element) {
       ImmutableList<ClassName> bindValues = BindValueProcessor.getBindValueAnnotations(element);
       ProcessorErrors.checkState(
@@ -97,12 +103,26 @@
           annotationClassName.simpleName(),
           element);
 
-      ProcessorErrors.checkState(
-          !element.getModifiers().contains(Modifier.PRIVATE),
-          element,
-          "@%s fields cannot be private. Found: %s",
-          annotationClassName.simpleName(),
-          element);
+      KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil();
+      Optional<ExecutableElement> propertyGetter =
+          metadataUtil.hasMetadata(element)
+              ? metadataUtil.getPropertyGetter(MoreElements.asVariable(element))
+              : Optional.empty();
+      if (propertyGetter.isPresent()) {
+        ProcessorErrors.checkState(
+            !propertyGetter.get().getModifiers().contains(Modifier.PRIVATE),
+            element,
+            "@%s field getter cannot be private. Found: %s",
+            annotationClassName.simpleName(),
+            element);
+      } else {
+        ProcessorErrors.checkState(
+            !element.getModifiers().contains(Modifier.PRIVATE),
+            element,
+            "@%s fields cannot be private. Found: %s",
+            annotationClassName.simpleName(),
+            element);
+      }
 
       ProcessorErrors.checkState(
           !Processors.hasAnnotation(element, Inject.class),
@@ -151,7 +171,8 @@
           qualifiers.isEmpty()
               ? Optional.<AnnotationMirror>empty()
               : Optional.<AnnotationMirror>of(qualifiers.get(0)),
-          optionalMapKeys);
+          optionalMapKeys,
+          propertyGetter);
     }
   }
 }
diff --git a/java/dagger/hilt/processor/BUILD b/java/dagger/hilt/processor/BUILD
index c04d0bc..b772e9d 100644
--- a/java/dagger/hilt/processor/BUILD
+++ b/java/dagger/hilt/processor/BUILD
@@ -69,6 +69,7 @@
         "//java/dagger/hilt/processor/internal:component_descriptor",
         "//java/dagger/hilt/processor/internal:component_names",
         "//java/dagger/hilt/processor/internal:components",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/hilt/processor/internal/aggregateddeps:annotation",
diff --git a/java/dagger/hilt/processor/internal/BUILD b/java/dagger/hilt/processor/internal/BUILD
index 9c9eb9f..ac57c70 100644
--- a/java/dagger/hilt/processor/internal/BUILD
+++ b/java/dagger/hilt/processor/internal/BUILD
@@ -54,16 +54,20 @@
     name = "processors",
     srcs = [
         "AnnotationValues.java",
-        "KotlinMetadata.java",
         "Processors.java",
     ],
     deps = [
         ":classnames",
+        ":kotlin",
         ":processor_errors",
         "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/codegen/kotlin",
+        "//java/dagger/internal/codegen/langmodel",
         "//java/dagger/internal/guava:base",
         "//java/dagger/internal/guava:collect",
         "@google_bazel_common//third_party/java/javapoet",
+        "@google_bazel_common//third_party/java/jsr305_annotations",
+        "@google_bazel_common//third_party/java/jsr330_inject",
         "@maven//:com_google_auto_auto_common",
         "@maven//:org_jetbrains_kotlin_kotlin_stdlib",
         "@maven//:org_jetbrains_kotlinx_kotlinx_metadata_jvm",
@@ -128,6 +132,15 @@
     ],
 )
 
+java_library(
+    name = "kotlin",
+    srcs = ["KotlinMetadataUtils.java"],
+    deps = [
+        "//:dagger_with_compiler",
+        "//java/dagger/internal/codegen/kotlin",
+    ],
+)
+
 filegroup(
     name = "srcs_filegroup",
     srcs = glob(["*"]),
diff --git a/java/dagger/hilt/processor/internal/KotlinMetadata.java b/java/dagger/hilt/processor/internal/KotlinMetadata.java
deleted file mode 100644
index 2fe6321..0000000
--- a/java/dagger/hilt/processor/internal/KotlinMetadata.java
+++ /dev/null
@@ -1,140 +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.processor.internal;
-
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
-import static dagger.hilt.processor.internal.AnnotationValues.getIntArrayValue;
-import static dagger.hilt.processor.internal.AnnotationValues.getIntValue;
-import static dagger.hilt.processor.internal.AnnotationValues.getOptionalIntValue;
-import static dagger.hilt.processor.internal.AnnotationValues.getOptionalStringValue;
-import static dagger.hilt.processor.internal.AnnotationValues.getStringArrayValue;
-import static dagger.hilt.processor.internal.AnnotationValues.getStringValue;
-
-import com.google.auto.common.MoreElements;
-import java.util.Optional;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.TypeElement;
-import kotlin.Metadata;
-import kotlinx.metadata.Flag;
-import kotlinx.metadata.Flag.ValueParameter;
-import kotlinx.metadata.KmClassVisitor;
-import kotlinx.metadata.KmConstructorVisitor;
-import kotlinx.metadata.KmValueParameterVisitor;
-import kotlinx.metadata.jvm.KotlinClassHeader;
-import kotlinx.metadata.jvm.KotlinClassMetadata;
-
-/** Data class of a TypeElement and its Kotlin metadata. */
-public final class KotlinMetadata {
-
-  private final KotlinClassMetadata.Class metadata;
-  private final TypeElement typeElement;
-
-  /**
-   * Kotlin metadata flag for this class.
-   *
-   * <p>Use {@link Flag.Class} to apply the right mask and obtain a specific value.
-   */
-  private final int flags;
-
-  private KotlinMetadata(KotlinClassMetadata.Class metadata, TypeElement typeElement, int flags) {
-    this.metadata = metadata;
-    this.typeElement = typeElement;
-    this.flags = flags;
-  }
-
-  /** Returns true if the type element of this metadata is a Kotlin object. */
-  public boolean isObjectClass() {
-    return Flag.Class.IS_OBJECT.invoke(flags);
-  }
-
-  /** Returns true if the type element of this metadata is a Kotlin companion object. */
-  public boolean isCompanionObjectClass() {
-    return Flag.Class.IS_COMPANION_OBJECT.invoke(flags);
-  }
-
-  /**
-   * Returns true if the type element of this metadata contains a constructor with declared default
-   * values.
-   */
-  public boolean containsConstructorWithDefaultParam() {
-    final boolean[] containsDefaultParam = { false };
-    metadata.accept(
-        new KmClassVisitor() {
-          private final KmConstructorVisitor constructorVisitor =
-              new KmConstructorVisitor() {
-                @Override
-                public KmValueParameterVisitor visitValueParameter(int flags, String name) {
-                  containsDefaultParam[0] |= ValueParameter.DECLARES_DEFAULT_VALUE.invoke(flags);
-                  return super.visitValueParameter(flags, name);
-                }
-              };
-
-          @Override
-          public KmConstructorVisitor visitConstructor(int flags) {
-            return constructorVisitor;
-          }
-        });
-    return containsDefaultParam[0];
-  }
-
-  /** Returns the Kotlin Metadata of a given type element. */
-  public static Optional<KotlinMetadata> of(TypeElement typeElement) {
-    if (!isAnnotationPresent(typeElement, Metadata.class)) {
-      return Optional.empty();
-    }
-
-    KotlinClassMetadata.Class metadata = metadataOf(typeElement);
-    MetadataVisitor visitor = new MetadataVisitor();
-    metadata.accept(visitor);
-    return Optional.of(new KotlinMetadata(metadata, typeElement, visitor.classFlags));
-  }
-
-  private static KotlinClassMetadata.Class metadataOf(TypeElement typeElement) {
-    AnnotationMirror metadataAnnotation =
-        MoreElements.getAnnotationMirror(typeElement, Metadata.class).get();
-    KotlinClassHeader header =
-        new KotlinClassHeader(
-            getIntValue(metadataAnnotation, "k"),
-            getIntArrayValue(metadataAnnotation, "mv"),
-            getIntArrayValue(metadataAnnotation, "bv"),
-            getStringArrayValue(metadataAnnotation, "d1"),
-            getStringArrayValue(metadataAnnotation, "d2"),
-            getStringValue(metadataAnnotation, "xs"),
-            getOptionalStringValue(metadataAnnotation, "pn").orElse(null),
-            getOptionalIntValue(metadataAnnotation, "xi").orElse(null));
-    KotlinClassMetadata metadata = KotlinClassMetadata.read(header);
-    if (metadata == null) {
-      // Should only happen on Kotlin < 1.0 (i.e. metadata version < 1.1)
-      throw new IllegalStateException(
-          "Unsupported metadata version. Check that your Kotlin version is >= 1.0");
-    }
-    if (metadata instanceof KotlinClassMetadata.Class) {
-      return (KotlinClassMetadata.Class) metadata;
-    } else {
-      throw new IllegalStateException("Unsupported metadata type: " + metadata);
-    }
-  }
-
-  private static final class MetadataVisitor extends KmClassVisitor {
-    int classFlags;
-
-    @Override
-    public void visit(int flags, String s) {
-      this.classFlags = flags;
-    }
-  }
-}
diff --git a/java/dagger/hilt/processor/internal/KotlinMetadataUtils.java b/java/dagger/hilt/processor/internal/KotlinMetadataUtils.java
new file mode 100644
index 0000000..0f762ac
--- /dev/null
+++ b/java/dagger/hilt/processor/internal/KotlinMetadataUtils.java
@@ -0,0 +1,38 @@
+/*
+ * 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.processor.internal;
+
+import dagger.Component;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
+import javax.inject.Singleton;
+
+/** A single-use provider of {@link KotlinMetadataUtil}. */
+public final class KotlinMetadataUtils {
+
+  @Singleton
+  @Component
+  interface MetadataComponent {
+    KotlinMetadataUtil get();
+  }
+
+  /** Gets the metadata util. */
+  public static KotlinMetadataUtil getMetadataUtil() {
+    return DaggerKotlinMetadataUtils_MetadataComponent.create().get();
+  }
+
+  private KotlinMetadataUtils() {}
+}
diff --git a/java/dagger/hilt/processor/internal/Processors.java b/java/dagger/hilt/processor/internal/Processors.java
index b387caf..a0cafc5 100644
--- a/java/dagger/hilt/processor/internal/Processors.java
+++ b/java/dagger/hilt/processor/internal/Processors.java
@@ -17,15 +17,18 @@
 package dagger.hilt.processor.internal;
 
 import static com.google.auto.common.MoreElements.asPackage;
+import static com.google.auto.common.MoreElements.asVariable;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static dagger.internal.codegen.extension.DaggerCollectors.toOptional;
 import static javax.lang.model.element.Modifier.ABSTRACT;
 import static javax.lang.model.element.Modifier.STATIC;
 
+import com.google.auto.common.AnnotationMirrors;
 import com.google.auto.common.GeneratedAnnotations;
 import com.google.auto.common.MoreElements;
 import com.google.auto.common.MoreTypes;
 import com.google.common.base.CaseFormat;
+import com.google.common.base.Equivalence.Wrapper;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.FluentIterable;
@@ -43,6 +46,8 @@
 import com.squareup.javapoet.ParameterizedTypeName;
 import com.squareup.javapoet.TypeName;
 import com.squareup.javapoet.TypeSpec;
+import dagger.internal.codegen.extension.DaggerStreams;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
 import java.lang.annotation.Annotation;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -50,8 +55,10 @@
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.RoundEnvironment;
+import javax.inject.Qualifier;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
@@ -726,7 +733,27 @@
 
   /** Returns Qualifier annotated annotations found on an element. */
   public static ImmutableList<AnnotationMirror> getQualifierAnnotations(Element element) {
-    return getAnnotationsAnnotatedWith(element, ClassNames.QUALIFIER);
+    // TODO(bcorso): Consolidate this logic with InjectionAnnotations in Dagger
+    ImmutableSet<? extends AnnotationMirror> qualifiers =
+        AnnotationMirrors.getAnnotatedAnnotations(element, Qualifier.class);
+    KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil();
+    // TODO(user): Apply an additional check to verify field element has a @BindValue
+    if (element.getKind() == ElementKind.FIELD && metadataUtil.hasMetadata(element)) {
+      VariableElement fieldElement = asVariable(element);
+      return Stream.concat(
+              qualifiers.stream(),
+              metadataUtil.isMissingSyntheticPropertyForAnnotations(fieldElement)
+                  ? Stream.empty()
+                  : metadataUtil
+                      .getSyntheticPropertyAnnotations(fieldElement, Qualifier.class)
+                      .stream())
+          .map(AnnotationMirrors.equivalence()::wrap)
+          .distinct()
+          .map(Wrapper::get)
+          .collect(DaggerStreams.toImmutableList());
+    } else {
+      return ImmutableList.copyOf(qualifiers);
+    }
   }
 
   /** Returns Scope annotated annotations found on an element. */
diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
index 7d04be5..d07e773 100644
--- a/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
+++ b/java/dagger/hilt/processor/internal/aggregateddeps/AggregatedDepsProcessor.java
@@ -37,9 +37,10 @@
 import dagger.hilt.processor.internal.BaseProcessor;
 import dagger.hilt.processor.internal.ClassNames;
 import dagger.hilt.processor.internal.Components;
-import dagger.hilt.processor.internal.KotlinMetadata;
+import dagger.hilt.processor.internal.KotlinMetadataUtils;
 import dagger.hilt.processor.internal.ProcessorErrors;
 import dagger.hilt.processor.internal.Processors;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -290,10 +291,8 @@
   }
 
   private static boolean isKotlinObject(TypeElement type) {
-    Optional<KotlinMetadata> kotlinMetadata = KotlinMetadata.of(type);
-    return kotlinMetadata
-        .map(metadata -> metadata.isObjectClass() || metadata.isCompanionObjectClass())
-        .orElse(false);
+    KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil();
+    return metadataUtil.isObjectClass(type) || metadataUtil.isCompanionObjectClass(type);
   }
 
   private static boolean hasOnlyStaticProvides(TypeElement module) {
diff --git a/java/dagger/hilt/processor/internal/aggregateddeps/BUILD b/java/dagger/hilt/processor/internal/aggregateddeps/BUILD
index f18f7d3..1eb8d36 100644
--- a/java/dagger/hilt/processor/internal/aggregateddeps/BUILD
+++ b/java/dagger/hilt/processor/internal/aggregateddeps/BUILD
@@ -48,9 +48,11 @@
         "//java/dagger/hilt/processor/internal:base_processor",
         "//java/dagger/hilt/processor/internal:classnames",
         "//java/dagger/hilt/processor/internal:components",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/codegen/kotlin",
         "//java/dagger/internal/guava:collect",
         "@google_bazel_common//third_party/java/auto:service",
         "@google_bazel_common//third_party/java/auto:value",
diff --git a/java/dagger/hilt/processor/internal/root/BUILD b/java/dagger/hilt/processor/internal/root/BUILD
index 3a0d0ac..923a79e 100644
--- a/java/dagger/hilt/processor/internal/root/BUILD
+++ b/java/dagger/hilt/processor/internal/root/BUILD
@@ -69,11 +69,13 @@
         ":root_type",
         "//java/dagger/hilt/processor/internal:classnames",
         "//java/dagger/hilt/processor/internal:component_descriptor",
+        "//java/dagger/hilt/processor/internal:kotlin",
         "//java/dagger/hilt/processor/internal:processor_errors",
         "//java/dagger/hilt/processor/internal:processors",
         "//java/dagger/hilt/processor/internal/aggregateddeps:component_dependencies",
         "//java/dagger/hilt/processor/internal/aliasof:alias_ofs",
         "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/codegen/kotlin",
         "//java/dagger/internal/guava:base",
         "//java/dagger/internal/guava:collect",
         "@google_bazel_common//third_party/java/auto:value",
diff --git a/java/dagger/hilt/processor/internal/root/RootMetadata.java b/java/dagger/hilt/processor/internal/root/RootMetadata.java
index 59a3348..d712341 100644
--- a/java/dagger/hilt/processor/internal/root/RootMetadata.java
+++ b/java/dagger/hilt/processor/internal/root/RootMetadata.java
@@ -30,12 +30,12 @@
 import dagger.hilt.processor.internal.ClassNames;
 import dagger.hilt.processor.internal.ComponentDescriptor;
 import dagger.hilt.processor.internal.ComponentTree;
-import dagger.hilt.processor.internal.KotlinMetadata;
+import dagger.hilt.processor.internal.KotlinMetadataUtils;
 import dagger.hilt.processor.internal.Processors;
 import dagger.hilt.processor.internal.aggregateddeps.ComponentDependencies;
 import dagger.hilt.processor.internal.aliasof.AliasOfs;
+import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
 import java.util.List;
-import java.util.Optional;
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
@@ -194,11 +194,9 @@
   }
 
   private static boolean daggerCanConstruct(TypeElement type) {
-    Optional<KotlinMetadata> kotlinMetadata = KotlinMetadata.of(type);
+    KotlinMetadataUtil metadataUtil = KotlinMetadataUtils.getMetadataUtil();
     boolean isKotlinObject =
-        kotlinMetadata
-            .map(metadata -> metadata.isObjectClass() || metadata.isCompanionObjectClass())
-            .orElse(false);
+        metadataUtil.isObjectClass(type) || metadataUtil.isCompanionObjectClass(type);
     if (isKotlinObject) {
       // Treat Kotlin object modules as if Dagger can construct them (it technically can't, but it
       // doesn't need to as it can use them since all their provision methods are static).
diff --git a/java/dagger/internal/codegen/BUILD b/java/dagger/internal/codegen/BUILD
index e64b99b..323e9ca 100644
--- a/java/dagger/internal/codegen/BUILD
+++ b/java/dagger/internal/codegen/BUILD
@@ -79,6 +79,7 @@
     artifact_target_libs = [
         ":package_info",
         "//java/dagger/internal/codegen/base",
+        "//java/dagger/internal/codegen/base:shared",
         "//java/dagger/internal/codegen/binding",
         "//java/dagger/internal/codegen/bindinggraphvalidation",
         "//java/dagger/internal/codegen/compileroption",
diff --git a/java/dagger/internal/codegen/base/BUILD b/java/dagger/internal/codegen/base/BUILD
index 71a5f29..0bcbb12 100644
--- a/java/dagger/internal/codegen/base/BUILD
+++ b/java/dagger/internal/codegen/base/BUILD
@@ -19,12 +19,23 @@
 
 package(default_visibility = ["//:src"])
 
+SHARED_SOURCES = [
+    "ClearableCache.java",
+    "MoreAnnotationMirrors.java",
+    "MoreAnnotationValues.java",
+]
+
 java_library(
     name = "base",
-    srcs = glob(["*.java"]),
+    srcs = glob(
+        ["*.java"],
+        exclude = SHARED_SOURCES,
+    ),
     plugins = ["//java/dagger/internal/codegen/bootstrap"],
     tags = ["maven:merged"],
+    exports = [":shared"],
     deps = [
+        ":shared",
         "//java/dagger:core",
         "//java/dagger/internal/codegen/extension",
         "//java/dagger/internal/codegen/javapoet",
@@ -40,3 +51,16 @@
         "@maven//:com_google_auto_auto_common",
     ],
 )
+
+# TODO(bcorso): Remove this target but first remove spi and producers from :base
+java_library(
+    name = "shared",
+    srcs = SHARED_SOURCES,
+    tags = ["maven:merged"],
+    deps = [
+        "//java/dagger/internal/codegen/extension",
+        "//java/dagger/internal/guava:base",
+        "//java/dagger/internal/guava:collect",
+        "@maven//:com_google_auto_auto_common",
+    ],
+)
diff --git a/java/dagger/internal/codegen/kotlin/BUILD b/java/dagger/internal/codegen/kotlin/BUILD
index b41dfb5..f919ef9 100644
--- a/java/dagger/internal/codegen/kotlin/BUILD
+++ b/java/dagger/internal/codegen/kotlin/BUILD
@@ -25,7 +25,8 @@
     plugins = ["//java/dagger/internal/codegen/bootstrap"],
     tags = ["maven:merged"],
     deps = [
-        "//java/dagger/internal/codegen/base",
+        "//java/dagger:core",
+        "//java/dagger/internal/codegen/base:shared",
         "//java/dagger/internal/codegen/extension",
         "//java/dagger/internal/codegen/langmodel",
         "//java/dagger/internal/guava:base",
diff --git a/java/dagger/internal/codegen/kotlin/KotlinMetadata.java b/java/dagger/internal/codegen/kotlin/KotlinMetadata.java
index c65f5e1..b7ba174 100644
--- a/java/dagger/internal/codegen/kotlin/KotlinMetadata.java
+++ b/java/dagger/internal/codegen/kotlin/KotlinMetadata.java
@@ -16,7 +16,6 @@
 
 package dagger.internal.codegen.kotlin;
 
-import static com.google.auto.common.MoreElements.isAnnotationPresent;
 import static com.google.common.base.Preconditions.checkArgument;
 import static dagger.internal.codegen.base.MoreAnnotationValues.getIntArrayValue;
 import static dagger.internal.codegen.base.MoreAnnotationValues.getIntValue;
@@ -39,18 +38,21 @@
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.annotation.Nullable;
-import javax.inject.Inject;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.VariableElement;
 import javax.lang.model.util.ElementFilter;
 import kotlin.Metadata;
 import kotlinx.metadata.Flag;
+import kotlinx.metadata.Flag.ValueParameter;
 import kotlinx.metadata.KmClassVisitor;
+import kotlinx.metadata.KmConstructorVisitor;
 import kotlinx.metadata.KmExtensionType;
 import kotlinx.metadata.KmPropertyExtensionVisitor;
 import kotlinx.metadata.KmPropertyVisitor;
+import kotlinx.metadata.KmValueParameterVisitor;
 import kotlinx.metadata.jvm.JvmFieldSignature;
 import kotlinx.metadata.jvm.JvmMethodSignature;
 import kotlinx.metadata.jvm.JvmPropertyExtensionVisitor;
@@ -62,49 +64,156 @@
 
   private final TypeElement typeElement;
 
+  private final KotlinClassMetadata.Class data;
+
   /**
    * Kotlin metadata flag for this class.
    *
    * <p>Use {@link Flag.Class} to apply the right mask and obtain a specific value.
    */
-  private final int flags;
+  private final Supplier<Integer> flags;
 
-  private final Optional<String> companionObjectName;
+  private final Supplier<Optional<String>> companionObjectName;
 
-  // Map that associates @Inject field elements with its Kotlin synthetic method for annotations.
+  private final Supplier<List<Property>> properties;
+
+  private final Supplier<Map<String, Property>> propertyDescriptors;
+
+  private final Supplier<Map<String, ExecutableElement>> methodDescriptors;
+
+  // Map that associates field elements with its Kotlin synthetic method for annotations.
   private final Supplier<Map<VariableElement, Optional<MethodForAnnotations>>>
       elementFieldAnnotationMethodMap;
 
-  private KotlinMetadata(
-      TypeElement typeElement,
-      int flags,
-      Optional<String> companionObjectName,
-      List<Property> properties) {
+  // Map that associates field elements with its Kotlin getter method.
+  private final Supplier<Map<VariableElement, Optional<ExecutableElement>>>
+      elementFieldGetterMethodMap;
+
+  private final Supplier<Boolean> containsConstructorWithDefaultParam;
+
+  private KotlinMetadata(TypeElement typeElement, KotlinClassMetadata.Class data) {
     this.typeElement = typeElement;
-    this.flags = flags;
-    this.companionObjectName = companionObjectName;
+    this.data = data;
+    this.flags = Suppliers.memoize(this::retrieveFlags);
+    this.companionObjectName = Suppliers.memoize(this::retrieveCompanionObjectName);
+    this.properties = Suppliers.memoize(this::retrieveProperties);
+    this.propertyDescriptors =
+        Suppliers.memoize(
+            () ->
+                properties.get().stream()
+                    .filter(property -> property.getFieldSignature().isPresent())
+                    .collect(
+                        Collectors.toMap(
+                            property -> property.getFieldSignature().get(), Function.identity())));
+    this.methodDescriptors =
+        Suppliers.memoize(
+            () ->
+                ElementFilter.methodsIn(typeElement.getEnclosedElements()).stream()
+                    .collect(
+                        Collectors.toMap(
+                            DaggerElements::getMethodDescriptor, Function.identity())));
     this.elementFieldAnnotationMethodMap =
         Suppliers.memoize(
-            () -> {
-              Map<String, Property> propertyDescriptors =
-                  properties.stream()
-                      .filter(property -> property.getFieldSignature().isPresent())
-                      .collect(
-                          Collectors.toMap(
-                              property -> property.getFieldSignature().get(), Function.identity()));
-              Map<String, ExecutableElement> methodDescriptors =
-                  ElementFilter.methodsIn(typeElement.getEnclosedElements()).stream()
-                      .collect(
-                          Collectors.toMap(
-                              DaggerElements::getMethodDescriptor, Function.identity()));
-              return mapFieldToAnnotationMethod(propertyDescriptors, methodDescriptors);
-            });
+            () -> mapFieldToAnnotationMethod(propertyDescriptors.get(), methodDescriptors.get()));
+    this.elementFieldGetterMethodMap =
+        Suppliers.memoize(
+            () -> mapFieldToGetterMethod(propertyDescriptors.get(), methodDescriptors.get()));
+    this.containsConstructorWithDefaultParam =
+        Suppliers.memoize(this::checkConstructorForDefaultParam);
+  }
+
+  private int retrieveFlags() {
+    FlagsVisitor visitor = new FlagsVisitor();
+    data.accept(visitor);
+    return visitor.flags;
+  }
+
+  private static final class FlagsVisitor extends KmClassVisitor {
+
+    int flags;
+
+    @Override
+    public void visit(int flags, String name) {
+      this.flags = flags;
+    }
+  }
+
+  private Optional<String> retrieveCompanionObjectName() {
+    CompanionObjectNameVisitor visitor = new CompanionObjectNameVisitor();
+    data.accept(visitor);
+    return visitor.name;
+  }
+
+  private static final class CompanionObjectNameVisitor extends KmClassVisitor {
+
+    Optional<String> name = Optional.empty();
+
+    @Override
+    public void visitCompanionObject(String name) {
+      this.name = Optional.of(name);
+    }
+  }
+
+  private List<Property> retrieveProperties() {
+    PropertiesVisitor visitor = new PropertiesVisitor();
+    data.accept(visitor);
+    return visitor.properties;
+  }
+
+  private static final class PropertiesVisitor extends KmClassVisitor {
+
+    List<Property> properties = new ArrayList<>();
+
+    @Override
+    public KmPropertyVisitor visitProperty(
+        int flags, String name, int getterFlags, int setterFlags) {
+      return new KmPropertyVisitor() {
+        Optional<String> fieldSignature;
+        Optional<String> getterSignature = Optional.empty();
+        Optional<String> methodForAnnotationsSignature = Optional.empty();
+
+        @Override
+        public KmPropertyExtensionVisitor visitExtensions(KmExtensionType kmExtensionType) {
+          if (!kmExtensionType.equals(JvmPropertyExtensionVisitor.TYPE)) {
+            return null;
+          }
+
+          return new JvmPropertyExtensionVisitor() {
+            @Override
+            public void visit(
+                int jvmFlags,
+                @Nullable JvmFieldSignature jvmFieldSignature,
+                @Nullable JvmMethodSignature jvmGetterSignature,
+                @Nullable JvmMethodSignature jvmSetterSignature) {
+              fieldSignature =
+                  Optional.ofNullable(jvmFieldSignature).map(JvmFieldSignature::asString);
+              getterSignature =
+                  Optional.ofNullable(jvmGetterSignature).map(JvmMethodSignature::asString);
+            }
+
+            @Override
+            public void visitSyntheticMethodForAnnotations(
+                @Nullable JvmMethodSignature methodSignature) {
+              methodForAnnotationsSignature =
+                  Optional.ofNullable(methodSignature).map(JvmMethodSignature::asString);
+            }
+          };
+        }
+
+        @Override
+        public void visitEnd() {
+          properties.add(
+              new Property(
+                  name, flags, fieldSignature, getterSignature, methodForAnnotationsSignature));
+        }
+      };
+    }
   }
 
   private Map<VariableElement, Optional<MethodForAnnotations>> mapFieldToAnnotationMethod(
       Map<String, Property> propertyDescriptors, Map<String, ExecutableElement> methodDescriptors) {
     return ElementFilter.fieldsIn(typeElement.getEnclosedElements()).stream()
-        .filter(field -> isAnnotationPresent(field, Inject.class))
+        .filter(field -> !field.getModifiers().contains(Modifier.STATIC))
         .collect(
             Collectors.toMap(
                 Function.identity(),
@@ -120,6 +229,20 @@
                                     .orElse(MethodForAnnotations.MISSING))));
   }
 
+  private Map<VariableElement, Optional<ExecutableElement>> mapFieldToGetterMethod(
+      Map<String, Property> propertyDescriptors, Map<String, ExecutableElement> methodDescriptors) {
+    return ElementFilter.fieldsIn(typeElement.getEnclosedElements()).stream()
+        .filter(field -> !field.getModifiers().contains(Modifier.STATIC))
+        .collect(
+            Collectors.toMap(
+                Function.identity(),
+                field ->
+                    findProperty(field, propertyDescriptors)
+                        .getGetterMethodSignature()
+                        .flatMap(
+                            signature -> Optional.ofNullable(methodDescriptors.get(signature)))));
+  }
+
   private Property findProperty(VariableElement field, Map<String, Property> propertyDescriptors) {
     String fieldDescriptor = getFieldDescriptor(field);
     if (propertyDescriptors.containsKey(fieldDescriptor)) {
@@ -132,11 +255,34 @@
     }
   }
 
+  private boolean checkConstructorForDefaultParam() {
+    ConstructorWithDefaultParamVisitor visitor = new ConstructorWithDefaultParamVisitor();
+    data.accept(visitor);
+    return visitor.containsConstructorWithDefaultParam;
+  }
+
+  private static final class ConstructorWithDefaultParamVisitor extends KmClassVisitor {
+
+    boolean containsConstructorWithDefaultParam;
+
+    @Override
+    public KmConstructorVisitor visitConstructor(int flags) {
+      return new KmConstructorVisitor() {
+        @Override
+        public KmValueParameterVisitor visitValueParameter(int flags, String name) {
+          containsConstructorWithDefaultParam |=
+              ValueParameter.DECLARES_DEFAULT_VALUE.invoke(flags);
+          return super.visitValueParameter(flags, name);
+        }
+      };
+    }
+  }
+
   TypeElement getTypeElement() {
     return typeElement;
   }
 
-  /** Gets the synthetic method for annotations of a given @Inject annotated field element. */
+  /** Gets the synthetic method for annotations of a given field element. */
   Optional<ExecutableElement> getSyntheticAnnotationMethod(VariableElement fieldElement) {
     checkArgument(elementFieldAnnotationMethodMap.get().containsKey(fieldElement));
     return elementFieldAnnotationMethodMap
@@ -169,12 +315,12 @@
   }
 
   boolean isObjectClass() {
-    return Flag.Class.IS_OBJECT.invoke(flags);
+    return Flag.Class.IS_OBJECT.invoke(flags.get());
   }
 
   /** Returns true if the type element of this metadata is a Kotlin companion object. */
   boolean isCompanionObjectClass() {
-    return Flag.Class.IS_COMPANION_OBJECT.invoke(flags);
+    return Flag.Class.IS_COMPANION_OBJECT.invoke(flags.get());
   }
 
   /**
@@ -183,19 +329,27 @@
    * returns an empty optional.
    */
   Optional<String> getCompanionObjectName() {
-    return companionObjectName;
+    return companionObjectName.get();
   }
 
   boolean isPrivate() {
-    return Flag.IS_PRIVATE.invoke(flags);
+    return Flag.IS_PRIVATE.invoke(flags.get());
+  }
+
+  /** Gets the getter method of a given field element corresponding to a property. */
+  Optional<ExecutableElement> getPropertyGetter(VariableElement fieldElement) {
+    checkArgument(elementFieldGetterMethodMap.get().containsKey(fieldElement));
+    return elementFieldGetterMethodMap.get().get(fieldElement);
+  }
+
+  /** Returns true if any constructor of the defined a default parameter. */
+  public boolean containsConstructorWithDefaultParam() {
+    return containsConstructorWithDefaultParam.get();
   }
 
   /** Parse Kotlin class metadata from a given type element * */
   static KotlinMetadata from(TypeElement typeElement) {
-    MetadataVisitor visitor = new MetadataVisitor();
-    metadataOf(typeElement).accept(visitor);
-    return new KotlinMetadata(
-        typeElement, visitor.classFlags, visitor.companionObjectName, visitor.classProperties);
+    return new KotlinMetadata(typeElement, metadataOf(typeElement));
   }
 
   private static KotlinClassMetadata.Class metadataOf(TypeElement typeElement) {
@@ -226,80 +380,25 @@
     }
   }
 
-  private static final class MetadataVisitor extends KmClassVisitor {
-
-    int classFlags;
-    Optional<String> companionObjectName = Optional.empty();
-    List<Property> classProperties = new ArrayList<>();
-
-    @Override
-    public void visit(int flags, String s) {
-      this.classFlags = flags;
-    }
-
-    @Override
-    public void visitCompanionObject(@Nullable String companionObjectName) {
-      this.companionObjectName = Optional.ofNullable(companionObjectName);
-    }
-
-    @Override
-    public KmPropertyVisitor visitProperty(
-        int flags, String name, int getterFlags, int setterFlags) {
-      return new KmPropertyVisitor() {
-        Optional<String> fieldSignature;
-        Optional<String> methodForAnnotationsSignature = Optional.empty();
-
-        @Override
-        public KmPropertyExtensionVisitor visitExtensions(KmExtensionType kmExtensionType) {
-          if (!kmExtensionType.equals(JvmPropertyExtensionVisitor.TYPE)) {
-            return null;
-          }
-
-          return new JvmPropertyExtensionVisitor() {
-            @Override
-            public void visit(
-                int jvmFlags,
-                @Nullable JvmFieldSignature jvmFieldSignature,
-                @Nullable JvmMethodSignature getterSignature,
-                @Nullable JvmMethodSignature setterSignature) {
-              fieldSignature =
-                  Optional.ofNullable(jvmFieldSignature).map(JvmFieldSignature::asString);
-            }
-
-            @Override
-            public void visitSyntheticMethodForAnnotations(
-                @Nullable JvmMethodSignature methodSignature) {
-              methodForAnnotationsSignature =
-                  Optional.ofNullable(methodSignature).map(JvmMethodSignature::asString);
-            }
-          };
-        }
-
-        @Override
-        public void visitEnd() {
-          classProperties.add(
-              new Property(name, flags, fieldSignature, methodForAnnotationsSignature));
-        }
-      };
-    }
-  }
-
   /* Data class representing Kotlin Property Metadata */
   private static final class Property {
 
     private final String name;
     private final int flags;
     private final Optional<String> fieldSignature;
+    private final Optional<String> getterSignature;
     private final Optional<String> methodForAnnotationsSignature;
 
     Property(
         String name,
         int flags,
         Optional<String> fieldSignature,
+        Optional<String> getterSignature,
         Optional<String> methodForAnnotationsSignature) {
       this.name = name;
       this.flags = flags;
       this.fieldSignature = fieldSignature;
+      this.getterSignature = getterSignature;
       this.methodForAnnotationsSignature = methodForAnnotationsSignature;
     }
 
@@ -322,6 +421,10 @@
       return fieldSignature;
     }
 
+    Optional<String> getGetterMethodSignature() {
+      return getterSignature;
+    }
+
     /** Returns JVM method descriptor of the synthetic method for property annotations. */
     Optional<String> getMethodForAnnotationsSignature() {
       return methodForAnnotationsSignature;
diff --git a/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java b/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java
index 1d49254..13c7cf2 100644
--- a/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java
+++ b/java/dagger/internal/codegen/kotlin/KotlinMetadataUtil.java
@@ -24,6 +24,7 @@
 import com.google.common.collect.ImmutableList;
 import dagger.internal.codegen.extension.DaggerCollectors;
 import java.lang.annotation.Annotation;
+import java.util.Optional;
 import javax.inject.Inject;
 import javax.lang.model.element.AnnotationMirror;
 import javax.lang.model.element.Element;
@@ -114,6 +115,15 @@
     return hasMetadata(typeElement) && metadataFactory.create(typeElement).isPrivate();
   }
 
+  public Optional<ExecutableElement> getPropertyGetter(VariableElement fieldElement) {
+    return metadataFactory.create(fieldElement).getPropertyGetter(fieldElement);
+  }
+
+  public boolean containsConstructorWithDefaultParam(TypeElement typeElement) {
+    return hasMetadata(typeElement)
+        && metadataFactory.create(typeElement).containsConstructorWithDefaultParam();
+  }
+
   /**
    * Returns {@code true} if the <code>@JvmStatic</code> annotation is present in the given element.
    */
diff --git a/java/dagger/internal/codegen/langmodel/DaggerElements.java b/java/dagger/internal/codegen/langmodel/DaggerElements.java
index 63c5e1d..12cec31 100644
--- a/java/dagger/internal/codegen/langmodel/DaggerElements.java
+++ b/java/dagger/internal/codegen/langmodel/DaggerElements.java
@@ -291,7 +291,9 @@
 
         @Override
         public String visitError(ErrorType errorType, Void v) {
-          return visitUnknown(errorType, null);
+          // For descriptor generating purposes we don't need a fully modeled type since we are
+          // only interested in obtaining the class name in its "internal form".
+          return visitDeclared(errorType, v);
         }
 
         @Override
diff --git a/javatests/artifacts/hilt-android/simpleKotlin/app/src/test/java/dagger/hilt/android/simpleKotlin/SimpleTest.kt b/javatests/artifacts/hilt-android/simpleKotlin/app/src/test/java/dagger/hilt/android/simpleKotlin/SimpleTest.kt
index 95b1417..2356ced 100644
--- a/javatests/artifacts/hilt-android/simpleKotlin/app/src/test/java/dagger/hilt/android/simpleKotlin/SimpleTest.kt
+++ b/javatests/artifacts/hilt-android/simpleKotlin/app/src/test/java/dagger/hilt/android/simpleKotlin/SimpleTest.kt
@@ -44,7 +44,7 @@
 class SimpleTest {
   @get:Rule val rule = HiltAndroidRule(this)
 
-  @BindValue @JvmField val bindStr = "STRING_BINDING"
+  @BindValue val bindStr = "STRING_BINDING"
 
   @Inject @JvmField var str: String? = null