[ApiModel] Add contexts for stubs
Bug: b/230445931
Change-Id: I4774e46029c004bc4fb323907acfdaa5678f0ee5
diff --git a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
index 0f0f7e9..315a68d 100644
--- a/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
+++ b/src/main/java/com/android/tools/r8/androidapi/ApiReferenceStubber.java
@@ -4,7 +4,10 @@
package com.android.tools.r8.androidapi;
+import static com.android.tools.r8.utils.MapUtils.ignoreKey;
+
import com.android.tools.r8.errors.MissingGlobalSyntheticsConsumerDiagnostic;
+import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DefaultInstanceInitializerCode;
@@ -17,6 +20,7 @@
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.graph.ProgramDefinition;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.graph.ThrowExceptionCode;
import com.android.tools.r8.graph.UseRegistry;
@@ -99,14 +103,16 @@
private void checkReferenceToLibraryClass(DexReference reference) {
DexType rewrittenType = appView.graphLens().lookupType(reference.getContextType());
- findReferencedLibraryClasses(rewrittenType);
+ findReferencedLibraryClasses(rewrittenType, getContext().getContextClass());
if (reference.isDexMethod()) {
- findReferencedLibraryMethod(reference.asDexMethod());
+ findReferencedLibraryMethod(reference.asDexMethod(), getContext().getContextClass());
}
}
}
private final AppView<?> appView;
+ private final Map<DexLibraryClass, Set<ProgramDefinition>> referencingContexts =
+ new ConcurrentHashMap<>();
private final Map<DexLibraryClass, Set<DexMethod>> libraryClassesToMock =
new ConcurrentHashMap<>();
private final Set<DexType> seenTypes = Sets.newConcurrentHashSet();
@@ -159,13 +165,13 @@
.isSyntheticOfKind(clazz.getType(), kinds -> kinds.API_MODEL_OUTLINE)) {
return;
}
- findReferencedLibraryClasses(clazz.type);
+ findReferencedLibraryClasses(clazz.type, clazz);
clazz.forEachProgramMethodMatching(
DexEncodedMethod::hasCode,
method -> method.registerCodeReferences(new ReferencesToApiLevelUseRegistry(method)));
}
- private void findReferencedLibraryMethod(DexMethod method) {
+ private void findReferencedLibraryMethod(DexMethod method, DexProgramClass context) {
DexType holderType = method.getHolderType();
if (!holderType.isClassType()) {
return;
@@ -187,13 +193,16 @@
}
if (holderApiLevel.isGreaterThan(appView.computedMinApiLevel())) {
libraryClassesToMock
- .computeIfAbsent(clazz.asLibraryClass(), ignored -> Sets.newConcurrentHashSet())
+ .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
.add(method);
+ referencingContexts
+ .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
+ .add(context);
}
}
}
- private void findReferencedLibraryClasses(DexType type) {
+ private void findReferencedLibraryClasses(DexType type, DexProgramClass context) {
if (!type.isClassType()) {
return;
}
@@ -210,7 +219,10 @@
if (androidApiLevel.isGreaterThan(appView.computedMinApiLevel())
&& !androidApiLevel.isUnknownApiLevel()) {
libraryClassesToMock.computeIfAbsent(
- clazz.asLibraryClass(), ignored -> Sets.newConcurrentHashSet());
+ clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet));
+ referencingContexts
+ .computeIfAbsent(clazz.asLibraryClass(), ignoreKey(Sets::newConcurrentHashSet))
+ .add(context);
}
}
workList.addIfNotSeen(clazz.allImmediateSupertypes());
@@ -231,6 +243,10 @@
.isSupported(libraryClass.getType())) {
return;
}
+ Set<ProgramDefinition> contexts = referencingContexts.get(libraryClass);
+ if (contexts == null) {
+ throw new Unreachable("Attempt to create a global synthetic with no contexts");
+ }
appView
.appInfo()
.getSyntheticItems()
@@ -238,6 +254,7 @@
() -> new MissingGlobalSyntheticsConsumerDiagnostic("API stubbing"),
kinds -> kinds.API_MODEL_STUB,
libraryClass.getType(),
+ contexts,
appView,
classBuilder -> {
classBuilder