Add permitted subclass attributes to internal structure
Bug: 227160052
Change-Id: I5b5af1c493492e8ac3b732813594aa54185d0643
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index 9dc5143..af340d4 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -205,6 +205,7 @@
null,
null,
Collections.emptyList(),
+ Collections.emptyList(),
null,
Collections.emptyList(),
ClassSignature.noSignature(),
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index 10132f3..604565b 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -65,6 +65,7 @@
import com.android.tools.r8.graph.NestMemberClassAttribute;
import com.android.tools.r8.graph.OffsetToObjectMapping;
import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.graph.PermittedSubclassAttribute;
import com.android.tools.r8.logging.Log;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
@@ -859,6 +860,7 @@
source,
attrs.nestHostAttribute,
attrs.nestMembersAttribute,
+ attrs.permittedSubclasses,
attrs.getEnclosingMethodAttribute(),
attrs.getInnerClasses(),
attrs.classSignature,
@@ -1427,6 +1429,7 @@
private ClassSignature classSignature = ClassSignature.noSignature();
private NestHostClassAttribute nestHostAttribute;
private List<NestMemberClassAttribute> nestMembersAttribute = Collections.emptyList();
+ private List<PermittedSubclassAttribute> permittedSubclasses = Collections.emptyList();
public DexAnnotationSet getAnnotations() {
if (lazyAnnotations != null) {
diff --git a/src/main/java/com/android/tools/r8/graph/ClassKind.java b/src/main/java/com/android/tools/r8/graph/ClassKind.java
index 60f78ea..e878e0d 100644
--- a/src/main/java/com/android/tools/r8/graph/ClassKind.java
+++ b/src/main/java/com/android/tools/r8/graph/ClassKind.java
@@ -26,6 +26,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -47,6 +48,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -69,6 +71,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -90,6 +93,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -110,6 +114,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -131,6 +136,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -152,6 +158,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -183,6 +190,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -204,6 +212,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 6f5e604..a77f418 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -80,6 +80,8 @@
private List<NestMemberClassAttribute> nestMembers;
+ private List<PermittedSubclassAttribute> permittedSubclasses;
+
/** Generic signature information if the attribute is present in the input */
protected ClassSignature classSignature;
@@ -94,6 +96,7 @@
MethodCollectionFactory methodCollectionFactory,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMethod,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -114,6 +117,8 @@
this.nestHost = nestHost;
this.nestMembers = nestMembers;
assert nestMembers != null;
+ this.permittedSubclasses = permittedSubclasses;
+ assert permittedSubclasses != null;
this.enclosingMethod = enclosingMethod;
this.innerClasses = innerClasses;
assert classSignature != null;
@@ -1180,7 +1185,7 @@
}
public boolean hasNestMemberAttributes() {
- return nestMembers != null && !nestMembers.isEmpty();
+ return !nestMembers.isEmpty();
}
public List<NestMemberClassAttribute> getNestMembersClassAttributes() {
@@ -1195,6 +1200,14 @@
nestMembers.removeIf(predicate);
}
+ public boolean hasPermittedSubclassAttributes() {
+ return !permittedSubclasses.isEmpty();
+ }
+
+ public List<PermittedSubclassAttribute> getPermittedSubclassAttributes() {
+ return permittedSubclasses;
+ }
+
/** Returns kotlin class info if the class is synthesized by kotlin compiler. */
public abstract KotlinClassLevelInfo getKotlinInfo();
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index 5130c57..43c2532 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -35,6 +35,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -54,6 +55,7 @@
methodCollectionFactory,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
index e5cd61c..24091e4 100644
--- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
@@ -33,6 +33,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -52,6 +53,7 @@
methodCollectionFactory,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -171,6 +173,7 @@
private DexString sourceFile = null;
private NestHostClassAttribute nestHost = null;
private List<NestMemberClassAttribute> nestMembers = Collections.emptyList();
+ private List<PermittedSubclassAttribute> permittedSubclasses = Collections.emptyList();
private EnclosingMethodAttribute enclosingMember = null;
private List<InnerClassAttribute> innerClasses = Collections.emptyList();
private ClassSignature classSignature = ClassSignature.noSignature();
@@ -213,6 +216,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 46bebdc..b49abbe 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -69,6 +69,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -90,6 +91,7 @@
methodCollectionFactory,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
@@ -113,6 +115,7 @@
DexString sourceFile,
NestHostClassAttribute nestHost,
List<NestMemberClassAttribute> nestMembers,
+ List<PermittedSubclassAttribute> permittedSubclasses,
EnclosingMethodAttribute enclosingMember,
List<InnerClassAttribute> innerClasses,
ClassSignature classSignature,
@@ -132,6 +135,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
diff --git a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index d88983a..ac2c8aa 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -226,6 +226,7 @@
private DexString sourceFile;
private NestHostClassAttribute nestHost = null;
private final List<NestMemberClassAttribute> nestMembers = new ArrayList<>();
+ private final List<PermittedSubclassAttribute> permittedSubclasses = new ArrayList<>();
private final Set<DexField> recordComponents = Sets.newIdentityHashSet();
private EnclosingMethodAttribute enclosingMember = null;
private final List<InnerClassAttribute> innerClasses = new ArrayList<>();
@@ -348,11 +349,12 @@
@Override
public void visitPermittedSubclass(String permittedSubclass) {
+ assert permittedSubclass != null;
+ DexType permittedSubclassType = application.getTypeFromName(permittedSubclass);
+ permittedSubclasses.add(new PermittedSubclassAttribute(permittedSubclassType));
if (classKind == ClassKind.PROGRAM) {
throw new CompilationError("Sealed classes are not supported as program classes", origin);
}
- // For library and classpath just ignore the permitted subclasses, as the compiler is not
- // validating the code with respect to sealed classes.
}
@Override
@@ -476,6 +478,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMember,
innerClasses,
classSignature,
diff --git a/src/main/java/com/android/tools/r8/graph/PermittedSubclassAttribute.java b/src/main/java/com/android/tools/r8/graph/PermittedSubclassAttribute.java
new file mode 100644
index 0000000..0c4dd43
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/PermittedSubclassAttribute.java
@@ -0,0 +1,49 @@
+// Copyright (c) 2022, 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.graph;
+
+import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.utils.structural.StructuralItem;
+import com.android.tools.r8.utils.structural.StructuralMapping;
+import com.android.tools.r8.utils.structural.StructuralSpecification;
+import java.util.Collections;
+import java.util.List;
+import org.objectweb.asm.ClassWriter;
+
+public class PermittedSubclassAttribute implements StructuralItem<PermittedSubclassAttribute> {
+
+ private final DexType permittedSubclass;
+
+ private static void specify(StructuralSpecification<PermittedSubclassAttribute, ?> spec) {
+ spec.withItem(a -> a.permittedSubclass);
+ }
+
+ public PermittedSubclassAttribute(DexType nestMember) {
+ this.permittedSubclass = nestMember;
+ }
+
+ public static List<PermittedSubclassAttribute> emptyList() {
+ return Collections.emptyList();
+ }
+
+ public DexType getPermittedSubclass() {
+ return permittedSubclass;
+ }
+
+ public void write(ClassWriter writer, NamingLens lens) {
+ assert permittedSubclass != null;
+ writer.visitPermittedSubclass(lens.lookupInternalName(permittedSubclass));
+ }
+
+ @Override
+ public PermittedSubclassAttribute self() {
+ return this;
+ }
+
+ @Override
+ public StructuralMapping<PermittedSubclassAttribute> getStructuralMapping() {
+ return PermittedSubclassAttribute::specify;
+ }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/TreeFixerBase.java b/src/main/java/com/android/tools/r8/graph/TreeFixerBase.java
index 0828ff2..1c99b6c 100644
--- a/src/main/java/com/android/tools/r8/graph/TreeFixerBase.java
+++ b/src/main/java/com/android/tools/r8/graph/TreeFixerBase.java
@@ -107,6 +107,7 @@
clazz.getSourceFile(),
fixupNestHost(clazz.getNestHostClassAttribute()),
fixupNestMemberAttributes(clazz.getNestMembersClassAttributes()),
+ fixupPermittedSubclassAttribute(clazz.getPermittedSubclassAttributes()),
fixupEnclosingMethodAttribute(clazz.getEnclosingMethodAttribute()),
fixupInnerClassAttributes(clazz.getInnerClasses()),
clazz.getClassSignature(),
@@ -271,6 +272,23 @@
return changed ? newNestMemberAttributes : nestMemberAttributes;
}
+ protected List<PermittedSubclassAttribute> fixupPermittedSubclassAttribute(
+ List<PermittedSubclassAttribute> permittedSubclassAttributes) {
+ if (permittedSubclassAttributes.isEmpty()) {
+ return permittedSubclassAttributes;
+ }
+ boolean changed = false;
+ List<PermittedSubclassAttribute> newPermittedSubclassAttributes =
+ new ArrayList<>(permittedSubclassAttributes.size());
+ for (PermittedSubclassAttribute permittedSubclassAttribute : permittedSubclassAttributes) {
+ DexType permittedSubclassType = permittedSubclassAttribute.getPermittedSubclass();
+ DexType newPermittedSubclassType = fixupType(permittedSubclassType);
+ newPermittedSubclassAttributes.add(new PermittedSubclassAttribute(newPermittedSubclassType));
+ changed |= newPermittedSubclassType != permittedSubclassType;
+ }
+ return changed ? newPermittedSubclassAttributes : permittedSubclassAttributes;
+ }
+
/** Fixup a proto descriptor. */
public DexProto fixupProto(DexProto proto) {
DexProto result = protoFixupCache.get(proto);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
index 695af34..c764377 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/EmulatedInterfaceApplicationRewriter.java
@@ -78,6 +78,7 @@
emulatedInterface.getSourceFile(),
null,
Collections.emptyList(),
+ Collections.emptyList(),
null, // Note that we clear the enclosing and inner class attributes.
Collections.emptyList(),
emulatedInterface.getClassSignature(),
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index 598dc4f..e9951c3 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.NestHostClassAttribute;
import com.android.tools.r8.graph.NestMemberClassAttribute;
+import com.android.tools.r8.graph.PermittedSubclassAttribute;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import java.util.ArrayList;
@@ -171,6 +172,7 @@
abstractFlag | finalFlag | itfFlag | Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC);
NestHostClassAttribute nestHost = null;
List<NestMemberClassAttribute> nestMembers = Collections.emptyList();
+ List<PermittedSubclassAttribute> permittedSubclasses = Collections.emptyList();
EnclosingMethodAttribute enclosingMembers = null;
List<InnerClassAttribute> innerClasses = Collections.emptyList();
for (SyntheticMethodBuilder builder : methods) {
@@ -198,6 +200,7 @@
sourceFile,
nestHost,
nestMembers,
+ permittedSubclasses,
enclosingMembers,
innerClasses,
signature,
diff --git a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
index 493df28..9d13687 100644
--- a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
@@ -34,6 +34,7 @@
null,
null,
Collections.emptyList(),
+ Collections.emptyList(),
null,
Collections.emptyList(),
ClassSignature.noSignature(),
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index ed70ece..5d54843 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -834,6 +834,7 @@
null,
null,
Collections.emptyList(),
+ Collections.emptyList(),
null,
Collections.emptyList(),
ClassSignature.noSignature(),