Model KmVersionRequirements in kotlin metadata
Bug: 157982139
Bug: 157977713
Change-Id: Idb01871157cab3152f06665756fc7f508c0ad179
diff --git a/src/main/java/com/android/tools/r8/kotlin/KmVisitorProviders.java b/src/main/java/com/android/tools/r8/kotlin/KmVisitorProviders.java
index 84d6e82..7431fb9 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KmVisitorProviders.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KmVisitorProviders.java
@@ -13,6 +13,7 @@
import kotlinx.metadata.KmTypeVisitor;
import kotlinx.metadata.KmValueParameterVisitor;
import kotlinx.metadata.KmVariance;
+import kotlinx.metadata.KmVersionRequirementVisitor;
/**
* The reason for having these visitor providers is to make the separation of concern a bit easier
@@ -101,4 +102,10 @@
KmTypeVisitor get(int flags, String typeFlexibilityId);
}
+
+ @FunctionalInterface
+ public interface KmVersionRequirementVisitorProvider {
+
+ KmVersionRequirementVisitor get();
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
index b0b381e..9987457 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassInfo.java
@@ -45,6 +45,7 @@
private final List<KotlinTypeReference> nestedClasses;
// TODO(b/154347404): Understand enum entries.
private final List<String> enumEntries;
+ private final KotlinVersionRequirementInfo versionRequirements;
private final KotlinTypeReference anonymousObjectOrigin;
private final String packageName;
@@ -59,6 +60,7 @@
List<KotlinTypeReference> sealedSubClasses,
List<KotlinTypeReference> nestedClasses,
List<String> enumEntries,
+ KotlinVersionRequirementInfo versionRequirements,
KotlinTypeReference anonymousObjectOrigin,
String packageName) {
this.flags = flags;
@@ -71,6 +73,7 @@
this.sealedSubClasses = sealedSubClasses;
this.nestedClasses = nestedClasses;
this.enumEntries = enumEntries;
+ this.versionRequirements = versionRequirements;
this.anonymousObjectOrigin = anonymousObjectOrigin;
this.packageName = packageName;
}
@@ -120,6 +123,7 @@
getSealedSubClasses(kmClass.getSealedSubclasses(), factory),
getNestedClasses(hostClass, kmClass.getNestedClasses(), factory),
kmClass.getEnumEntries(),
+ KotlinVersionRequirementInfo.create(kmClass.getVersionRequirements()),
getAnonymousObjectOrigin(kmClass, factory),
packageName);
}
@@ -261,7 +265,7 @@
}
// TODO(b/154347404): Understand enum entries.
kmClass.getEnumEntries().addAll(enumEntries);
-
+ versionRequirements.rewrite(kmClass::visitVersionRequirement);
JvmExtensionsKt.setModuleName(kmClass, moduleName);
if (anonymousObjectOrigin != null) {
String renamedAnon =
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
index 857ef39..c28b4a7 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinConstructorInfo.java
@@ -24,16 +24,20 @@
// Information from original KmValueParameter(s) if available.
private final int flags;
// Information about the value parameters.
- private final List<KotlinValueParameterInfo> valueParameterInfos;
+ private final List<KotlinValueParameterInfo> valueParameters;
+ // Information about version requirements.
+ private final KotlinVersionRequirementInfo versionRequirements;
// Information about the signature.
private final KotlinJvmMethodSignatureInfo signature;
private KotlinConstructorInfo(
int flags,
- List<KotlinValueParameterInfo> valueParameterInfos,
+ List<KotlinValueParameterInfo> valueParameters,
+ KotlinVersionRequirementInfo versionRequirements,
KotlinJvmMethodSignatureInfo signature) {
this.flags = flags;
- this.valueParameterInfos = valueParameterInfos;
+ this.valueParameters = valueParameters;
+ this.versionRequirements = versionRequirements;
this.signature = signature;
}
@@ -42,6 +46,7 @@
return new KotlinConstructorInfo(
kmConstructor.getFlags(),
KotlinValueParameterInfo.create(kmConstructor.getValueParameters(), factory, reporter),
+ KotlinVersionRequirementInfo.create(kmConstructor.getVersionRequirements()),
KotlinJvmMethodSignatureInfo.create(JvmExtensionsKt.getSignature(kmConstructor), factory));
}
@@ -57,9 +62,10 @@
if (signature != null) {
JvmExtensionsKt.setSignature(kmConstructor, signature.rewrite(method, appView, namingLens));
}
- for (KotlinValueParameterInfo valueParameterInfo : valueParameterInfos) {
+ for (KotlinValueParameterInfo valueParameterInfo : valueParameters) {
valueParameterInfo.rewrite(kmConstructor::visitValueParameter, appView, namingLens);
}
+ versionRequirements.rewrite(kmConstructor::visitVersionRequirement);
kmClass.getConstructors().add(kmConstructor);
}
@@ -75,7 +81,7 @@
@Override
public void trace(DexDefinitionSupplier definitionSupplier) {
- forEachApply(valueParameterInfos, param -> param::trace, definitionSupplier);
+ forEachApply(valueParameters, param -> param::trace, definitionSupplier);
if (signature != null) {
signature.trace(definitionSupplier);
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
index c5be533..d71d574 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinFunctionInfo.java
@@ -37,6 +37,8 @@
private final KotlinJvmMethodSignatureInfo signature;
// Information about the lambdaClassOrigin.
private final KotlinTypeReference lambdaClassOrigin;
+ // Information about version requirements.
+ private final KotlinVersionRequirementInfo versionRequirements;
// A value describing if any of the parameters are crossinline.
private final boolean crossInlineParameter;
@@ -49,6 +51,7 @@
List<KotlinTypeParameterInfo> typeParameters,
KotlinJvmMethodSignatureInfo signature,
KotlinTypeReference lambdaClassOrigin,
+ KotlinVersionRequirementInfo versionRequirements,
boolean crossInlineParameter) {
this.flags = flags;
this.name = name;
@@ -58,6 +61,7 @@
this.typeParameters = typeParameters;
this.signature = signature;
this.lambdaClassOrigin = lambdaClassOrigin;
+ this.versionRequirements = versionRequirements;
this.crossInlineParameter = crossInlineParameter;
}
@@ -85,6 +89,7 @@
KotlinTypeParameterInfo.create(kmFunction.getTypeParameters(), factory, reporter),
KotlinJvmMethodSignatureInfo.create(JvmExtensionsKt.getSignature(kmFunction), factory),
getlambdaClassOrigin(kmFunction, factory),
+ KotlinVersionRequirementInfo.create(kmFunction.getVersionRequirements()),
isCrossInline);
}
@@ -123,6 +128,7 @@
if (receiverParameterType != null) {
receiverParameterType.rewrite(kmFunction::visitReceiverParameterType, appView, namingLens);
}
+ versionRequirements.rewrite(kmFunction::visitVersionRequirement);
JvmFunctionExtensionVisitor extensionVisitor =
(JvmFunctionExtensionVisitor) kmFunction.visitExtensions(JvmFunctionExtensionVisitor.TYPE);
if (signature != null && extensionVisitor != null) {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
index fa21f81..bc124c6 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataWriter.java
@@ -33,6 +33,7 @@
import kotlinx.metadata.KmTypeParameter;
import kotlinx.metadata.KmTypeProjection;
import kotlinx.metadata.KmValueParameter;
+import kotlinx.metadata.KmVersionRequirement;
import kotlinx.metadata.jvm.JvmExtensionsKt;
import kotlinx.metadata.jvm.JvmFieldSignature;
import kotlinx.metadata.jvm.JvmMethodSignature;
@@ -351,6 +352,7 @@
appendKmProperty(nextNextIndent, sb, kmProperty);
});
});
+ appendKmVersionRequirement(indent, sb, kmClass.getVersionRequirements());
appendKeyValue(
indent,
"constructors",
@@ -389,6 +391,7 @@
JvmMethodSignature signature = JvmExtensionsKt.getSignature(constructor);
appendKeyValue(
newIndent, "signature", sb, signature != null ? signature.asString() : "null");
+ appendKmVersionRequirement(newIndent, sb, constructor.getVersionRequirements());
});
}
@@ -420,6 +423,7 @@
"valueParameters",
sb,
nextIndent -> appendValueParameters(nextIndent, sb, function.getValueParameters()));
+ appendKmVersionRequirement(newIndent, sb, function.getVersionRequirements());
JvmMethodSignature signature = JvmExtensionsKt.getSignature(function);
appendKeyValue(
newIndent, "signature", sb, signature != null ? signature.asString() : "null");
@@ -461,6 +465,7 @@
"setterParameter",
sb,
nextIndent -> appendValueParameter(nextIndent, sb, kmProperty.getSetterParameter()));
+ appendKmVersionRequirement(newIndent, sb, kmProperty.getVersionRequirements());
appendKeyValue(newIndent, "jvmFlags", sb, JvmExtensionsKt.getJvmFlags(kmProperty) + "");
JvmFieldSignature fieldSignature = JvmExtensionsKt.getFieldSignature(kmProperty);
appendKeyValue(
@@ -730,6 +735,7 @@
nextIndent -> {
appendKmType(nextIndent, sb, kmTypeAlias.underlyingType);
});
+ appendKmVersionRequirement(newIndent, sb, kmTypeAlias.getVersionRequirements());
});
}
@@ -753,4 +759,44 @@
});
});
}
+
+ private static void appendKmVersionRequirement(
+ String indent, StringBuilder sb, List<KmVersionRequirement> kmVersionRequirements) {
+ appendKeyValue(
+ indent,
+ "versionRequirements",
+ sb,
+ newIndent -> {
+ appendKmList(
+ newIndent,
+ "KmVersionRequirement",
+ sb,
+ kmVersionRequirements,
+ (nextIndent, kmVersionRequirement) -> {
+ appendKmSection(
+ nextIndent,
+ "KmVersionRequirement",
+ sb,
+ nextNextIndent -> {
+ appendKeyValue(nextNextIndent, "kind", sb, kmVersionRequirement.kind.name());
+ appendKeyValue(
+ nextNextIndent, "level", sb, kmVersionRequirement.level.name());
+ appendKeyValue(
+ nextNextIndent,
+ "errorCode",
+ sb,
+ kmVersionRequirement.getErrorCode() == null
+ ? "null"
+ : kmVersionRequirement.getErrorCode().toString());
+ appendKeyValue(
+ nextNextIndent, "message", sb, kmVersionRequirement.getMessage());
+ appendKeyValue(
+ nextNextIndent,
+ "version",
+ sb,
+ kmVersionRequirement.getVersion().toString());
+ });
+ });
+ });
+ }
}
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
index 94afee8..4d14c67 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinPropertyInfo.java
@@ -44,6 +44,8 @@
private final List<KotlinTypeParameterInfo> typeParameters;
+ private final KotlinVersionRequirementInfo versionRequirements;
+
private final int jvmFlags;
private final KotlinJvmFieldSignatureInfo fieldSignature;
@@ -63,6 +65,7 @@
KotlinTypeInfo receiverParameterType,
KotlinValueParameterInfo setterParameter,
List<KotlinTypeParameterInfo> typeParameters,
+ KotlinVersionRequirementInfo versionRequirements,
int jvmFlags,
KotlinJvmFieldSignatureInfo fieldSignature,
KotlinJvmMethodSignatureInfo getterSignature,
@@ -76,6 +79,7 @@
this.receiverParameterType = receiverParameterType;
this.setterParameter = setterParameter;
this.typeParameters = typeParameters;
+ this.versionRequirements = versionRequirements;
this.jvmFlags = jvmFlags;
this.fieldSignature = fieldSignature;
this.getterSignature = getterSignature;
@@ -94,6 +98,7 @@
KotlinTypeInfo.create(kmProperty.getReceiverParameterType(), factory, reporter),
KotlinValueParameterInfo.create(kmProperty.getSetterParameter(), factory, reporter),
KotlinTypeParameterInfo.create(kmProperty.getTypeParameters(), factory, reporter),
+ KotlinVersionRequirementInfo.create(kmProperty.getVersionRequirements()),
JvmExtensionsKt.getJvmFlags(kmProperty),
KotlinJvmFieldSignatureInfo.create(JvmExtensionsKt.getFieldSignature(kmProperty), factory),
KotlinJvmMethodSignatureInfo.create(
@@ -146,6 +151,7 @@
for (KotlinTypeParameterInfo typeParameter : typeParameters) {
typeParameter.rewrite(kmProperty::visitTypeParameter, appView, namingLens);
}
+ versionRequirements.rewrite(kmProperty::visitVersionRequirement);
JvmPropertyExtensionVisitor extensionVisitor =
(JvmPropertyExtensionVisitor) kmProperty.visitExtensions(JvmPropertyExtensionVisitor.TYPE);
if (extensionVisitor != null) {
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
index 3872963..bb75b7f 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinTypeAliasInfo.java
@@ -26,6 +26,7 @@
private final KotlinTypeInfo expandedType;
private final List<KotlinTypeParameterInfo> typeParameters;
private final List<KotlinAnnotationInfo> annotations;
+ private final KotlinVersionRequirementInfo versionRequirements;
private KotlinTypeAliasInfo(
int flags,
@@ -33,7 +34,8 @@
KotlinTypeInfo underlyingType,
KotlinTypeInfo expandedType,
List<KotlinTypeParameterInfo> typeParameters,
- List<KotlinAnnotationInfo> annotations) {
+ List<KotlinAnnotationInfo> annotations,
+ KotlinVersionRequirementInfo versionRequirements) {
this.flags = flags;
this.name = name;
assert underlyingType != null;
@@ -42,6 +44,7 @@
this.expandedType = expandedType;
this.typeParameters = typeParameters;
this.annotations = annotations;
+ this.versionRequirements = versionRequirements;
}
public static KotlinTypeAliasInfo create(
@@ -52,7 +55,8 @@
KotlinTypeInfo.create(alias.underlyingType, factory, reporter),
KotlinTypeInfo.create(alias.expandedType, factory, reporter),
KotlinTypeParameterInfo.create(alias.getTypeParameters(), factory, reporter),
- KotlinAnnotationInfo.create(alias.getAnnotations(), factory));
+ KotlinAnnotationInfo.create(alias.getAnnotations(), factory),
+ KotlinVersionRequirementInfo.create(alias.getVersionRequirements()));
}
void rewrite(
@@ -68,6 +72,7 @@
for (KotlinAnnotationInfo annotation : annotations) {
annotation.rewrite(kmTypeAliasVisitor::visitAnnotation, appView, namingLens);
}
+ versionRequirements.rewrite(kmTypeAliasVisitor::visitVersionRequirement);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinVersionRequirementInfo.java b/src/main/java/com/android/tools/r8/kotlin/KotlinVersionRequirementInfo.java
new file mode 100644
index 0000000..9530f4c
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinVersionRequirementInfo.java
@@ -0,0 +1,82 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.kotlin;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import kotlinx.metadata.KmVersion;
+import kotlinx.metadata.KmVersionRequirement;
+import kotlinx.metadata.KmVersionRequirementLevel;
+import kotlinx.metadata.KmVersionRequirementVersionKind;
+import kotlinx.metadata.KmVersionRequirementVisitor;
+
+class KotlinVersionRequirementInfo {
+
+ private static final KotlinVersionRequirementInfo NO_VERSION_REQUIREMENTS =
+ new KotlinVersionRequirementInfo(ImmutableList.of());
+
+ private final List<KotlinVersionRequirementPoint> versionRequirements;
+
+ private KotlinVersionRequirementInfo(List<KotlinVersionRequirementPoint> versionRequirements) {
+ this.versionRequirements = versionRequirements;
+ }
+
+ static KotlinVersionRequirementInfo create(List<KmVersionRequirement> kmVersionRequirements) {
+ if (kmVersionRequirements.isEmpty()) {
+ return NO_VERSION_REQUIREMENTS;
+ }
+ ImmutableList.Builder<KotlinVersionRequirementPoint> builder = ImmutableList.builder();
+ for (KmVersionRequirement kmVersionRequirement : kmVersionRequirements) {
+ builder.add(KotlinVersionRequirementPoint.create(kmVersionRequirement));
+ }
+ return new KotlinVersionRequirementInfo(builder.build());
+ }
+
+ public void rewrite(KmVisitorProviders.KmVersionRequirementVisitorProvider visitorProvider) {
+ if (this == NO_VERSION_REQUIREMENTS) {
+ return;
+ }
+ for (KotlinVersionRequirementPoint versionRequirement : versionRequirements) {
+ versionRequirement.rewrite(visitorProvider.get());
+ }
+ }
+
+ private static class KotlinVersionRequirementPoint {
+
+ private final Integer errorCode;
+ private final KmVersionRequirementVersionKind kind;
+ private final KmVersionRequirementLevel level;
+ private final String message;
+ private final KmVersion version;
+
+ private KotlinVersionRequirementPoint(
+ KmVersionRequirementVersionKind kind,
+ KmVersionRequirementLevel level,
+ Integer errorCode,
+ String message,
+ KmVersion version) {
+ this.errorCode = errorCode;
+ this.kind = kind;
+ this.level = level;
+ this.message = message;
+ this.version = version;
+ }
+
+ private static KotlinVersionRequirementPoint create(KmVersionRequirement kmVersionRequirement) {
+ return new KotlinVersionRequirementPoint(
+ kmVersionRequirement.kind,
+ kmVersionRequirement.level,
+ kmVersionRequirement.getErrorCode(),
+ kmVersionRequirement.getMessage(),
+ kmVersionRequirement.version);
+ }
+
+ private void rewrite(KmVersionRequirementVisitor visitor) {
+ visitor.visit(kind, level, errorCode, message);
+ visitor.visitVersion(version.getMajor(), version.getMinor(), version.getPatch());
+ visitor.visitEnd();
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
index 8202a9c..6df1462 100644
--- a/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
+++ b/src/test/java/com/android/tools/r8/kotlin/coroutines/KotlinxCoroutinesTestRunner.java
@@ -83,9 +83,8 @@
.compile()
.inspect(inspector -> assertEqualMetadata(new CodeInspector(BASE_LIBRARY), inspector))
.writeToZip();
- compileTestSources(baseJar);
- // TODO(b/157977713): We should be able to run tests.
- // runTestsInJar(testJar, baseJar);
+ Path testJar = compileTestSources(baseJar);
+ runTestsInJar(testJar, baseJar);
}
private Path compileTestSources(Path baseJar) throws Exception {