Refactor kotlinmemberinfo into function, field and property info

Change-Id: I7f7d42f4cc8dc77db8ce13a07c4f46647ad8f0a8
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
index e9251be..5275c4d 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinInfo.java
@@ -13,6 +13,8 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.kotlin.KotlinMemberInfo.KotlinFieldInfo;
+import com.android.tools.r8.kotlin.KotlinMemberInfo.KotlinPropertyInfo;
 import com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.KmPropertyGroup;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -169,12 +171,13 @@
     }
     for (DexEncodedField field : fields) {
       if (backingFieldTester.test(field)) {
-        String name = field.getKotlinMemberInfo().propertyName;
+        KotlinFieldInfo kotlinFieldInfo = field.getKotlinMemberInfo().asFieldInfo();
+        assert kotlinFieldInfo != null;
+        String name = kotlinFieldInfo.propertyName;
         assert name != null;
         KmPropertyGroup.Builder builder =
             propertyGroupBuilderMap.computeIfAbsent(
-                name,
-                k -> KmPropertyGroup.builder(field.getKotlinMemberInfo().propertyFlags, name));
+                name, k -> KmPropertyGroup.builder(kotlinFieldInfo.flags, name));
         builder.foundBackingField(field);
       }
     }
@@ -183,26 +186,28 @@
         continue;
       }
       if (method.isKotlinProperty() || method.isKotlinExtensionProperty()) {
-        String name = method.getKotlinMemberInfo().propertyName;
+        assert method.getKotlinMemberInfo().isPropertyInfo();
+        KotlinPropertyInfo kotlinPropertyInfo = method.getKotlinMemberInfo().asPropertyInfo();
+        String name = kotlinPropertyInfo.propertyName;
         assert name != null;
         KmPropertyGroup.Builder builder =
             propertyGroupBuilderMap.computeIfAbsent(
                 name,
                 // Hitting here (creating a property builder) after visiting all fields means that
                 // this property doesn't have a backing field. Don't use members' flags.
-                k -> KmPropertyGroup.builder(method.getKotlinMemberInfo().propertyFlags, name));
-        switch (method.getKotlinMemberInfo().memberKind) {
+                k -> KmPropertyGroup.builder(kotlinPropertyInfo.flags, name));
+        switch (kotlinPropertyInfo.memberKind) {
           case EXTENSION_PROPERTY_GETTER:
             builder.isExtensionGetter();
             // fallthrough;
           case PROPERTY_GETTER:
-            builder.foundGetter(method, method.getKotlinMemberInfo().flags);
+            builder.foundGetter(method, kotlinPropertyInfo.getterFlags);
             break;
           case EXTENSION_PROPERTY_SETTER:
             builder.isExtensionSetter();
             // fallthrough;
           case PROPERTY_SETTER:
-            builder.foundSetter(method, method.getKotlinMemberInfo().flags);
+            builder.foundSetter(method, kotlinPropertyInfo.setterFlags);
             break;
           case EXTENSION_PROPERTY_ANNOTATIONS:
             builder.isExtensionAnnotations();
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMemberInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMemberInfo.java
index dfdb28b..4238d3e 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMemberInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMemberInfo.java
@@ -3,6 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.kotlin;
 
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.CONSTRUCTOR;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.EXTENSION_FUNCTION;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.EXTENSION_PROPERTY_GETTER;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.EXTENSION_PROPERTY_SETTER;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.FUNCTION;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.PROPERTY_GETTER;
+import static com.android.tools.r8.kotlin.KotlinMemberInfo.MemberKind.PROPERTY_SETTER;
+import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.getJvmMethodSignature;
 import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.toJvmFieldSignature;
 import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.toJvmMethodSignature;
 import static com.android.tools.r8.kotlin.KotlinMetadataSynthesizer.isExtension;
@@ -10,7 +18,6 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.KmFunctionProcessor;
 import com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.KmPropertyProcessor;
 import com.android.tools.r8.utils.Reporter;
 import com.google.common.collect.ImmutableList;
@@ -18,18 +25,19 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import kotlinx.metadata.KmConstructor;
 import kotlinx.metadata.KmDeclarationContainer;
 import kotlinx.metadata.KmFunction;
 import kotlinx.metadata.KmProperty;
 import kotlinx.metadata.KmValueParameter;
+import kotlinx.metadata.jvm.JvmMethodSignature;
 
 // Provides access to field/method-level Kotlin information.
-public class KotlinMemberInfo {
-  private static final List<KmValueParameter> EMPTY_PARAM = ImmutableList.of();
+public abstract class KotlinMemberInfo {
+
   private static final List<KotlinValueParameterInfo> EMPTY_PARAM_INFO = ImmutableList.of();
 
-  private static final KotlinMemberInfo NO_KOTLIN_MEMBER_INFO =
-      new KotlinMemberInfo(MemberKind.NONE, 0, EMPTY_PARAM);
+  private static final KotlinMemberInfo NO_KOTLIN_MEMBER_INFO = new NoKotlinMemberInfo();
 
   public static KotlinMemberInfo getNoKotlinMemberInfo() {
     return NO_KOTLIN_MEMBER_INFO;
@@ -38,76 +46,180 @@
   public final MemberKind memberKind;
   // Original member flags. May be necessary to keep Kotlin-specific flag, e.g., suspend function.
   final int flags;
-  // TODO(b/151194869): better to split into FunctionInfo v.s. PropertyInfo ?
-  // Original property flags. E.g., for property getter, getter flags are stored to `flags`, while
-  // the property's flags are stored here, in case of properties without a backing field.
-  final int propertyFlags;
-  // Original property name for (extension) property. Otherwise, null.
-  final String propertyName;
-  // Information from original KmValueParameter(s) if available. Otherwise, null.
-  private final List<KotlinValueParameterInfo> valueParameterInfos;
 
-  // Constructor for KmFunction
-  private KotlinMemberInfo(
-      MemberKind memberKind, int flags, List<KmValueParameter> kmValueParameters) {
-    this(memberKind, flags, 0, null, kmValueParameters);
-  }
-
-  // Constructor for a backing field and a getter in KmProperty
-  private KotlinMemberInfo(
-      MemberKind memberKind, int flags, int propertyFlags, String propertyName) {
-    this(memberKind, flags, propertyFlags, propertyName, EMPTY_PARAM);
-  }
-
-  // Constructor for a setter in KmProperty
-  private KotlinMemberInfo(
-      MemberKind memberKind,
-      int flags,
-      int propertyFlags,
-      String propertyName,
-      KmValueParameter kmValueParameter) {
-    this(
-        memberKind,
-        flags,
-        propertyFlags,
-        propertyName,
-        kmValueParameter != null ? ImmutableList.of(kmValueParameter) : EMPTY_PARAM);
-  }
-
-  private KotlinMemberInfo(
-      MemberKind memberKind,
-      int flags,
-      int propertyFlags,
-      String propertyName,
-      List<KmValueParameter> kmValueParameters) {
+  private KotlinMemberInfo(MemberKind memberKind, int flags) {
     this.memberKind = memberKind;
     this.flags = flags;
-    this.propertyFlags = propertyFlags;
-    this.propertyName = propertyName;
-    assert kmValueParameters != null;
-    if (kmValueParameters.isEmpty()) {
-      this.valueParameterInfos = EMPTY_PARAM_INFO;
-    } else {
-      this.valueParameterInfos = new ArrayList<>(kmValueParameters.size());
-      for (KmValueParameter kmValueParameter : kmValueParameters) {
-        valueParameterInfos.add(KotlinValueParameterInfo.fromKmValueParameter(kmValueParameter));
-      }
+  }
+
+  public boolean isFunctionInfo() {
+    return false;
+  }
+
+  public KotlinFunctionInfo asFunctionInfo() {
+    return null;
+  }
+
+  public boolean isFieldInfo() {
+    return false;
+  }
+
+  public KotlinFieldInfo asFieldInfo() {
+    return null;
+  }
+
+  public boolean isPropertyInfo() {
+    return false;
+  }
+
+  public KotlinPropertyInfo asPropertyInfo() {
+    return null;
+  }
+
+  private static class NoKotlinMemberInfo extends KotlinMemberInfo {
+
+    private NoKotlinMemberInfo() {
+      super(MemberKind.NONE, 0);
     }
   }
 
-  KotlinValueParameterInfo getValueParameterInfo(int i) {
-    if (valueParameterInfos.isEmpty()) {
-      return null;
+  public static class KotlinFunctionInfo extends KotlinMemberInfo {
+
+    // Information from original KmValueParameter(s) if available.
+    private final List<KotlinValueParameterInfo> valueParameterInfos;
+
+    private KotlinFunctionInfo(
+        MemberKind memberKind, int flags, List<KotlinValueParameterInfo> valueParameterInfos) {
+      super(memberKind, flags);
+      assert memberKind.isFunction() || memberKind.isConstructor();
+      this.valueParameterInfos = valueParameterInfos;
     }
-    if (i < 0 || i >= valueParameterInfos.size()) {
-      return null;
+
+    KotlinValueParameterInfo getValueParameterInfo(int i) {
+      if (valueParameterInfos.isEmpty()) {
+        return null;
+      }
+      if (i < 0 || i >= valueParameterInfos.size()) {
+        return null;
+      }
+      return valueParameterInfos.get(i);
     }
-    return valueParameterInfos.get(i);
+
+    @Override
+    public boolean isFunctionInfo() {
+      return true;
+    }
+
+    @Override
+    public KotlinFunctionInfo asFunctionInfo() {
+      return this;
+    }
+  }
+
+  public static class KotlinFieldInfo extends KotlinMemberInfo {
+
+    // Original property name for (extension) property. Otherwise, null.
+    final String propertyName;
+
+    private KotlinFieldInfo(MemberKind memberKind, int flags, String propertyName) {
+      super(memberKind, flags);
+      this.propertyName = propertyName;
+    }
+
+    @Override
+    public boolean isFieldInfo() {
+      return true;
+    }
+
+    @Override
+    public KotlinFieldInfo asFieldInfo() {
+      return this;
+    }
+  }
+
+  public static class KotlinPropertyInfo extends KotlinMemberInfo {
+
+    // Original getter flags. E.g., for property getter.
+    final int getterFlags;
+
+    // Original setter flags. E.g., for property setter.
+    final int setterFlags;
+
+    // Original property name for (extension) property. Otherwise, null.
+    final String propertyName;
+
+    // Information from original KmValueParameter if available.
+    final KotlinValueParameterInfo valueParameterInfo;
+
+    private KotlinPropertyInfo(
+        MemberKind memberKind,
+        int flags,
+        int getterFlags,
+        int setterFlags,
+        String propertyName,
+        KotlinValueParameterInfo valueParameterInfo) {
+      super(memberKind, flags);
+      this.getterFlags = getterFlags;
+      this.setterFlags = setterFlags;
+      this.propertyName = propertyName;
+      this.valueParameterInfo = valueParameterInfo;
+    }
+
+    @Override
+    public KotlinPropertyInfo asPropertyInfo() {
+      return this;
+    }
+
+    @Override
+    public boolean isPropertyInfo() {
+      return true;
+    }
+  }
+
+  private static KotlinFunctionInfo createFunctionInfoFromConstructor(KmConstructor kmConstructor) {
+    return createFunctionInfo(
+        CONSTRUCTOR, kmConstructor.getFlags(), kmConstructor.getValueParameters());
+  }
+
+  private static KotlinFunctionInfo createFunctionInfo(
+      MemberKind memberKind, KmFunction kmFunction) {
+    return createFunctionInfo(memberKind, kmFunction.getFlags(), kmFunction.getValueParameters());
+  }
+
+  private static KotlinFunctionInfo createFunctionInfo(
+      MemberKind memberKind, int flags, List<KmValueParameter> valueParameters) {
+    assert memberKind.isFunction() || memberKind.isConstructor();
+    if (valueParameters.isEmpty()) {
+      return new KotlinFunctionInfo(memberKind, flags, EMPTY_PARAM_INFO);
+    }
+    List<KotlinValueParameterInfo> valueParameterInfos = new ArrayList<>(valueParameters.size());
+    for (KmValueParameter kmValueParameter : valueParameters) {
+      valueParameterInfos.add(KotlinValueParameterInfo.fromKmValueParameter(kmValueParameter));
+    }
+    return new KotlinFunctionInfo(memberKind, flags, valueParameterInfos);
+  }
+
+  private static KotlinFieldInfo createFieldInfo(MemberKind memberKind, KmProperty kmProperty) {
+    assert memberKind.isBackingField() || memberKind.isBackingFieldForCompanionObject();
+    return new KotlinFieldInfo(memberKind, kmProperty.getFlags(), kmProperty.getName());
+  }
+
+  private static KotlinPropertyInfo createPropertyInfo(
+      MemberKind memberKind, KmProperty kmProperty) {
+    assert memberKind.isProperty();
+    return new KotlinPropertyInfo(
+        memberKind,
+        kmProperty.getFlags(),
+        kmProperty.getGetterFlags(),
+        kmProperty.getSetterFlags(),
+        kmProperty.getName(),
+        KotlinValueParameterInfo.fromKmValueParameter(kmProperty.getSetterParameter()));
   }
 
   public enum MemberKind {
     NONE,
 
+    CONSTRUCTOR,
     FUNCTION,
     EXTENSION_FUNCTION,
 
@@ -122,6 +234,10 @@
     EXTENSION_PROPERTY_SETTER,
     EXTENSION_PROPERTY_ANNOTATIONS;
 
+    public boolean isConstructor() {
+      return this == CONSTRUCTOR;
+    }
+
     public boolean isFunction() {
       return this == FUNCTION || isExtensionFunction();
     }
@@ -159,23 +275,37 @@
       return;
     }
 
-    KmDeclarationContainer kmDeclarationContainer = kotlinInfo.getDeclarations();
-    String companionObject = null;
-    if (kotlinInfo.isClass()) {
-      companionObject = kotlinInfo.asClass().kmClass.getCompanionObject();
-    }
-
+    Map<String, KmConstructor> kmConstructorMap = new HashMap<>();
     Map<String, KmFunction> kmFunctionMap = new HashMap<>();
     Map<String, KmProperty> kmPropertyFieldMap = new HashMap<>();
     Map<String, KmProperty> kmPropertyGetterMap = new HashMap<>();
     Map<String, KmProperty> kmPropertySetterMap = new HashMap<>();
 
-    kmDeclarationContainer.getFunctions().forEach(kmFunction -> {
-      KmFunctionProcessor functionProcessor = new KmFunctionProcessor(kmFunction, reporter);
-      if (functionProcessor.signature() != null) {
-        kmFunctionMap.put(functionProcessor.signature().asString(), kmFunction);
-      }
-    });
+    KmDeclarationContainer kmDeclarationContainer = kotlinInfo.getDeclarations();
+    String companionObject = null;
+    if (kotlinInfo.isClass()) {
+      companionObject = kotlinInfo.asClass().kmClass.getCompanionObject();
+      kotlinInfo
+          .asClass()
+          .kmClass
+          .getConstructors()
+          .forEach(
+              kmConstructor -> {
+                JvmMethodSignature methodSignature = getJvmMethodSignature(kmConstructor, reporter);
+                if (methodSignature != null) {
+                  kmConstructorMap.put(methodSignature.asString(), kmConstructor);
+                }
+              });
+    }
+    kmDeclarationContainer
+        .getFunctions()
+        .forEach(
+            kmFunction -> {
+              JvmMethodSignature methodSignature = getJvmMethodSignature(kmFunction, reporter);
+              if (methodSignature != null) {
+                kmFunctionMap.put(methodSignature.asString(), kmFunction);
+              }
+            });
     kmDeclarationContainer.getProperties().forEach(kmProperty -> {
       KmPropertyProcessor propertyProcessor = new KmPropertyProcessor(kmProperty, reporter);
       if (propertyProcessor.fieldSignature() != null) {
@@ -200,72 +330,35 @@
       if (kmPropertyFieldMap.containsKey(key)) {
         KmProperty kmProperty = kmPropertyFieldMap.get(key);
         field.setKotlinMemberInfo(
-            new KotlinMemberInfo(
+            createFieldInfo(
                 clazz == kotlinInfo.clazz
                     ? MemberKind.PROPERTY_BACKING_FIELD
                     : MemberKind.COMPANION_OBJECT_BACKING_FIELD,
-                kmProperty.getFlags(),
-                kmProperty.getFlags(),
-                kmProperty.getName()));
+                kmProperty));
       }
     }
 
     for (DexEncodedMethod method : clazz.methods()) {
-      if (method.isInitializer()) {
-        continue;
-      }
       String key = toJvmMethodSignature(method.method).asString();
-      if (kmFunctionMap.containsKey(key)) {
+      if (kmConstructorMap.containsKey(key)) {
+        // Interestingly we cannot assert that the method is a jvm initializer, because the jvm
+        // signature can be a different.
+        method.setKotlinMemberInfo(createFunctionInfoFromConstructor(kmConstructorMap.get(key)));
+      } else if (kmFunctionMap.containsKey(key)) {
         KmFunction kmFunction = kmFunctionMap.get(key);
-        if (isExtension(kmFunction)) {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.EXTENSION_FUNCTION,
-                  kmFunction.getFlags(),
-                  kmFunction.getValueParameters()));
-        } else {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.FUNCTION,
-                  kmFunction.getFlags(),
-                  kmFunction.getValueParameters()));
-        }
+        method.setKotlinMemberInfo(
+            createFunctionInfo(
+                isExtension(kmFunction) ? EXTENSION_FUNCTION : FUNCTION, kmFunction));
       } else if (kmPropertyGetterMap.containsKey(key)) {
         KmProperty kmProperty = kmPropertyGetterMap.get(key);
-        if (isExtension(kmProperty)) {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.EXTENSION_PROPERTY_GETTER,
-                  kmProperty.getGetterFlags(),
-                  kmProperty.getFlags(),
-                  kmProperty.getName()));
-        } else {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.PROPERTY_GETTER,
-                  kmProperty.getGetterFlags(),
-                  kmProperty.getFlags(),
-                  kmProperty.getName()));
-        }
+        method.setKotlinMemberInfo(
+            createPropertyInfo(
+                isExtension(kmProperty) ? EXTENSION_PROPERTY_GETTER : PROPERTY_GETTER, kmProperty));
       } else if (kmPropertySetterMap.containsKey(key)) {
         KmProperty kmProperty = kmPropertySetterMap.get(key);
-        if (isExtension(kmProperty)) {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.EXTENSION_PROPERTY_SETTER,
-                  kmProperty.getSetterFlags(),
-                  kmProperty.getFlags(),
-                  kmProperty.getName(),
-                  kmProperty.getSetterParameter()));
-        } else {
-          method.setKotlinMemberInfo(
-              new KotlinMemberInfo(
-                  MemberKind.PROPERTY_SETTER,
-                  kmProperty.getSetterFlags(),
-                  kmProperty.getFlags(),
-                  kmProperty.getName(),
-                  kmProperty.getSetterParameter()));
-        }
+        method.setKotlinMemberInfo(
+            createPropertyInfo(
+                isExtension(kmProperty) ? EXTENSION_PROPERTY_SETTER : PROPERTY_SETTER, kmProperty));
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
index 474c123..855a71f 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataJvmExtensionUtils.java
@@ -24,14 +24,12 @@
 import kotlinx.metadata.KmConstructorVisitor;
 import kotlinx.metadata.KmExtensionType;
 import kotlinx.metadata.KmFunction;
-import kotlinx.metadata.KmFunctionExtensionVisitor;
-import kotlinx.metadata.KmFunctionVisitor;
 import kotlinx.metadata.KmProperty;
 import kotlinx.metadata.KmPropertyExtensionVisitor;
 import kotlinx.metadata.KmPropertyVisitor;
 import kotlinx.metadata.jvm.JvmConstructorExtensionVisitor;
+import kotlinx.metadata.jvm.JvmExtensionsKt;
 import kotlinx.metadata.jvm.JvmFieldSignature;
-import kotlinx.metadata.jvm.JvmFunctionExtensionVisitor;
 import kotlinx.metadata.jvm.JvmMethodSignature;
 import kotlinx.metadata.jvm.JvmPropertyExtensionVisitor;
 
@@ -174,37 +172,25 @@
     }
   }
 
-  static class KmFunctionProcessor {
-    // Custom name via @JvmName("..."). Otherwise, null.
-    private JvmMethodSignature signature = null;
+  // Custom name via @JvmName("..."). Otherwise, null.
+  static JvmMethodSignature getJvmMethodSignature(KmConstructor kmConstructor, Reporter reporter) {
+    return remapJvmMethodSignature(JvmExtensionsKt.getSignature(kmConstructor), reporter);
+  }
 
-    KmFunctionProcessor(KmFunction kmFunction, Reporter reporter) {
-      kmFunction.accept(new KmFunctionVisitor() {
-        @Override
-        public KmFunctionExtensionVisitor visitExtensions(KmExtensionType type) {
-          if (type != JvmFunctionExtensionVisitor.TYPE) {
-            return null;
-          }
-          return new JvmFunctionExtensionVisitor() {
-            @Override
-            public void visit(JvmMethodSignature desc) {
-              assert signature == null : signature.asString();
-              signature = desc;
-            }
-          };
-        }
-      });
-      if (signature != null) {
-        String remappedDesc = remapKotlinTypeInDesc(signature.getDesc(), reporter);
-        if (remappedDesc != null && !remappedDesc.equals(signature.getDesc())) {
-          signature = new JvmMethodSignature(signature.getName(), remappedDesc);
-        }
+  // Custom name via @JvmName("..."). Otherwise, null.
+  static JvmMethodSignature getJvmMethodSignature(KmFunction kmFunction, Reporter reporter) {
+    return remapJvmMethodSignature(JvmExtensionsKt.getSignature(kmFunction), reporter);
+  }
+
+  private static JvmMethodSignature remapJvmMethodSignature(
+      JvmMethodSignature signature, Reporter reporter) {
+    if (signature != null) {
+      String remappedDesc = remapKotlinTypeInDesc(signature.getDesc(), reporter);
+      if (remappedDesc != null && !remappedDesc.equals(signature.getDesc())) {
+        signature = new JvmMethodSignature(signature.getName(), remappedDesc);
       }
     }
-
-    JvmMethodSignature signature() {
-      return signature;
-    }
+    return signature;
   }
 
   static class KmPropertyProcessor {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
index 43b5cf2..2be6e27 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
@@ -26,6 +26,7 @@
 import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.TypeSignature;
+import com.android.tools.r8.kotlin.KotlinMemberInfo.KotlinFunctionInfo;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.List;
@@ -283,13 +284,17 @@
       MethodTypeSignature signature,
       AppView<AppInfoWithLiveness> appView,
       NamingLens lens) {
+    KotlinFunctionInfo kotlinFunctionInfo = method.getKotlinMemberInfo().asFunctionInfo();
+    if (kotlinFunctionInfo == null) {
+      return false;
+    }
     boolean isExtension = method.isKotlinExtensionFunction();
     for (int i = isExtension ? 1 : 0; i < method.method.proto.parameters.values.length; i++) {
       DexType parameterType = method.method.proto.parameters.values[i];
       DebugLocalInfo debugLocalInfo = method.getParameterInfo().get(i);
       String parameterName = debugLocalInfo != null ? debugLocalInfo.name.toString() : ("p" + i);
       KotlinValueParameterInfo valueParameterInfo =
-          method.getKotlinMemberInfo().getValueParameterInfo(isExtension ? i - 1 : i);
+          kotlinFunctionInfo.getValueParameterInfo(isExtension ? i - 1 : i);
       TypeSignature parameterTypeSignature = signature.getParameterTypeSignature(i);
       KmValueParameter kmValueParameter =
           toRewrittenKmValueParameter(
@@ -611,8 +616,9 @@
             return null;
           }
         }
+        assert setter.getKotlinMemberInfo().isPropertyInfo();
         KotlinValueParameterInfo valueParameterInfo =
-            setter.getKotlinMemberInfo().getValueParameterInfo(valueIndex);
+            setter.getKotlinMemberInfo().asPropertyInfo().valueParameterInfo;
         KmValueParameter kmValueParameter = toRewrittenKmValueParameter(
             valueParameterInfo, valueType, valueSignature, "value", appView, lens);
         if (kmValueParameter != null) {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
index 3134b8a..fcf3db6 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinValueParameterInfo.java
@@ -32,6 +32,9 @@
   }
 
   static KotlinValueParameterInfo fromKmValueParameter(KmValueParameter kmValueParameter) {
+    if (kmValueParameter == null) {
+      return null;
+    }
     KmType kmType = kmValueParameter.getType();
     return new KotlinValueParameterInfo(
         kmValueParameter.getName(),