Introduce ReturnType to separate V from BaseTypeSignature.
Bug: 129925954
Change-Id: I4ec940b7292cc05a082f582844fa6becb9e94615
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignature.java b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
index 743f406..049cb7a 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -133,6 +133,8 @@
ClassSignature(
ClassTypeSignature superClassSignature,
List<ClassTypeSignature> superInterfaceSignatures) {
+ assert superClassSignature != null;
+ assert superInterfaceSignatures != null;
this.superClassSignature = superClassSignature;
this.superInterfaceSignatures = superInterfaceSignatures;
}
@@ -223,7 +225,7 @@
public static class ClassTypeSignature extends FieldTypeSignature {
static final ClassTypeSignature UNKNOWN_CLASS_TYPE_SIGNATURE =
- new ClassTypeSignature(null, ImmutableList.of());
+ new ClassTypeSignature(DexItemFactory.nullValueType, ImmutableList.of());
final DexType type;
// E.g., for Map<K, V>, a signature will indicate what types are for K and V.
@@ -237,6 +239,8 @@
ClassTypeSignature innerTypeSignature;
ClassTypeSignature(DexType type, List<FieldTypeSignature> typeArguments) {
+ assert type != null;
+ assert typeArguments != null;
this.type = type;
this.typeArguments = typeArguments;
}
@@ -295,6 +299,7 @@
final TypeSignature elementSignature;
ArrayTypeSignature(TypeSignature elementSignature) {
+ assert elementSignature != null;
this.elementSignature = elementSignature;
}
@@ -327,6 +332,7 @@
final String typeVariable;
TypeVariableSignature(String typeVariable) {
+ assert typeVariable != null;
this.typeVariable = typeVariable;
}
@@ -351,8 +357,8 @@
final DexType type;
BaseTypeSignature(DexType type) {
- assert type.isPrimitiveType() || type.isVoidType()
- : type.toDescriptorString();
+ assert type != null;
+ assert type.isPrimitiveType() : type.toDescriptorString();
this.type = type;
}
@@ -373,22 +379,41 @@
}
}
+ public static class ReturnType {
+ static final ReturnType VOID = new ReturnType(null);
+
+ // `null` indicates that it's `void`.
+ final TypeSignature typeSignature;
+
+ ReturnType(TypeSignature typeSignature) {
+ this.typeSignature = typeSignature;
+ }
+
+ public boolean isVoidDescriptor() {
+ return typeSignature == null;
+ }
+
+ public TypeSignature typeSignature() {
+ return typeSignature;
+ }
+ }
+
public static class MethodTypeSignature implements DexDefinitionSignature<DexEncodedMethod> {
static final MethodTypeSignature UNKNOWN_METHOD_TYPE_SIGNATURE =
- new MethodTypeSignature(
- ImmutableList.of(),
- ClassTypeSignature.UNKNOWN_CLASS_TYPE_SIGNATURE,
- ImmutableList.of());
+ new MethodTypeSignature(ImmutableList.of(), ReturnType.VOID, ImmutableList.of());
// TODO(b/129925954): encoding formal type parameters
final List<TypeSignature> typeSignatures;
- final TypeSignature returnType;
+ final ReturnType returnType;
final List<TypeSignature> throwsSignatures;
MethodTypeSignature(
List<TypeSignature> typeSignatures,
- TypeSignature returnType,
+ ReturnType returnType,
List<TypeSignature> throwsSignatures) {
+ assert typeSignatures != null;
+ assert returnType != null;
+ assert throwsSignatures != null;
this.typeSignatures = typeSignatures;
this.returnType = returnType;
this.throwsSignatures = throwsSignatures;
@@ -401,7 +426,7 @@
return typeSignatures.get(i);
}
- public TypeSignature returnType() {
+ public ReturnType returnType() {
return returnType;
}
@@ -848,7 +873,7 @@
expect(')');
- TypeSignature returnType = updateReturnType();
+ ReturnType returnType = updateReturnType();
ImmutableList.Builder<TypeSignature> throwsSignatureBuilder = ImmutableList.builder();
if (symbol == '^') {
@@ -868,13 +893,13 @@
parameterSignatureBuilder.build(), returnType, throwsSignatureBuilder.build());
}
- private TypeSignature updateReturnType() {
+ private ReturnType updateReturnType() {
// ReturnType ::= TypeSignature | "V".
if (symbol != 'V') {
- return updateTypeSignature(ParserPosition.MEMBER_ANNOTATION);
+ return new ReturnType(updateTypeSignature(ParserPosition.MEMBER_ANNOTATION));
} else {
scanSymbol();
- return new BaseTypeSignature(appView.dexItemFactory().voidType);
+ return ReturnType.VOID;
}
}
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 88a1d8c..ecef010 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataSynthesizer.java
@@ -250,23 +250,23 @@
DexProto proto = method.method.proto;
DexType returnType = proto.returnType;
- TypeSignature returnSignature = signature.returnType();
- KmType kmReturnType = toRenamedKmType(returnType, returnSignature, appView, lens);
+ TypeSignature returnSignature = signature.returnType().typeSignature();
+ KmType kmReturnType = setRenamedKmType(
+ returnType, returnSignature, appView, lens, kmFunction::setReturnType);
if (kmReturnType == null) {
return null;
}
- kmFunction.setReturnType(kmReturnType);
if (method.isKotlinExtensionFunction()) {
assert proto.parameters.values.length > 0
: method.method.toSourceString();
DexType receiverType = proto.parameters.values[0];
TypeSignature receiverSignature = signature.getParameterTypeSignature(0);
- KmType kmReceiverType = toRenamedKmType(receiverType, receiverSignature, appView, lens);
+ KmType kmReceiverType = setRenamedKmType(
+ receiverType, receiverSignature, appView, lens, kmFunction::setReceiverParameterType);
if (kmReceiverType == null) {
return null;
}
- kmFunction.setReceiverParameterType(kmReceiverType);
}
List<KmValueParameter> parameters = kmFunction.getValueParameters();
@@ -514,7 +514,7 @@
}
DexType returnType = getter.method.proto.returnType;
- TypeSignature returnSignature = signature.returnType();
+ TypeSignature returnSignature = signature.returnType().typeSignature();
if (kmPropertyType == null) {
// The property type is not set yet.
kmPropertyType = setRenamedKmType(
diff --git a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
index 3bf1f61..775f030 100644
--- a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -15,6 +16,7 @@
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignature.Parser;
+import com.android.tools.r8.graph.GenericSignature.ReturnType;
import com.android.tools.r8.graph.GenericSignature.TypeSignature;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import com.android.tools.r8.utils.AndroidApp;
@@ -57,6 +59,8 @@
ClassSubject cyy = inspector.clazz(CYY.class);
assertThat(cyy, isPresent());
+ DexEncodedMethod method;
+
ClassSignature classSignature;
ClassTypeSignature classTypeSignature;
FieldTypeSignature fieldTypeSignature;
@@ -65,6 +69,8 @@
FieldTypeSignature typeArgument;
TypeSignature parameterSignature;
TypeSignature elementSignature;
+ ReturnType returnType;
+ TypeSignature returnTypeSignature;
//
// Testing ClassSignature
@@ -110,17 +116,19 @@
// A$Y$YY newYY([B<T>)
MethodSubject newYY = zz.uniqueMethodWithName("newYY");
assertThat(newYY, isPresent());
- DexEncodedMethod method = newYY.getMethod();
+ method = newYY.getMethod();
assertNotNull(method);
methodTypeSignature = Parser.toMethodTypeSignature(method, appView);
assertNotNull(methodTypeSignature);
// return type: A$Y$YY
- TypeSignature returnType = methodTypeSignature.returnType();
- assertTrue(returnType.isFieldTypeSignature());
- assertTrue(returnType.asFieldTypeSignature().isClassTypeSignature());
- check_A_Y_YY(a, y, yy, returnType.asFieldTypeSignature().asClassTypeSignature());
+ returnType = methodTypeSignature.returnType();
+ assertFalse(returnType.isVoidDescriptor());
+ returnTypeSignature = returnType.typeSignature();
+ assertTrue(returnTypeSignature.isFieldTypeSignature());
+ assertTrue(returnTypeSignature.asFieldTypeSignature().isClassTypeSignature());
+ check_A_Y_YY(a, y, yy, returnTypeSignature.asFieldTypeSignature().asClassTypeSignature());
// type of 1st argument: [B<T>
assertEquals(1, methodTypeSignature.typeSignatures.size());
@@ -146,9 +154,11 @@
// return type: Function<A$Y$ZZ<TT>, A$Y$YY>
returnType = methodTypeSignature.returnType();
- assertTrue(returnType.isFieldTypeSignature());
- assertTrue(returnType.asFieldTypeSignature().isClassTypeSignature());
- classTypeSignature = returnType.asFieldTypeSignature().asClassTypeSignature();
+ assertFalse(returnType.isVoidDescriptor());
+ returnTypeSignature = returnType.typeSignature();
+ assertTrue(returnTypeSignature.isFieldTypeSignature());
+ assertTrue(returnTypeSignature.asFieldTypeSignature().isClassTypeSignature());
+ classTypeSignature = returnTypeSignature.asFieldTypeSignature().asClassTypeSignature();
DexType functionType =
factory.createType(DescriptorUtils.javaTypeToDescriptor(Function.class.getTypeName()));
assertEquals(functionType, classTypeSignature.type);
@@ -167,18 +177,24 @@
// type of 1st argument: Supplier<A$Y$ZZ<TT>>
assertEquals(1, methodTypeSignature.typeSignatures.size());
parameterSignature = methodTypeSignature.getParameterTypeSignature(0);
- assertNotNull(parameterSignature);
- assertTrue(parameterSignature.isFieldTypeSignature());
- assertTrue(parameterSignature.asFieldTypeSignature().isClassTypeSignature());
- classTypeSignature = parameterSignature.asFieldTypeSignature().asClassTypeSignature();
- DexType supplierType =
- factory.createType(DescriptorUtils.javaTypeToDescriptor(Supplier.class.getTypeName()));
- assertEquals(supplierType, classTypeSignature.type);
- typeArguments = classTypeSignature.typeArguments;
- assertEquals(1, typeArguments.size());
- typeArgument = typeArguments.get(0);
- assertTrue(typeArgument.isClassTypeSignature());
- check_A_Y_ZZ(a, y, zz, typeArgument.asClassTypeSignature());
+ check_supplier(factory, a, y, zz, parameterSignature);
+
+ // void boo(Supplier<A$Y$ZZ<TT>>)
+ MethodSubject boo = zz.uniqueMethodWithName("boo");
+ assertThat(boo, isPresent());
+ method = boo.getMethod();
+ assertNotNull(method);
+
+ // return type: void
+ methodTypeSignature = Parser.toMethodTypeSignature(method, appView);
+ assertNotNull(methodTypeSignature);
+ returnType = methodTypeSignature.returnType();
+ assertTrue(returnType.isVoidDescriptor());
+
+ // type of 1st argument: Supplier<A$Y$ZZ<TT>>
+ assertEquals(1, methodTypeSignature.typeSignatures.size());
+ parameterSignature = methodTypeSignature.getParameterTypeSignature(0);
+ check_supplier(factory, a, y, zz, parameterSignature);
}
private void check_A_Y(ClassSubject a, ClassSubject y, ClassTypeSignature signature) {
@@ -208,6 +224,26 @@
assertTrue(typeArgument.isTypeVariableSignature());
assertEquals("TT", typeArgument.asTypeVariableSignature().typeVariable);
}
+
+ private void check_supplier(
+ DexItemFactory factory,
+ ClassSubject a,
+ ClassSubject y,
+ ClassSubject zz,
+ TypeSignature signature) {
+ assertNotNull(signature);
+ assertTrue(signature.isFieldTypeSignature());
+ assertTrue(signature.asFieldTypeSignature().isClassTypeSignature());
+ ClassTypeSignature classTypeSignature = signature.asFieldTypeSignature().asClassTypeSignature();
+ DexType supplierType =
+ factory.createType(DescriptorUtils.javaTypeToDescriptor(Supplier.class.getTypeName()));
+ assertEquals(supplierType, classTypeSignature.type);
+ List<FieldTypeSignature> typeArguments = classTypeSignature.typeArguments;
+ assertEquals(1, typeArguments.size());
+ FieldTypeSignature typeArgument = typeArguments.get(0);
+ assertTrue(typeArgument.isClassTypeSignature());
+ check_A_Y_ZZ(a, y, zz, typeArgument.asClassTypeSignature());
+ }
}
//
@@ -237,6 +273,10 @@
}
};
}
+
+ void boo(Supplier<ZZ<TT>> zzSupplier) {
+ convertToYY(zzSupplier).apply(this);
+ }
}
ZZ<T> zz() {