Change GenericSignatureVisitor to emit return types
This will allow one to more easily rewrite signatures.
Bug: 184927364
Bug: 129925954
Change-Id: I5a3db1d3f4b60422959f2d477faf463375351dd2
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 2fa08c8..bf7c42b 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -167,14 +167,15 @@
return interfaceBounds;
}
- public void visit(GenericSignatureVisitor visitor) {
- visitor.visitClassBound(classBound);
- if (interfaceBounds == null) {
- return;
+ public FormalTypeParameter visit(GenericSignatureVisitor visitor) {
+ FieldTypeSignature rewrittenClassBound =
+ classBound == null ? null : visitor.visitClassBound(classBound);
+ List<FieldTypeSignature> rewrittenInterfaceBounds =
+ visitor.visitInterfaceBounds(interfaceBounds);
+ if (classBound == rewrittenClassBound && interfaceBounds == rewrittenInterfaceBounds) {
+ return this;
}
- for (FieldTypeSignature interfaceBound : interfaceBounds) {
- visitor.visitInterfaceBound(interfaceBound);
- }
+ return new FormalTypeParameter(name, rewrittenClassBound, rewrittenInterfaceBounds);
}
}
@@ -232,12 +233,18 @@
return formalTypeParameters;
}
- public void visit(GenericSignatureVisitor visitor) {
- visitor.visitFormalTypeParameters(formalTypeParameters);
- visitor.visitSuperClass(superClassSignature);
- for (ClassTypeSignature superInterface : superInterfaceSignatures) {
- visitor.visitSuperInterface(superInterface);
+ public ClassSignature visit(GenericSignatureVisitor visitor) {
+ List<FormalTypeParameter> rewrittenParameters =
+ visitor.visitFormalTypeParameters(formalTypeParameters);
+ ClassTypeSignature rewrittenSuperClass = visitor.visitSuperClass(superClassSignature);
+ List<ClassTypeSignature> rewrittenInterfaces =
+ visitor.visitSuperInterfaces(superInterfaceSignatures);
+ if (formalTypeParameters == rewrittenParameters
+ && superClassSignature == rewrittenSuperClass
+ && superInterfaceSignatures == rewrittenInterfaces) {
+ return this;
}
+ return new ClassSignature(rewrittenParameters, rewrittenSuperClass, rewrittenInterfaces);
}
public String toRenamedString(NamingLens namingLens, Predicate<DexType> isTypeMissing) {
@@ -286,8 +293,9 @@
}
@Override
- public void visit(GenericSignatureVisitor visitor) {
+ public ClassSignature visit(GenericSignatureVisitor visitor) {
assert false : "Should not visit an invalid signature";
+ return this;
}
@Override
@@ -447,7 +455,8 @@
static final class StarFieldTypeSignature extends FieldTypeSignature {
- static final StarFieldTypeSignature STAR_FIELD_TYPE_SIGNATURE = new StarFieldTypeSignature();
+ private static final StarFieldTypeSignature STAR_FIELD_TYPE_SIGNATURE =
+ new StarFieldTypeSignature();
private StarFieldTypeSignature() {
super(WildcardIndicator.NONE);
@@ -462,6 +471,10 @@
public boolean isStar() {
return true;
}
+
+ public static StarFieldTypeSignature getStarFieldTypeSignature() {
+ return STAR_FIELD_TYPE_SIGNATURE;
+ }
}
private static final ClassTypeSignature NO_FIELD_TYPE_SIGNATURE =
@@ -475,26 +488,34 @@
// Note that this could be nested, e.g., Map<K, Consumer<V>>.
final List<FieldTypeSignature> typeArguments;
- // TODO(b/129925954): towards immutable structure?
- // Double-linked enclosing-inner relations.
- ClassTypeSignature enclosingTypeSignature;
- ClassTypeSignature innerTypeSignature;
+ final ClassTypeSignature enclosingTypeSignature;
public ClassTypeSignature(DexType type) {
- this(type, EMPTY_TYPE_ARGUMENTS);
+ this(type, EMPTY_TYPE_ARGUMENTS, null);
}
public ClassTypeSignature(DexType type, List<FieldTypeSignature> typeArguments) {
- this(type, typeArguments, WildcardIndicator.NOT_AN_ARGUMENT);
+ this(type, typeArguments, null, WildcardIndicator.NOT_AN_ARGUMENT);
+ }
+
+ public ClassTypeSignature(
+ DexType type,
+ List<FieldTypeSignature> typeArguments,
+ ClassTypeSignature enclosingTypeSignature) {
+ this(type, typeArguments, enclosingTypeSignature, WildcardIndicator.NOT_AN_ARGUMENT);
}
private ClassTypeSignature(
- DexType type, List<FieldTypeSignature> typeArguments, WildcardIndicator indicator) {
+ DexType type,
+ List<FieldTypeSignature> typeArguments,
+ ClassTypeSignature enclosingTypeSignature,
+ WildcardIndicator indicator) {
super(indicator);
assert type != null;
assert typeArguments != null;
this.type = type;
this.typeArguments = typeArguments;
+ this.enclosingTypeSignature = enclosingTypeSignature;
assert typeArguments.stream().allMatch(FieldTypeSignature::isArgument);
}
@@ -519,10 +540,7 @@
@Override
public ClassTypeSignature asArgument(WildcardIndicator indicator) {
assert indicator != WildcardIndicator.NOT_AN_ARGUMENT;
- ClassTypeSignature argument = new ClassTypeSignature(type, typeArguments, indicator);
- argument.innerTypeSignature = this.innerTypeSignature;
- argument.enclosingTypeSignature = this.enclosingTypeSignature;
- return argument;
+ return new ClassTypeSignature(type, typeArguments, enclosingTypeSignature, indicator);
}
@Override
@@ -530,17 +548,23 @@
return new ArrayTypeSignature(this);
}
- static void link(ClassTypeSignature outer, ClassTypeSignature inner) {
- assert outer.innerTypeSignature == null && inner.enclosingTypeSignature == null;
- outer.innerTypeSignature = inner;
- inner.enclosingTypeSignature = outer;
- }
-
- public void visit(GenericSignatureVisitor visitor) {
- visitor.visitTypeArguments(typeArguments);
- if (innerTypeSignature != null) {
- visitor.visitSimpleClass(innerTypeSignature);
+ public ClassTypeSignature visit(GenericSignatureVisitor visitor) {
+ DexType visitedType = visitor.visitType(type);
+ if (visitedType == null) {
+ return null;
}
+ List<FieldTypeSignature> rewrittenArguments = visitor.visitTypeArguments(typeArguments);
+ ClassTypeSignature rewrittenOuter = null;
+ if (enclosingTypeSignature != null) {
+ rewrittenOuter = visitor.visitSimpleClass(enclosingTypeSignature);
+ }
+ if (type == visitedType
+ && typeArguments == rewrittenArguments
+ && enclosingTypeSignature == rewrittenOuter) {
+ return this;
+ }
+ return new ClassTypeSignature(
+ visitedType, rewrittenArguments, rewrittenOuter, getWildcardIndicator());
}
public boolean hasTypeVariableArguments() {
@@ -592,8 +616,15 @@
return new ArrayTypeSignature(this);
}
- public void visit(GenericSignatureVisitor visitor) {
- visitor.visitTypeSignature(elementSignature);
+ public ArrayTypeSignature visit(GenericSignatureVisitor visitor) {
+ TypeSignature rewrittenElementSignature = visitor.visitTypeSignature(elementSignature);
+ if (rewrittenElementSignature == null) {
+ return null;
+ }
+ if (elementSignature == rewrittenElementSignature) {
+ return this;
+ }
+ return new ArrayTypeSignature(elementSignature, getWildcardIndicator());
}
}
@@ -743,11 +774,20 @@
return this;
}
- public void visit(GenericSignatureVisitor visitor) {
- visitor.visitFormalTypeParameters(formalTypeParameters);
- visitor.visitMethodTypeSignatures(typeSignatures);
- visitor.visitReturnType(returnType);
- visitor.visitThrowsSignatures(throwsSignatures);
+ public MethodTypeSignature visit(GenericSignatureVisitor visitor) {
+ List<FormalTypeParameter> rewrittenParameters =
+ visitor.visitFormalTypeParameters(formalTypeParameters);
+ List<TypeSignature> rewrittenSignatures = visitor.visitMethodTypeSignatures(typeSignatures);
+ ReturnType rewrittenReturnType = visitor.visitReturnType(returnType);
+ List<TypeSignature> rewrittenThrows = visitor.visitThrowsSignatures(throwsSignatures);
+ if (formalTypeParameters == rewrittenParameters
+ && typeSignatures == rewrittenSignatures
+ && returnType == rewrittenReturnType
+ && throwsSignatures == rewrittenThrows) {
+ return this;
+ }
+ return new MethodTypeSignature(
+ rewrittenParameters, rewrittenSignatures, rewrittenReturnType, rewrittenThrows);
}
public List<FormalTypeParameter> getFormalTypeParameters() {
@@ -800,8 +840,9 @@
}
@Override
- public void visit(GenericSignatureVisitor visitor) {
+ public MethodTypeSignature visit(GenericSignatureVisitor visitor) {
assert false : "Should not visit an invalid signature";
+ return this;
}
@Override
@@ -1072,12 +1113,11 @@
DexType parsedEnclosingType = parsedTypeName(qualIdent.toString());
List<FieldTypeSignature> typeArguments = updateOptTypeArguments();
- ClassTypeSignature outerMostTypeSignature =
+
+ ClassTypeSignature outerTypeSignature =
new ClassTypeSignature(
parsedEnclosingType, typeArguments.isEmpty() ? EMPTY_TYPE_ARGUMENTS : typeArguments);
-
- ClassTypeSignature outerTypeSignature = outerMostTypeSignature;
- ClassTypeSignature innerTypeSignature;
+ ClassTypeSignature innerTypeSignature = null;
while (symbol == '.') {
// Deal with Member Classes.
scanSymbol();
@@ -1088,13 +1128,13 @@
innerTypeSignature =
new ClassTypeSignature(
parsedEnclosingType,
- typeArguments.isEmpty() ? EMPTY_TYPE_ARGUMENTS : typeArguments);
- ClassTypeSignature.link(outerTypeSignature, innerTypeSignature);
+ typeArguments.isEmpty() ? EMPTY_TYPE_ARGUMENTS : typeArguments,
+ outerTypeSignature);
outerTypeSignature = innerTypeSignature;
}
expect(';');
- return outerMostTypeSignature;
+ return innerTypeSignature != null ? innerTypeSignature : outerTypeSignature;
}
private List<FieldTypeSignature> updateOptTypeArguments() {
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureEnqueuerAnalysis.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureEnqueuerAnalysis.java
index a7e9927..ea66ba7 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureEnqueuerAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureEnqueuerAnalysis.java
@@ -54,105 +54,136 @@
}
@Override
- public void visitClassSignature(ClassSignature classSignature) {
+ public ClassSignature visitClassSignature(ClassSignature classSignature) {
if (classSignature.hasNoSignature()) {
- return;
+ return classSignature;
}
- classSignature.visit(this);
+ return classSignature.visit(this);
}
@Override
- public void visitMethodSignature(MethodTypeSignature methodSignature) {
+ public MethodTypeSignature visitMethodSignature(MethodTypeSignature methodSignature) {
if (methodSignature.hasNoSignature()) {
- return;
+ return methodSignature;
}
- methodSignature.visit(this);
+ return methodSignature.visit(this);
}
@Override
- public void visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
+ public FieldTypeSignature visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
if (fieldSignature.hasNoSignature()) {
- return;
+ return fieldSignature;
}
if (fieldSignature.isStar()) {
- return;
+ return fieldSignature;
}
if (fieldSignature.isTypeVariableSignature()) {
- return;
+ return fieldSignature;
}
if (fieldSignature.isArrayTypeSignature()) {
fieldSignature.asArrayTypeSignature().visit(this);
- return;
+ return fieldSignature;
}
assert fieldSignature.isClassTypeSignature();
- visitClassTypeSignature(fieldSignature.asClassTypeSignature());
- }
-
- private void visitClassTypeSignature(ClassTypeSignature classTypeSignature) {
- enqueuerDefinitionSupplier.definitionFor(classTypeSignature.type, context);
- classTypeSignature.visit(this);
+ return fieldSignature.asClassTypeSignature().visit(this);
}
@Override
- public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
+ public List<FormalTypeParameter> visitFormalTypeParameters(
+ List<FormalTypeParameter> formalTypeParameters) {
formalTypeParameters.forEach(formalTypeParameter -> formalTypeParameter.visit(this));
+ return formalTypeParameters;
}
@Override
- public void visitClassBound(FieldTypeSignature fieldSignature) {
- visitFieldTypeSignature(fieldSignature);
+ public FieldTypeSignature visitClassBound(FieldTypeSignature fieldSignature) {
+ return visitFieldTypeSignature(fieldSignature);
}
@Override
- public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
- visitFieldTypeSignature(fieldSignature);
+ public List<FieldTypeSignature> visitInterfaceBounds(List<FieldTypeSignature> fieldSignatures) {
+ if (fieldSignatures == null) {
+ return null;
+ }
+ fieldSignatures.forEach(this::visitInterfaceBound);
+ return fieldSignatures;
}
@Override
- public void visitSuperClass(ClassTypeSignature classTypeSignature) {
- visitClassTypeSignature(classTypeSignature);
+ public FieldTypeSignature visitInterfaceBound(FieldTypeSignature fieldSignature) {
+ return visitFieldTypeSignature(fieldSignature);
}
@Override
- public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
- visitClassTypeSignature(classTypeSignature);
+ public ClassTypeSignature visitSuperClass(ClassTypeSignature classTypeSignature) {
+ return classTypeSignature.visit(this);
}
@Override
- public void visitTypeSignature(TypeSignature typeSignature) {
+ public List<ClassTypeSignature> visitSuperInterfaces(
+ List<ClassTypeSignature> interfaceSignatures) {
+ if (interfaceSignatures == null) {
+ return null;
+ }
+ interfaceSignatures.forEach(this::visitSuperInterface);
+ return interfaceSignatures;
+ }
+
+ @Override
+ public ClassTypeSignature visitSuperInterface(ClassTypeSignature classTypeSignature) {
+ return classTypeSignature.visit(this);
+ }
+
+ @Override
+ public TypeSignature visitTypeSignature(TypeSignature typeSignature) {
if (typeSignature.isBaseTypeSignature()) {
- return;
+ return typeSignature;
}
assert typeSignature.isFieldTypeSignature();
- visitFieldTypeSignature(typeSignature.asFieldTypeSignature());
+ return visitFieldTypeSignature(typeSignature.asFieldTypeSignature());
}
@Override
- public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
- visitClassTypeSignature(classTypeSignature);
+ public ClassTypeSignature visitSimpleClass(ClassTypeSignature classTypeSignature) {
+ return classTypeSignature.visit(this);
}
@Override
- public void visitReturnType(ReturnType returnType) {
+ public ReturnType visitReturnType(ReturnType returnType) {
if (returnType.isVoidDescriptor()) {
- return;
+ return returnType;
}
visitTypeSignature(returnType.typeSignature);
+ return returnType;
}
@Override
- public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+ public List<TypeSignature> visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
typeSignatures.forEach(this::visitTypeSignature);
+ return typeSignatures;
}
@Override
- public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+ public List<TypeSignature> visitThrowsSignatures(List<TypeSignature> typeSignatures) {
typeSignatures.forEach(this::visitTypeSignature);
+ return typeSignatures;
}
@Override
- public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
+ public List<FieldTypeSignature> visitTypeArguments(List<FieldTypeSignature> typeArguments) {
typeArguments.forEach(this::visitFieldTypeSignature);
+ return typeArguments;
+ }
+
+ @Override
+ public FormalTypeParameter visitFormalTypeParameter(FormalTypeParameter formalTypeParameter) {
+ return formalTypeParameter.visit(this);
+ }
+
+ @Override
+ public DexType visitType(DexType type) {
+ enqueuerDefinitionSupplier.definitionFor(type, context);
+ return type;
}
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
index a670da0..739bc27 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
@@ -30,98 +30,123 @@
private final StringBuilder sb = new StringBuilder();
@Override
- public void visitClassSignature(ClassSignature classSignature) {
- classSignature.visit(this);
+ public ClassSignature visitClassSignature(ClassSignature classSignature) {
+ return classSignature.visit(this);
}
@Override
- public void visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
+ public FieldTypeSignature visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
printFieldTypeSignature(fieldSignature, false);
+ return fieldSignature;
}
@Override
- public void visitMethodSignature(MethodTypeSignature methodSignature) {
- methodSignature.visit(this);
+ public MethodTypeSignature visitMethodSignature(MethodTypeSignature methodSignature) {
+ return methodSignature.visit(this);
}
@Override
- public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+ public List<TypeSignature> visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
sb.append("(");
typeSignatures.forEach(this::visitTypeSignature);
sb.append(")");
+ return typeSignatures;
}
@Override
- public void visitReturnType(ReturnType returnType) {
+ public ReturnType visitReturnType(ReturnType returnType) {
if (returnType.isVoidDescriptor()) {
sb.append("V");
} else {
visitTypeSignature(returnType.typeSignature);
}
+ return returnType;
}
@Override
- public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+ public List<TypeSignature> visitThrowsSignatures(List<TypeSignature> typeSignatures) {
for (TypeSignature typeSignature : typeSignatures) {
sb.append("^");
visitTypeSignature(typeSignature);
}
+ return typeSignatures;
}
@Override
- public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
+ public List<FormalTypeParameter> visitFormalTypeParameters(
+ List<FormalTypeParameter> formalTypeParameters) {
if (formalTypeParameters.isEmpty()) {
- return;
+ return formalTypeParameters;
}
sb.append("<");
- for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
- sb.append(formalTypeParameter.name);
- formalTypeParameter.visit(this);
- }
+ formalTypeParameters.forEach(this::visitFormalTypeParameter);
sb.append(">");
+ return formalTypeParameters;
}
@Override
- public void visitClassBound(FieldTypeSignature fieldSignature) {
+ public FieldTypeSignature visitClassBound(FieldTypeSignature fieldSignature) {
sb.append(":");
printFieldTypeSignature(fieldSignature, false);
+ return fieldSignature;
}
@Override
- public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
+ public List<FieldTypeSignature> visitInterfaceBounds(List<FieldTypeSignature> fieldSignatures) {
+ if (fieldSignatures == null) {
+ return null;
+ }
+ fieldSignatures.forEach(this::visitInterfaceBound);
+ return fieldSignatures;
+ }
+
+ @Override
+ public FieldTypeSignature visitInterfaceBound(FieldTypeSignature fieldSignature) {
sb.append(":");
printFieldTypeSignature(fieldSignature, false);
+ return fieldSignature;
}
@Override
- public void visitSuperClass(ClassTypeSignature classTypeSignature) {
+ public ClassTypeSignature visitSuperClass(ClassTypeSignature classTypeSignature) {
printFieldTypeSignature(classTypeSignature, false);
+ return classTypeSignature;
}
@Override
- public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
+ public List<ClassTypeSignature> visitSuperInterfaces(
+ List<ClassTypeSignature> interfaceSignatures) {
+ interfaceSignatures.forEach(this::visitSuperInterface);
+ return interfaceSignatures;
+ }
+
+ @Override
+ public ClassTypeSignature visitSuperInterface(ClassTypeSignature classTypeSignature) {
printFieldTypeSignature(classTypeSignature, false);
+ return classTypeSignature;
}
@Override
- public void visitTypeSignature(TypeSignature typeSignature) {
+ public TypeSignature visitTypeSignature(TypeSignature typeSignature) {
if (typeSignature.isBaseTypeSignature()) {
DexType type = typeSignature.asBaseTypeSignature().type;
sb.append(type.toDescriptorString());
} else {
printFieldTypeSignature(typeSignature.asFieldTypeSignature(), false);
}
+ return typeSignature;
}
@Override
- public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
+ public ClassTypeSignature visitSimpleClass(ClassTypeSignature classTypeSignature) {
printFieldTypeSignature(classTypeSignature, true);
+ return classTypeSignature;
}
@Override
- public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
+ public List<FieldTypeSignature> visitTypeArguments(List<FieldTypeSignature> typeArguments) {
if (typeArguments.isEmpty()) {
- return;
+ return typeArguments;
}
sb.append("<");
for (FieldTypeSignature typeArgument : typeArguments) {
@@ -133,10 +158,17 @@
visitTypeSignature(typeArgument);
}
sb.append(">");
+ return typeArguments;
+ }
+
+ @Override
+ public FormalTypeParameter visitFormalTypeParameter(FormalTypeParameter formalTypeParameter) {
+ sb.append(formalTypeParameter.name);
+ return formalTypeParameter.visit(this);
}
private void printFieldTypeSignature(
- FieldTypeSignature fieldTypeSignature, boolean printingInner) {
+ FieldTypeSignature fieldTypeSignature, boolean printingOuter) {
// For inner member classes we only print the inner name and the type-arguments.
if (fieldTypeSignature.isStar()) {
sb.append("*");
@@ -151,11 +183,14 @@
if (classTypeSignature.hasNoSignature()) {
return;
}
+ // Visit enclosing before printing the type name to ensure we
+ if (classTypeSignature.enclosingTypeSignature != null) {
+ visitSimpleClass(classTypeSignature.enclosingTypeSignature);
+ }
String renamedString = namingLens.lookupDescriptor(classTypeSignature.type).toString();
- if (!printingInner) {
+ if (classTypeSignature.enclosingTypeSignature == null) {
sb.append("L").append(DescriptorUtils.getBinaryNameFromDescriptor(renamedString));
} else {
- assert classTypeSignature.enclosingTypeSignature != null;
DexType enclosingType = classTypeSignature.enclosingTypeSignature.type;
String outerDescriptor = namingLens.lookupDescriptor(enclosingType).toString();
String innerClassName = DescriptorUtils.getInnerClassName(outerDescriptor, renamedString);
@@ -170,14 +205,21 @@
}
sb.append(".").append(innerClassName);
}
- classTypeSignature.visit(this);
- if (!printingInner) {
+ visitTypeArguments(classTypeSignature.typeArguments);
+ if (!printingOuter) {
sb.append(";");
}
}
}
@Override
+ public DexType visitType(DexType type) {
+ // We need to delay printing of class type until enclosing class has been visited. We therefore
+ // only print in printFieldTypeSignature.
+ return type;
+ }
+
+ @Override
public String toString() {
return sb.toString();
}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
index d20833f..5820a4c 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
@@ -8,19 +8,17 @@
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_ARGUMENTS;
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_PARAMS;
import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_SIGNATURES;
-import static com.android.tools.r8.graph.GenericSignature.FieldTypeSignature.noSignature;
-import static com.android.tools.r8.graph.GenericSignature.StarFieldTypeSignature.STAR_FIELD_TYPE_SIGNATURE;
import static com.google.common.base.Predicates.alwaysFalse;
-import com.android.tools.r8.graph.GenericSignature.ArrayTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ClassSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignature.ReturnType;
+import com.android.tools.r8.graph.GenericSignature.StarFieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.TypeSignature;
-import java.util.ArrayList;
+import com.android.tools.r8.utils.ListUtils;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -60,14 +58,15 @@
if (classSignature.hasNoSignature() || classSignature.isInvalid()) {
return classSignature;
}
- return new ClassSignatureRewriter().run(classSignature);
+ return new GenericSignatureRewriter().visitClassSignature(classSignature);
}
public FieldTypeSignature rewrite(FieldTypeSignature fieldTypeSignature) {
if (fieldTypeSignature.hasNoSignature() || fieldTypeSignature.isInvalid()) {
return fieldTypeSignature;
}
- FieldTypeSignature rewrittenSignature = new TypeSignatureRewriter().run(fieldTypeSignature);
+ FieldTypeSignature rewrittenSignature =
+ new GenericSignatureRewriter().visitFieldTypeSignature(fieldTypeSignature);
return rewrittenSignature == null ? FieldTypeSignature.noSignature() : rewrittenSignature;
}
@@ -75,268 +74,169 @@
if (methodTypeSignature.hasNoSignature() || methodTypeSignature.isInvalid()) {
return methodTypeSignature;
}
- return new MethodTypeSignatureRewriter().run(methodTypeSignature);
+ return new GenericSignatureRewriter().visitMethodSignature(methodTypeSignature);
}
- private class ClassSignatureRewriter implements GenericSignatureVisitor {
-
- private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
- private ClassTypeSignature rewrittenSuperClass;
- private final List<ClassTypeSignature> rewrittenSuperInterfaces = new ArrayList<>();
+ private class GenericSignatureRewriter implements GenericSignatureVisitor {
@Override
- public void visitClassSignature(ClassSignature classSignature) {
- classSignature.visit(this);
- }
-
- @Override
- public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
- for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
- rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
- }
- }
-
- @Override
- public void visitSuperClass(ClassTypeSignature classTypeSignature) {
- rewrittenSuperClass = new ClassTypeSignatureRewriter(true).run(classTypeSignature);
- if (rewrittenSuperClass == null) {
- rewrittenSuperClass = new ClassTypeSignature(factory.objectType, EMPTY_TYPE_ARGUMENTS);
- }
- }
-
- @Override
- public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
- ClassTypeSignature superInterface =
- new ClassTypeSignatureRewriter(true).run(classTypeSignature);
- if (superInterface != null) {
- rewrittenSuperInterfaces.add(superInterface);
- }
- }
-
- private ClassSignature run(ClassSignature classSignature) {
- classSignature.visit(this);
- if (rewrittenTypeParameters.isEmpty()
- && rewrittenSuperInterfaces.isEmpty()
- && rewrittenSuperClass.hasNoSignature()
- && rewrittenSuperClass.type == factory.objectType) {
+ public ClassSignature visitClassSignature(ClassSignature classSignature) {
+ ClassSignature rewritten = classSignature.visit(this);
+ if (rewritten.getFormalTypeParameters().isEmpty()
+ && rewritten.superInterfaceSignatures.isEmpty()
+ && rewritten.superClassSignature.type == factory.objectType) {
return ClassSignature.noSignature();
}
- return new ClassSignature(
- rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
- rewrittenSuperClass,
- rewrittenSuperInterfaces.isEmpty() ? EMPTY_SUPER_INTERFACES : rewrittenSuperInterfaces);
- }
- }
-
- private class MethodTypeSignatureRewriter implements GenericSignatureVisitor {
-
- private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
- private final List<TypeSignature> rewrittenTypeSignatures = new ArrayList<>();
-
- ReturnType rewrittenReturnType = null;
- private final List<TypeSignature> rewrittenThrowsSignatures = new ArrayList<>();
-
- @Override
- public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
- for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
- rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
- }
+ return rewritten;
}
@Override
- public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
- for (TypeSignature typeSignature : typeSignatures) {
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
- rewrittenTypeSignatures.add(rewrittenType == null ? objectTypeSignature : rewrittenType);
- }
+ public MethodTypeSignature visitMethodSignature(MethodTypeSignature methodSignature) {
+ return methodSignature.visit(this);
}
@Override
- public void visitReturnType(ReturnType returnType) {
- if (returnType.isVoidDescriptor()) {
- rewrittenReturnType = ReturnType.VOID;
+ public FieldTypeSignature visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
+ if (fieldSignature.isStar() || fieldSignature.isTypeVariableSignature()) {
+ return fieldSignature;
+ } else if (fieldSignature.isArrayTypeSignature()) {
+ return fieldSignature.asArrayTypeSignature().visit(this);
} else {
- TypeSignature originalType = returnType.typeSignature();
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(originalType);
- if (rewrittenType == null) {
- rewrittenReturnType = ReturnType.VOID;
- } else if (rewrittenType == originalType) {
- rewrittenReturnType = returnType;
- } else {
- rewrittenReturnType = new ReturnType(rewrittenType);
- }
+ assert fieldSignature.isClassTypeSignature();
+ return fieldSignature.asClassTypeSignature().visit(this);
}
}
@Override
- public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
- for (TypeSignature typeSignature : typeSignatures) {
- TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
- // If a throwing type is no longer found we remove it from the signature.
- if (rewrittenType != null) {
- rewrittenThrowsSignatures.add(rewrittenType);
- }
- }
- }
-
- private MethodTypeSignature run(MethodTypeSignature methodTypeSignature) {
- methodTypeSignature.visit(this);
- assert rewrittenReturnType != null;
- if (rewrittenTypeParameters.isEmpty()
- && rewrittenTypeSignatures.isEmpty()
- && rewrittenReturnType.isVoidDescriptor()
- && rewrittenThrowsSignatures.isEmpty()) {
- return MethodTypeSignature.noSignature();
- }
- return new MethodTypeSignature(
- rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
- rewrittenTypeSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenTypeSignatures,
- rewrittenReturnType,
- rewrittenThrowsSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenThrowsSignatures);
- }
- }
-
- private class FormalTypeParameterRewriter implements GenericSignatureVisitor {
-
- private FieldTypeSignature rewrittenClassBound = noSignature();
- private final List<FieldTypeSignature> rewrittenInterfaceBounds = new ArrayList<>();
-
- @Override
- public void visitClassBound(FieldTypeSignature fieldSignature) {
- rewrittenClassBound = new TypeSignatureRewriter().run(fieldSignature);
- }
-
- @Override
- public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
- FieldTypeSignature interfaceBound = new TypeSignatureRewriter().run(fieldSignature);
- if (interfaceBound != null) {
- rewrittenInterfaceBounds.add(interfaceBound);
- }
- }
-
- private FormalTypeParameter run(FormalTypeParameter formalTypeParameter) {
- formalTypeParameter.visit(this);
- // Guard against the case where we have <T::...> that is, no class or interfaces bounds.
- if (rewrittenInterfaceBounds.isEmpty()
- && (rewrittenClassBound == null || !rewrittenClassBound.hasSignature())) {
- rewrittenClassBound = objectTypeSignature;
- }
- return new FormalTypeParameter(
- formalTypeParameter.name,
- rewrittenClassBound == null ? noSignature() : rewrittenClassBound,
- rewrittenInterfaceBounds.isEmpty() ? EMPTY_TYPE_ARGUMENTS : rewrittenInterfaceBounds);
- }
- }
-
- private class TypeSignatureRewriter implements GenericSignatureVisitor {
-
- private TypeSignature run(TypeSignature typeSignature) {
+ public TypeSignature visitTypeSignature(TypeSignature typeSignature) {
if (typeSignature.isBaseTypeSignature()) {
return typeSignature;
+ } else {
+ return visitFieldTypeSignature(typeSignature.asFieldTypeSignature());
}
- assert typeSignature.isFieldTypeSignature();
- return run(typeSignature.asFieldTypeSignature());
}
- private FieldTypeSignature run(FieldTypeSignature fieldTypeSignature) {
- if (fieldTypeSignature.isStar()) {
- return fieldTypeSignature;
+ @Override
+ public List<FormalTypeParameter> visitFormalTypeParameters(
+ List<FormalTypeParameter> formalTypeParameters) {
+ if (formalTypeParameters.isEmpty()) {
+ return EMPTY_TYPE_PARAMS;
}
- if (fieldTypeSignature.isTypeVariableSignature()) {
- return fieldTypeSignature;
+ return ListUtils.map(formalTypeParameters, this::visitFormalTypeParameter);
+ }
+
+ @Override
+ public FormalTypeParameter visitFormalTypeParameter(FormalTypeParameter formalTypeParameter) {
+ return formalTypeParameter.visit(this);
+ }
+
+ @Override
+ public ClassTypeSignature visitSuperClass(ClassTypeSignature classTypeSignature) {
+ ClassTypeSignature rewritten = classTypeSignature.visit(this);
+ return rewritten == null || rewritten.type() == context.type
+ ? new ClassTypeSignature(factory.objectType, EMPTY_TYPE_ARGUMENTS)
+ : rewritten;
+ }
+
+ @Override
+ public List<ClassTypeSignature> visitSuperInterfaces(
+ List<ClassTypeSignature> interfaceSignatures) {
+ if (interfaceSignatures.isEmpty()) {
+ return EMPTY_SUPER_INTERFACES;
}
- if (fieldTypeSignature.isArrayTypeSignature()) {
- ArrayTypeSignature arrayTypeSignature = fieldTypeSignature.asArrayTypeSignature();
- TypeSignature rewrittenElement = run(arrayTypeSignature.elementSignature);
- if (rewrittenElement == null) {
- return new ArrayTypeSignature(objectTypeSignature);
+ return ListUtils.mapNotNull(interfaceSignatures, this::visitSuperInterface);
+ }
+
+ @Override
+ public ClassTypeSignature visitSuperInterface(ClassTypeSignature classTypeSignature) {
+ ClassTypeSignature rewritten = classTypeSignature.visit(this);
+ return rewritten == null || rewritten.type() == context.type ? null : rewritten;
+ }
+
+ @Override
+ public List<TypeSignature> visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+ if (typeSignatures.isEmpty()) {
+ return EMPTY_TYPE_SIGNATURES;
+ }
+ return ListUtils.map(
+ typeSignatures,
+ typeSignature -> {
+ TypeSignature rewrittenSignature = visitTypeSignature(typeSignature);
+ return rewrittenSignature == null ? objectTypeSignature : rewrittenSignature;
+ });
+ }
+
+ @Override
+ public ReturnType visitReturnType(ReturnType returnType) {
+ if (returnType.isVoidDescriptor()) {
+ return ReturnType.VOID;
+ } else {
+ TypeSignature originalType = returnType.typeSignature();
+ TypeSignature rewrittenType = visitTypeSignature(originalType);
+ if (rewrittenType == null) {
+ return ReturnType.VOID;
+ } else if (rewrittenType == originalType) {
+ return returnType;
+ } else {
+ return new ReturnType(rewrittenType);
}
- return rewrittenElement.toArrayTypeSignature();
}
- assert fieldTypeSignature.isClassTypeSignature();
- ClassTypeSignature classTypeSignature = fieldTypeSignature.asClassTypeSignature();
- if (classTypeSignature.hasNoSignature()) {
- return classTypeSignature;
- }
- return new ClassTypeSignatureRewriter(false).run(classTypeSignature);
- }
- }
-
- private class ClassTypeSignatureRewriter implements GenericSignatureVisitor {
-
- private final boolean isSuperClassOrInterface;
-
- // These fields are updated when iterating the modeled structure.
- private DexType currentType;
-
- // The following references are used to have a head and tail pointer to the classTypeSignature
- // link we are building. The topClassSignature will have a reference to the top-most package
- // and class-name. The parentClassSignature is a pointer pointing to the tail always and will
- // be linked and updated when calling ClassTypeSignature.link.
- private ClassTypeSignature topClassSignature;
- private ClassTypeSignature parentClassSignature;
-
- private ClassTypeSignatureRewriter(boolean isSuperClassOrInterface) {
- this.isSuperClassOrInterface = isSuperClassOrInterface;
}
@Override
- public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
- currentType = getTarget(classTypeSignature.type);
- if (currentType == null) {
- return;
+ public List<TypeSignature> visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+ if (typeSignatures.isEmpty()) {
+ return EMPTY_TYPE_SIGNATURES;
}
- classTypeSignature.visit(this);
+ // If a throwing type is no longer found we remove it from the signature.
+ return ListUtils.mapNotNull(typeSignatures, this::visitTypeSignature);
}
@Override
- public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
- ClassTypeSignature newClassTypeSignature;
+ public FieldTypeSignature visitClassBound(FieldTypeSignature fieldSignature) {
+ return visitFieldTypeSignature(fieldSignature);
+ }
+
+ @Override
+ public List<FieldTypeSignature> visitInterfaceBounds(List<FieldTypeSignature> fieldSignatures) {
+ if (fieldSignatures == null) {
+ return null;
+ }
+ if (fieldSignatures.isEmpty()) {
+ return EMPTY_TYPE_ARGUMENTS;
+ }
+ return ListUtils.mapNotNull(fieldSignatures, this::visitFieldTypeSignature);
+ }
+
+ @Override
+ public FieldTypeSignature visitInterfaceBound(FieldTypeSignature fieldSignature) {
+ return visitFieldTypeSignature(fieldSignature);
+ }
+
+ @Override
+ public ClassTypeSignature visitSimpleClass(ClassTypeSignature classTypeSignature) {
+ return classTypeSignature.visit(this);
+ }
+
+ @Override
+ public List<FieldTypeSignature> visitTypeArguments(List<FieldTypeSignature> typeArguments) {
if (typeArguments.isEmpty()) {
- newClassTypeSignature = new ClassTypeSignature(currentType, EMPTY_TYPE_ARGUMENTS);
- } else {
- List<FieldTypeSignature> rewrittenTypeArguments = new ArrayList<>(typeArguments.size());
- for (FieldTypeSignature typeArgument : typeArguments) {
- if (typeArgument.isStar()) {
- rewrittenTypeArguments.add(typeArgument);
- continue;
- }
- FieldTypeSignature rewritten = new TypeSignatureRewriter().run(typeArgument);
- if (rewritten != null) {
- rewrittenTypeArguments.add(rewritten.asArgument(typeArgument.getWildcardIndicator()));
- } else {
- rewrittenTypeArguments.add(STAR_FIELD_TYPE_SIGNATURE);
- }
- }
- newClassTypeSignature = new ClassTypeSignature(currentType, rewrittenTypeArguments);
+ return EMPTY_TYPE_ARGUMENTS;
}
- if (topClassSignature == null) {
- topClassSignature = newClassTypeSignature;
- parentClassSignature = newClassTypeSignature;
- } else {
- ClassTypeSignature.link(parentClassSignature, newClassTypeSignature);
- parentClassSignature = newClassTypeSignature;
- }
+ return ListUtils.map(
+ typeArguments,
+ fieldTypeSignature -> {
+ FieldTypeSignature rewrittenSignature = visitFieldTypeSignature(fieldTypeSignature);
+ return rewrittenSignature == null
+ ? StarFieldTypeSignature.getStarFieldTypeSignature()
+ : rewrittenSignature;
+ });
}
- private ClassTypeSignature run(ClassTypeSignature classTypeSignature) {
- currentType = getTarget(classTypeSignature.type);
- if (currentType == null) {
- return null;
- }
- classTypeSignature.visit(this);
- return topClassSignature;
- }
-
- private DexType getTarget(DexType type) {
+ @Override
+ public DexType visitType(DexType type) {
DexType rewrittenType = lookupType.apply(type);
- if (wasPruned.test(rewrittenType)) {
- return null;
- }
- if (isSuperClassOrInterface && context.type == rewrittenType) {
- return null;
- }
- return rewrittenType;
+ return wasPruned.test(rewrittenType) ? null : rewrittenType;
}
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
index d3840dd..ba1d8f2 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
@@ -16,59 +16,77 @@
public interface GenericSignatureVisitor {
- default void visitClassSignature(ClassSignature classSignature) {
+ default ClassSignature visitClassSignature(ClassSignature classSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitMethodSignature(MethodTypeSignature methodSignature) {
+ default MethodTypeSignature visitMethodSignature(MethodTypeSignature methodSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
+ default FieldTypeSignature visitFieldTypeSignature(FieldTypeSignature fieldSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
+ default List<FormalTypeParameter> visitFormalTypeParameters(
+ List<FormalTypeParameter> formalTypeParameters) {
throw new Unreachable("Implement if visited");
}
- default void visitClassBound(FieldTypeSignature fieldSignature) {
+ default FormalTypeParameter visitFormalTypeParameter(FormalTypeParameter formalTypeParameter) {
throw new Unreachable("Implement if visited");
}
- default void visitInterfaceBound(FieldTypeSignature fieldSignature) {
+ default FieldTypeSignature visitClassBound(FieldTypeSignature fieldSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitSuperClass(ClassTypeSignature classTypeSignature) {
+ default List<FieldTypeSignature> visitInterfaceBounds(List<FieldTypeSignature> fieldSignatures) {
throw new Unreachable("Implement if visited");
}
- default void visitSuperInterface(ClassTypeSignature classTypeSignature) {
+ default FieldTypeSignature visitInterfaceBound(FieldTypeSignature fieldSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitTypeSignature(TypeSignature typeSignature) {
+ default ClassTypeSignature visitSuperClass(ClassTypeSignature classTypeSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitSimpleClass(ClassTypeSignature classTypeSignature) {
+ default List<ClassTypeSignature> visitSuperInterfaces(
+ List<ClassTypeSignature> interfaceSignatures) {
throw new Unreachable("Implement if visited");
}
- default void visitReturnType(ReturnType returnType) {
+ default ClassTypeSignature visitSuperInterface(ClassTypeSignature classTypeSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+ default TypeSignature visitTypeSignature(TypeSignature typeSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+ default ClassTypeSignature visitSimpleClass(ClassTypeSignature classTypeSignature) {
throw new Unreachable("Implement if visited");
}
- default void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
+ default ReturnType visitReturnType(ReturnType returnType) {
+ throw new Unreachable("Implement if visited");
+ }
+
+ default List<TypeSignature> visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+ throw new Unreachable("Implement if visited");
+ }
+
+ default List<TypeSignature> visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+ throw new Unreachable("Implement if visited");
+ }
+
+ default List<FieldTypeSignature> visitTypeArguments(List<FieldTypeSignature> typeArguments) {
+ throw new Unreachable("Implement if visited");
+ }
+
+ default DexType visitType(DexType type) {
throw new Unreachable("Implement if visited");
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/ListUtils.java b/src/main/java/com/android/tools/r8/utils/ListUtils.java
index f4c8deb..b04728e 100644
--- a/src/main/java/com/android/tools/r8/utils/ListUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ListUtils.java
@@ -87,6 +87,17 @@
return result;
}
+ public static <S, T> List<T> mapNotNull(Collection<S> list, Function<S, T> fn) {
+ List<T> result = new ArrayList<>(list.size());
+ for (S element : list) {
+ T mapped = fn.apply(element);
+ if (mapped != null) {
+ result.add(mapped);
+ }
+ }
+ return result;
+ }
+
/**
* Rewrites the input list based on the given function. Returns the mapped list if any elements
* were rewritten, otherwise returns the original list.
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 2d1be5b..df62f93 100644
--- a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
@@ -125,10 +125,16 @@
assertNull(formalTypeParameter.interfaceBounds);
assertTrue(formalTypeParameter.classBound.isClassTypeSignature());
ClassTypeSignature classBoundSignature = formalTypeParameter.classBound.asClassTypeSignature();
- assertEquals(y.getDexProgramClass().type, classBoundSignature.innerTypeSignature.type);
- assertEquals(1, classBoundSignature.typeArguments.size());
+ assertEquals(y.getDexProgramClass().type, classBoundSignature.type);
+ assertEquals(1, classBoundSignature.enclosingTypeSignature.typeArguments.size());
assertEquals(
- "T", classBoundSignature.typeArguments.get(0).asTypeVariableSignature().typeVariable);
+ "T",
+ classBoundSignature
+ .enclosingTypeSignature
+ .typeArguments
+ .get(0)
+ .asTypeVariableSignature()
+ .typeVariable);
assertTrue(classSignature.superInterfaceSignatures.isEmpty());
classTypeSignature = classSignature.superClassSignature;
@@ -173,7 +179,7 @@
assertTrue(methodFormalParameter.classBound.isClassTypeSignature());
assertEquals(
y.getDexProgramClass().getType(),
- methodFormalParameter.classBound.asClassTypeSignature().innerTypeSignature.type);
+ methodFormalParameter.classBound.asClassTypeSignature().type);
assertNotNull(methodFormalParameter.interfaceBounds);
assertEquals(1, methodFormalParameter.interfaceBounds.size());
FieldTypeSignature interfaceBound = methodFormalParameter.interfaceBounds.get(0);
@@ -258,29 +264,31 @@
check_A_Y_foo_bar_baz(y, appView);
}
- private void check_A_Y(ClassSubject a, ClassSubject y, ClassTypeSignature signature) {
+ private void check_A(ClassSubject a, ClassTypeSignature signature) {
assertEquals(a.getDexProgramClass().type, signature.type);
List<FieldTypeSignature> typeArguments = signature.typeArguments;
assertEquals(1, typeArguments.size());
FieldTypeSignature typeArgument = typeArguments.get(0);
assertTrue(typeArgument.isTypeVariableSignature());
assertEquals("T", typeArgument.asTypeVariableSignature().typeVariable);
- assertEquals(y.getDexProgramClass().type, signature.innerTypeSignature.type);
+ }
+
+ private void check_A_Y(ClassSubject a, ClassSubject y, ClassTypeSignature signature) {
+ check_A(a, signature.enclosingTypeSignature);
+ assertEquals(y.getDexProgramClass().type, signature.type);
}
private void check_A_Y_YY(
ClassSubject a, ClassSubject y, ClassSubject yy, ClassTypeSignature signature) {
- check_A_Y(a, y, signature);
- assertEquals(
- yy.getDexProgramClass().type, signature.innerTypeSignature.innerTypeSignature.type);
+ check_A_Y(a, y, signature.enclosingTypeSignature);
+ assertEquals(yy.getDexProgramClass().type, signature.type);
}
private void check_A_Y_ZZ(
ClassSubject a, ClassSubject y, ClassSubject zz, ClassTypeSignature signature) {
- check_A_Y(a, y, signature);
- ClassTypeSignature innerMost = signature.innerTypeSignature.innerTypeSignature;
- assertEquals(zz.getDexProgramClass().type, innerMost.type);
- List<FieldTypeSignature> typeArguments = innerMost.typeArguments;
+ check_A_Y(a, y, signature.enclosingTypeSignature);
+ assertEquals(zz.getDexProgramClass().type, signature.type);
+ List<FieldTypeSignature> typeArguments = signature.typeArguments;
assertEquals(1, typeArguments.size());
FieldTypeSignature typeArgument = typeArguments.get(0);
assertTrue(typeArgument.isTypeVariableSignature());