Replace SyntheticKind enum by a class structure.
Change-Id: Ic9ebd296c3e5581cb6ce7bf7f44c9902b3561247
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index 366ad9c..4ff028a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -391,9 +391,7 @@
public static DexAnnotation createAnnotationSynthesizedClass(
SyntheticKind kind, DexItemFactory dexItemFactory) {
DexAnnotationElement kindElement =
- new DexAnnotationElement(
- dexItemFactory.kindString,
- new DexValueString(dexItemFactory.createString(kind.descriptor)));
+ new DexAnnotationElement(dexItemFactory.kindString, DexValueInt.create(kind.getId()));
DexAnnotationElement[] elements = new DexAnnotationElement[] {kindElement};
return new DexAnnotation(
VISIBILITY_BUILD,
@@ -423,12 +421,11 @@
if (kindElement.name != factory.kindString) {
return null;
}
- if (!kindElement.value.isDexValueString()) {
+ if (!kindElement.value.isDexValueInt()) {
return null;
}
SyntheticKind kind =
- SyntheticNaming.SyntheticKind.fromDescriptor(
- kindElement.value.asDexValueString().getValue().toString());
+ SyntheticNaming.SyntheticKind.fromId(kindElement.value.asDexValueInt().getValue());
return kind;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringForTesting.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringForTesting.java
index 6636e1e..dab2a94 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringForTesting.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceDesugaringForTesting.java
@@ -9,7 +9,7 @@
public class InterfaceDesugaringForTesting {
public static String getEmulateLibraryClassNameSuffix() {
- return SyntheticKind.EMULATED_INTERFACE_CLASS.descriptor;
+ return SyntheticKind.EMULATED_INTERFACE_CLASS.getDescriptor();
}
public static String getCompanionClassNameSuffix() {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
index 574f518..097df5d 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
@@ -70,9 +70,9 @@
ClassToFeatureSplitMap classToFeatureSplitMap,
SyntheticItems syntheticItems) {
HasherWrapper hasher = HasherWrapper.murmur3128Hasher();
- hasher.putInt(kind.id);
- if (getKind().isFixedSuffixSynthetic) {
- // Fixed synthetics are non-shareable. Its unique type is used as the hash key.
+ hasher.putInt(kind.getId());
+ if (!getKind().isShareable()) {
+ // Non-shareable synthetics should use its assumed unique type as the hash.
getHolder().getType().hash(hasher);
return hasher.hash();
}
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index fdaaaee..bcf892c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -717,7 +717,7 @@
AppView<?> appView,
Predicate<DexType> reserved) {
DexItemFactory factory = appView.dexItemFactory();
- if (kind.isFixedSuffixSynthetic) {
+ if (kind.isFixedSuffixSynthetic()) {
return SyntheticNaming.createExternalType(kind, externalSyntheticTypePrefix, "", factory);
}
NumberGenerator generator =
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 7740805..887941c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -190,7 +190,7 @@
if (clazz != null) {
assert kind != null;
assert !baseDefinitionFor.apply(type).hasClassResolutionResult()
- || kind.mayOverridesNonProgramType
+ || kind.isMayOverridesNonProgramType()
: "Pending synthetic definition also present in the active program: " + type;
return clazz;
}
@@ -524,7 +524,7 @@
public DexProgramClass getExistingFixedClass(
SyntheticKind kind, DexClass context, AppView<?> appView) {
- assert kind.isFixedSuffixSynthetic;
+ assert kind.isFixedSuffixSynthetic();
SynthesizingContext outerContext = internalGetOuterContext(context, appView);
DexType type = SyntheticNaming.createFixedType(kind, outerContext, appView.dexItemFactory());
DexClass clazz = appView.definitionFor(type);
@@ -553,7 +553,7 @@
AppView<?> appView,
Consumer<SyntheticProgramClassBuilder> fn,
Consumer<DexProgramClass> onCreationConsumer) {
- assert kind.isFixedSuffixSynthetic;
+ assert kind.isFixedSuffixSynthetic();
SynthesizingContext outerContext = internalGetOuterContext(context, appView);
return internalEnsureFixedProgramClass(kind, fn, onCreationConsumer, outerContext, appView);
}
@@ -832,7 +832,7 @@
if (!removedClasses.contains(definition.getHolder().getType())) {
if (definition.isProgramDefinition()) {
committedProgramTypesBuilder.add(definition.getHolder().getType());
- if (definition.getKind().mayOverridesNonProgramType) {
+ if (definition.getKind().isMayOverridesNonProgramType()) {
appBuilder.addProgramClassPotentiallyOverridingNonProgramClass(
definition.asProgramDefinition().getHolder());
} else {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
index d660753..728947e 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -70,8 +70,8 @@
protected ByteVector write(
ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
ByteVector byteVector = new ByteVector();
- assert 0 <= kind.id && kind.id <= Short.MAX_VALUE;
- byteVector.putShort(kind.id);
+ assert 0 <= kind.getId() && kind.getId() <= Short.MAX_VALUE;
+ byteVector.putShort(kind.getId());
return byteVector;
}
}
@@ -122,7 +122,7 @@
return NO_MARKER;
}
assert clazz.annotations().size() == 1;
- if (kind.isSingleSyntheticMethod) {
+ if (kind.isSingleSyntheticMethod()) {
if (!clazz.interfaces.isEmpty()) {
return NO_MARKER;
}
@@ -161,11 +161,11 @@
}
public boolean isSyntheticMethods() {
- return kind != null && kind.isSingleSyntheticMethod;
+ return kind != null && kind.isSingleSyntheticMethod();
}
public boolean isSyntheticClass() {
- return kind != null && !kind.isSingleSyntheticMethod;
+ return kind != null && !kind.isSingleSyntheticMethod();
}
public SyntheticKind getKind() {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index ec8a010..d2daa6c 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -145,22 +145,21 @@
.setOptimizationInfo(optimizationInfo)
.applyIf(!checkAndroidApiLevels, DexEncodedMethod.Builder::disableAndroidApiLevelCheck)
.build();
- assert isValidSyntheticMethod(method, syntheticKind);
+ assert !syntheticKind.isSingleSyntheticMethod()
+ || isValidSingleSyntheticMethod(method, syntheticKind);
return method;
}
/**
- * Predicate for what is a "supported" synthetic method.
+ * Predicate for what is a "supported" single synthetic method.
*
- * <p>This method is used when identifying synthetic methods in the program input and should be as
- * narrow as possible.
- *
- * <p>Methods in fixed suffix synthetics are identified differently (through the class name) and
- * can have different properties.
+ * <p>This method is used when identifying single synthetic methods in the program input and
+ * should be as narrow as possible.
*/
- public static boolean isValidSyntheticMethod(
+ public static boolean isValidSingleSyntheticMethod(
DexEncodedMethod method, SyntheticKind syntheticKind) {
- return isValidSingleSyntheticMethod(method) || syntheticKind.isFixedSuffixSynthetic;
+ assert syntheticKind.isSingleSyntheticMethod();
+ return isValidSingleSyntheticMethod(method);
}
public static boolean isValidSingleSyntheticMethod(DexEncodedMethod method) {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
index d00eb21..2129b9d 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
@@ -11,7 +11,7 @@
import java.util.function.Consumer;
/**
- * Definition of a synthetic method item.
+ * Definition of a single synthetic method item.
*
* <p>This class is internal to the synthetic items collection, thus package-protected.
*/
@@ -24,6 +24,7 @@
SyntheticMethodDefinition(SyntheticKind kind, SynthesizingContext context, ProgramMethod method) {
super(kind, context);
+ assert kind.isSingleSyntheticMethod();
this.method = method;
}
@@ -70,7 +71,7 @@
@Override
public boolean isValid() {
- return SyntheticMethodBuilder.isValidSyntheticMethod(method.getDefinition(), getKind());
+ return SyntheticMethodBuilder.isValidSingleSyntheticMethod(method.getDefinition(), getKind());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
index 657f7d5..0e80d65 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticNaming.java
@@ -9,11 +9,54 @@
import com.android.tools.r8.references.ClassReference;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.utils.DescriptorUtils;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
+import com.android.tools.r8.utils.structural.Equatable;
+import com.android.tools.r8.utils.structural.Ordered;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
public class SyntheticNaming {
+ private static class KindGenerator {
+ private int nextId = 1;
+ private List<SyntheticKind> kinds = new ArrayList<>();
+
+ private int getNextId() {
+ return nextId++;
+ }
+
+ private SyntheticKind register(SyntheticKind kind) {
+ kinds.add(kind);
+ return kind;
+ }
+
+ SyntheticKind forSingleMethod(String descriptor) {
+ return register(new SyntheticMethodKind(getNextId(), descriptor));
+ }
+
+ SyntheticKind forInstanceClass(String descriptor) {
+ return register(new SyntheticClassKind(getNextId(), descriptor));
+ }
+
+ SyntheticKind forFixedClass(String descriptor) {
+ return register(new SyntheticFixedClassKind(getNextId(), descriptor, false, false));
+ }
+
+ SyntheticKind forGlobalClass() {
+ return register(new SyntheticFixedClassKind(getNextId(), "", true, true));
+ }
+
+ SyntheticKind forGlobalClasspathClass() {
+ return register(new SyntheticFixedClassKind(getNextId(), "", false, false));
+ }
+
+ List<SyntheticKind> getAllKinds() {
+ List<SyntheticKind> kinds = this.kinds;
+ this.kinds = null;
+ return kinds;
+ }
+ }
+
/**
* Enumeration of all kinds of synthetic items.
*
@@ -23,95 +66,202 @@
* will be put into any non-minified synthetic name and thus the kind "descriptor" must be a
* distinct for each kind.
*/
- public enum SyntheticKind {
- // Class synthetics.
- ENUM_UNBOXING_LOCAL_UTILITY_CLASS("$EnumUnboxingLocalUtility", 24, false, true),
- ENUM_UNBOXING_SHARED_UTILITY_CLASS("$EnumUnboxingSharedUtility", 25, false, true),
- RECORD_TAG("", 1, false, true, true),
- COMPANION_CLASS("$-CC", 2, false, true),
- EMULATED_INTERFACE_CLASS("$-EL", 3, false, true),
- RETARGET_CLASS("RetargetClass", 20, false, true),
- RETARGET_STUB("", 36, false, true),
- RETARGET_INTERFACE("RetargetInterface", 21, false, true),
- WRAPPER("$Wrapper", 22, false, true),
- VIVIFIED_WRAPPER("$VivifiedWrapper", 23, false, true),
- LAMBDA("Lambda", 4, false),
- INIT_TYPE_ARGUMENT("-IA", 5, false, true),
- HORIZONTAL_INIT_TYPE_ARGUMENT_1(SYNTHETIC_CLASS_SEPARATOR + "IA$1", 6, false, true),
- HORIZONTAL_INIT_TYPE_ARGUMENT_2(SYNTHETIC_CLASS_SEPARATOR + "IA$2", 7, false, true),
- HORIZONTAL_INIT_TYPE_ARGUMENT_3(SYNTHETIC_CLASS_SEPARATOR + "IA$3", 8, false, true),
- NON_FIXED_INIT_TYPE_ARGUMENT("$IA", 35, false),
- // Method synthetics.
- ENUM_UNBOXING_CHECK_NOT_ZERO_METHOD("CheckNotZero", 27, true),
- RECORD_HELPER("Record", 9, true),
- BACKPORT("Backport", 10, true),
- BACKPORT_WITH_FORWARDING("BackportWithForwarding", 34, true),
- STATIC_INTERFACE_CALL("StaticInterfaceCall", 11, true),
- TO_STRING_IF_NOT_NULL("ToStringIfNotNull", 12, true),
- THROW_CCE_IF_NOT_NULL("ThrowCCEIfNotNull", 13, true),
- THROW_IAE("ThrowIAE", 14, true),
- THROW_ICCE("ThrowICCE", 15, true),
- THROW_NSME("ThrowNSME", 16, true),
- TWR_CLOSE_RESOURCE("TwrCloseResource", 17, true),
- SERVICE_LOADER("ServiceLoad", 18, true),
- OUTLINE("Outline", 19, true),
- API_CONVERSION("APIConversion", 26, true),
- API_CONVERSION_PARAMETERS("APIConversionParameters", 28, true),
- EMULATED_INTERFACE_MARKER_CLASS("", 29, false, true, true),
- CONST_DYNAMIC("$Condy", 30, false),
- ENUM_CONVERSION("$EnumConversion", 31, false, true),
- ARRAY_CONVERSION("$ArrayConversion", 37, true, false),
- API_MODEL_OUTLINE("ApiModelOutline", 32, true, false, false),
- API_MODEL_STUB("", 33, false, true, true);
+ public abstract static class SyntheticKind implements Ordered<SyntheticKind> {
+
+ public static final SyntheticKind ENUM_UNBOXING_LOCAL_UTILITY_CLASS,
+ ENUM_UNBOXING_SHARED_UTILITY_CLASS,
+ RECORD_TAG,
+ COMPANION_CLASS,
+ EMULATED_INTERFACE_CLASS,
+ RETARGET_CLASS,
+ RETARGET_STUB,
+ RETARGET_INTERFACE,
+ WRAPPER,
+ VIVIFIED_WRAPPER,
+ LAMBDA,
+ INIT_TYPE_ARGUMENT,
+ HORIZONTAL_INIT_TYPE_ARGUMENT_1,
+ HORIZONTAL_INIT_TYPE_ARGUMENT_2,
+ HORIZONTAL_INIT_TYPE_ARGUMENT_3,
+ NON_FIXED_INIT_TYPE_ARGUMENT,
+ ENUM_UNBOXING_CHECK_NOT_ZERO_METHOD,
+ RECORD_HELPER,
+ BACKPORT,
+ BACKPORT_WITH_FORWARDING,
+ STATIC_INTERFACE_CALL,
+ TO_STRING_IF_NOT_NULL,
+ THROW_CCE_IF_NOT_NULL,
+ THROW_IAE,
+ THROW_ICCE,
+ THROW_NSME,
+ TWR_CLOSE_RESOURCE,
+ SERVICE_LOADER,
+ OUTLINE,
+ API_CONVERSION,
+ API_CONVERSION_PARAMETERS,
+ EMULATED_INTERFACE_MARKER_CLASS,
+ CONST_DYNAMIC,
+ ENUM_CONVERSION,
+ ARRAY_CONVERSION,
+ API_MODEL_OUTLINE,
+ API_MODEL_STUB;
+
+ private static final List<SyntheticKind> ALL_KINDS;
static {
- assert verifyNoOverlappingIds();
+ KindGenerator generator = new KindGenerator();
+ // Global synthetics.
+ RECORD_TAG = generator.forGlobalClass();
+ API_MODEL_STUB = generator.forGlobalClass();
+
+ // Classpath only synthetics in the global type namespace.
+ RETARGET_STUB = generator.forGlobalClasspathClass();
+ EMULATED_INTERFACE_MARKER_CLASS = generator.forGlobalClasspathClass();
+
+ // Fixed suffix synthetics. Each has a hygienic prefix type.
+ ENUM_UNBOXING_LOCAL_UTILITY_CLASS = generator.forFixedClass("$EnumUnboxingLocalUtility");
+ ENUM_UNBOXING_SHARED_UTILITY_CLASS = generator.forFixedClass("$EnumUnboxingSharedUtility");
+ COMPANION_CLASS = generator.forFixedClass("$-CC");
+ EMULATED_INTERFACE_CLASS = generator.forFixedClass("$-EL");
+ RETARGET_CLASS = generator.forFixedClass("RetargetClass");
+ RETARGET_INTERFACE = generator.forFixedClass("RetargetInterface");
+ WRAPPER = generator.forFixedClass("$Wrapper");
+ VIVIFIED_WRAPPER = generator.forFixedClass("$VivifiedWrapper");
+ INIT_TYPE_ARGUMENT = generator.forFixedClass("-IA");
+ HORIZONTAL_INIT_TYPE_ARGUMENT_1 = generator.forFixedClass(SYNTHETIC_CLASS_SEPARATOR + "IA$1");
+ HORIZONTAL_INIT_TYPE_ARGUMENT_2 = generator.forFixedClass(SYNTHETIC_CLASS_SEPARATOR + "IA$2");
+ HORIZONTAL_INIT_TYPE_ARGUMENT_3 = generator.forFixedClass(SYNTHETIC_CLASS_SEPARATOR + "IA$3");
+ ENUM_CONVERSION = generator.forFixedClass("$EnumConversion");
+
+ // Locally generated synthetic classes.
+ LAMBDA = generator.forInstanceClass("Lambda");
+ NON_FIXED_INIT_TYPE_ARGUMENT = generator.forInstanceClass("$IA");
+ CONST_DYNAMIC = generator.forInstanceClass("$Condy");
+
+ // Method synthetics.
+ ENUM_UNBOXING_CHECK_NOT_ZERO_METHOD = generator.forSingleMethod("CheckNotZero");
+ RECORD_HELPER = generator.forSingleMethod("Record");
+ BACKPORT = generator.forSingleMethod("Backport");
+ BACKPORT_WITH_FORWARDING = generator.forSingleMethod("BackportWithForwarding");
+ STATIC_INTERFACE_CALL = generator.forSingleMethod("StaticInterfaceCall");
+ TO_STRING_IF_NOT_NULL = generator.forSingleMethod("ToStringIfNotNull");
+ THROW_CCE_IF_NOT_NULL = generator.forSingleMethod("ThrowCCEIfNotNull");
+ THROW_IAE = generator.forSingleMethod("ThrowIAE");
+ THROW_ICCE = generator.forSingleMethod("ThrowICCE");
+ THROW_NSME = generator.forSingleMethod("ThrowNSME");
+ TWR_CLOSE_RESOURCE = generator.forSingleMethod("TwrCloseResource");
+ SERVICE_LOADER = generator.forSingleMethod("ServiceLoad");
+ OUTLINE = generator.forSingleMethod("Outline");
+ API_CONVERSION = generator.forSingleMethod("APIConversion");
+ API_CONVERSION_PARAMETERS = generator.forSingleMethod("APIConversionParameters");
+ ARRAY_CONVERSION = generator.forSingleMethod("$ArrayConversion");
+ API_MODEL_OUTLINE = generator.forSingleMethod("ApiModelOutline");
+
+ ALL_KINDS = generator.getAllKinds();
}
- public final String descriptor;
- public final int id;
- public final boolean isSingleSyntheticMethod;
- public final boolean isFixedSuffixSynthetic;
- public final boolean mayOverridesNonProgramType;
+ private final int id;
+ private final String descriptor;
- SyntheticKind(String descriptor, int id, boolean isSingleSyntheticMethod) {
- this(descriptor, id, isSingleSyntheticMethod, false);
- }
-
- SyntheticKind(
- String descriptor,
- int id,
- boolean isSingleSyntheticMethod,
- boolean isFixedSuffixSynthetic) {
- this(descriptor, id, isSingleSyntheticMethod, isFixedSuffixSynthetic, false);
- }
-
- SyntheticKind(
- String descriptor,
- int id,
- boolean isSingleSyntheticMethod,
- boolean isFixedSuffixSynthetic,
- boolean mayOverridesNonProgramType) {
- this.descriptor = descriptor;
+ SyntheticKind(int id, String descriptor) {
this.id = id;
- this.isSingleSyntheticMethod = isSingleSyntheticMethod;
- this.isFixedSuffixSynthetic = isFixedSuffixSynthetic;
- this.mayOverridesNonProgramType = mayOverridesNonProgramType;
+ this.descriptor = descriptor;
}
- public boolean allowSyntheticContext() {
- return this == RECORD_TAG;
+ @Override
+ public int compareTo(SyntheticKind other) {
+ return Integer.compare(id, other.getId());
}
- public boolean isGlobal() {
- return isFixedSuffixSynthetic && descriptor.isEmpty();
+ @Override
+ public int hashCode() {
+ return id;
}
- public boolean isShareable() {
- if (isFixedSuffixSynthetic) {
- // Fixed synthetics are non-shareable. Ordered by their unique type.
- return false;
+ @Override
+ public boolean equals(Object o) {
+ return Equatable.equalsImpl(this, o);
+ }
+
+ public static Collection<SyntheticKind> values() {
+ return ALL_KINDS;
+ }
+
+ public static SyntheticKind fromId(int id) {
+ if (0 < id && id <= ALL_KINDS.size()) {
+ return ALL_KINDS.get(id - 1);
}
+ assert false;
+ return null;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public abstract boolean isShareable();
+
+ public abstract boolean isSingleSyntheticMethod();
+
+ public abstract boolean isFixedSuffixSynthetic();
+
+ public abstract boolean isGlobal();
+
+ public abstract boolean isMayOverridesNonProgramType();
+
+ public abstract boolean allowSyntheticContext();
+ }
+
+ private static class SyntheticMethodKind extends SyntheticKind {
+
+ public SyntheticMethodKind(int id, String descriptor) {
+ super(id, descriptor);
+ }
+
+ @Override
+ public boolean isShareable() {
+ // Single methods may always be shared.
+ return true;
+ }
+
+ @Override
+ public boolean isSingleSyntheticMethod() {
+ return true;
+ }
+
+ @Override
+ public boolean isFixedSuffixSynthetic() {
+ return false;
+ }
+
+ @Override
+ public boolean isGlobal() {
+ return false;
+ }
+
+ @Override
+ public boolean isMayOverridesNonProgramType() {
+ return false;
+ }
+
+ @Override
+ public boolean allowSyntheticContext() {
+ return false;
+ }
+ }
+
+ private static class SyntheticClassKind extends SyntheticKind {
+
+ public SyntheticClassKind(int id, String descriptor) {
+ super(id, descriptor);
+ }
+
+ @Override
+ public boolean isShareable() {
if (this == NON_FIXED_INIT_TYPE_ARGUMENT) {
// TODO(b/214901256): Sharing of synthetic classes may lead to duplicate method errors.
return false;
@@ -119,33 +269,70 @@
return true;
}
- public static SyntheticKind fromDescriptor(String descriptor) {
- for (SyntheticKind kind : values()) {
- if (kind.descriptor.equals(descriptor)) {
- return kind;
- }
- }
- return null;
+ @Override
+ public final boolean isSingleSyntheticMethod() {
+ return false;
}
- public static SyntheticKind fromId(int id) {
- for (SyntheticKind kind : values()) {
- if (kind.id == id) {
- return kind;
- }
- }
- return null;
+ @Override
+ public boolean isFixedSuffixSynthetic() {
+ return false;
}
- private static boolean verifyNoOverlappingIds() {
- Int2ReferenceMap<SyntheticKind> idToKind = new Int2ReferenceOpenHashMap<>();
- for (SyntheticKind kind : values()) {
- SyntheticKind kindWithSameId = idToKind.put(kind.id, kind);
- assert kindWithSameId == null
- : "Synthetic kind " + idToKind + " has same id as " + kindWithSameId;
- }
+ @Override
+ public boolean isGlobal() {
+ return false;
+ }
+
+ @Override
+ public boolean isMayOverridesNonProgramType() {
+ return false;
+ }
+
+ @Override
+ public boolean allowSyntheticContext() {
+ return false;
+ }
+ }
+
+ private static class SyntheticFixedClassKind extends SyntheticClassKind {
+ private final boolean mayOverridesNonProgramType;
+ private final boolean allowSyntheticContext;
+
+ private SyntheticFixedClassKind(
+ int id,
+ String descriptor,
+ boolean mayOverridesNonProgramType,
+ boolean allowSyntheticContext) {
+ super(id, descriptor);
+ this.mayOverridesNonProgramType = mayOverridesNonProgramType;
+ this.allowSyntheticContext = allowSyntheticContext;
+ }
+
+ @Override
+ public boolean isShareable() {
+ return false;
+ }
+
+ @Override
+ public boolean isFixedSuffixSynthetic() {
return true;
}
+
+ @Override
+ public boolean isGlobal() {
+ return getDescriptor().isEmpty();
+ }
+
+ @Override
+ public boolean isMayOverridesNonProgramType() {
+ return mayOverridesNonProgramType;
+ }
+
+ @Override
+ public boolean allowSyntheticContext() {
+ return allowSyntheticContext;
+ }
}
private static final String SYNTHETIC_CLASS_SEPARATOR = "$$";
@@ -169,22 +356,22 @@
String binaryName = type.toBinaryName();
int index =
binaryName.lastIndexOf(
- kind.isFixedSuffixSynthetic ? kind.descriptor : SYNTHETIC_CLASS_SEPARATOR);
+ kind.isFixedSuffixSynthetic() ? kind.descriptor : SYNTHETIC_CLASS_SEPARATOR);
if (index < 0) {
throw new Unreachable("Unexpected failure to compute an synthetic prefix");
}
return binaryName.substring(0, index);
}
- public static DexType createFixedType(
+ static DexType createFixedType(
SyntheticKind kind, SynthesizingContext context, DexItemFactory factory) {
- assert kind.isFixedSuffixSynthetic;
+ assert kind.isFixedSuffixSynthetic();
return createType("", kind, context.getSynthesizingContextType(), "", factory);
}
static DexType createInternalType(
SyntheticKind kind, SynthesizingContext context, String id, DexItemFactory factory) {
- assert !kind.isFixedSuffixSynthetic;
+ assert !kind.isFixedSuffixSynthetic();
return createType(
INTERNAL_SYNTHETIC_CLASS_SEPARATOR,
kind,
@@ -195,9 +382,9 @@
static DexType createExternalType(
SyntheticKind kind, String externalSyntheticTypePrefix, String id, DexItemFactory factory) {
- assert kind.isFixedSuffixSynthetic == id.isEmpty();
+ assert kind.isFixedSuffixSynthetic() == id.isEmpty();
return createType(
- kind.isFixedSuffixSynthetic ? "" : EXTERNAL_SYNTHETIC_CLASS_SEPARATOR,
+ kind.isFixedSuffixSynthetic() ? "" : EXTERNAL_SYNTHETIC_CLASS_SEPARATOR,
kind,
externalSyntheticTypePrefix,
id,
@@ -257,14 +444,9 @@
createDescriptor(EXTERNAL_SYNTHETIC_CLASS_SEPARATOR, kind, context.getBinaryName(), id));
}
- public static boolean isInternalStaticInterfaceCall(ClassReference reference) {
- return SyntheticNaming.isSynthetic(
- reference, Phase.INTERNAL, SyntheticKind.STATIC_INTERFACE_CALL);
- }
-
static boolean isSynthetic(ClassReference clazz, Phase phase, SyntheticKind kind) {
String typeName = clazz.getTypeName();
- if (kind.isFixedSuffixSynthetic) {
+ if (kind.isFixedSuffixSynthetic()) {
assert phase == null;
return clazz.getBinaryName().endsWith(kind.descriptor);
}
diff --git a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
index 5977b9a..18fb93b 100644
--- a/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
+++ b/src/test/java/com/android/tools/r8/synthesis/SyntheticItemsTestUtils.java
@@ -78,7 +78,7 @@
if (kind.isGlobal()) {
continue;
}
- if (kind.isFixedSuffixSynthetic) {
+ if (kind.isFixedSuffixSynthetic()) {
if (SyntheticNaming.isSynthetic(reference, null, kind)) {
return true;
}