Disentangle IR conversion from lambda rewriter.
This refactoring is in preparation for moving lambda creation to the
enqueuer. It should lead to no behavioral changes.
Bug: 129458850
Change-Id: Ia06ff7283881dbd9486519a06c85ddf8fc8bf365
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index b3a6d66..6ef43a6 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -219,7 +219,7 @@
options.desugaredLibraryConfiguration.getEmulateLibraryInterface().isEmpty()
? null
: new InterfaceMethodRewriter(appView, this);
- this.lambdaRewriter = new LambdaRewriter(appView, this);
+ this.lambdaRewriter = new LambdaRewriter(appView);
this.desugaredLibraryAPIConverter = new DesugaredLibraryAPIConverter(appView);
this.twrCloseResourceRewriter = null;
this.lambdaMerger = null;
@@ -244,7 +244,7 @@
this.methodOptimizationInfoCollector = null;
return;
}
- this.lambdaRewriter = options.enableDesugaring ? new LambdaRewriter(appView, this) : null;
+ this.lambdaRewriter = options.enableDesugaring ? new LambdaRewriter(appView) : null;
this.interfaceMethodRewriter =
options.isInterfaceMethodDesugaringEnabled()
? new InterfaceMethodRewriter(appView, this)
@@ -402,8 +402,9 @@
private void synthesizeLambdaClasses(Builder<?> builder, ExecutorService executorService)
throws ExecutionException {
if (lambdaRewriter != null) {
- lambdaRewriter.adjustAccessibility();
- lambdaRewriter.synthesizeLambdaClasses(builder, executorService);
+ lambdaRewriter.adjustAccessibility(this);
+ lambdaRewriter.synthesizeLambdaClasses(builder);
+ lambdaRewriter.optimizeSynthesizedClasses(this, executorService);
}
}
@@ -814,7 +815,7 @@
if (lambdaRewriter != null) {
lambdaRewriter.synthesizeLambdaClassesForWave(
- wave, executorService, delayedOptimizationFeedback, lensCodeRewriter);
+ wave, executorService, delayedOptimizationFeedback, lensCodeRewriter, this);
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index ce77849..cf9eca4 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -27,6 +27,7 @@
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Invoke.Type;
+import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.synthetic.SynthesizedCode;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.utils.InternalOptions;
@@ -83,7 +84,7 @@
this.type = lambdaClassType;
this.descriptor = descriptor;
- DexItemFactory factory = rewriter.factory;
+ DexItemFactory factory = rewriter.getFactory();
DexProto constructorProto = factory.createProto(
factory.voidType, descriptor.captures.values);
this.constructor = factory.createMethod(
@@ -103,6 +104,11 @@
// Generate unique lambda class type for lambda descriptor and instantiation point context.
static DexType createLambdaClassType(
LambdaRewriter rewriter, DexType accessedFrom, LambdaDescriptor match) {
+ return createLambdaClassType(rewriter.getFactory(), accessedFrom, match);
+ }
+
+ public static DexType createLambdaClassType(
+ DexItemFactory factory, DexType accessedFrom, LambdaDescriptor match) {
StringBuilder lambdaClassDescriptor = new StringBuilder("L");
// We always create lambda class in the same package where it is referenced.
@@ -123,7 +129,7 @@
// Add unique lambda descriptor id
lambdaClassDescriptor.append(match.uniqueId).append(';');
- return rewriter.factory.createType(lambdaClassDescriptor.toString());
+ return factory.createType(lambdaClassDescriptor.toString());
}
final DexProgramClass getOrCreateLambdaClass() {
@@ -132,7 +138,7 @@
private DexProgramClass synthesizeLambdaClass() {
DexMethod mainMethod =
- rewriter.factory.createMethod(type, descriptor.erasedProto, descriptor.name);
+ rewriter.getFactory().createMethod(type, descriptor.erasedProto, descriptor.name);
DexProgramClass clazz =
new DexProgramClass(
@@ -143,9 +149,9 @@
// classloader (package private access is not allowed across classloaders, b/72538146).
ClassAccessFlags.fromDexAccessFlags(
Constants.ACC_FINAL | Constants.ACC_SYNTHETIC | Constants.ACC_PUBLIC),
- rewriter.factory.objectType,
+ rewriter.getFactory().objectType,
buildInterfaces(),
- rewriter.factory.createString("lambda"),
+ rewriter.getFactory().createString("lambda"),
null,
Collections.emptyList(),
null,
@@ -155,9 +161,9 @@
synthesizeInstanceFields(),
synthesizeDirectMethods(),
synthesizeVirtualMethods(mainMethod),
- rewriter.factory.getSkipNameValidationForTesting(),
+ rewriter.getFactory().getSkipNameValidationForTesting(),
LambdaClass::computeChecksumForSynthesizedClass);
- rewriter.converter.appView.appInfo().addSynthesizedClass(clazz);
+ rewriter.getAppInfo().addSynthesizedClass(clazz);
// The method addSynthesizedFrom() may be called concurrently. To avoid a Concurrent-
// ModificationException we must use synchronization.
@@ -186,8 +192,12 @@
}
final DexField getCaptureField(int index) {
- return rewriter.factory.createField(this.type,
- descriptor.captures.values[index], rewriter.factory.createString("f$" + index));
+ return rewriter
+ .getFactory()
+ .createField(
+ this.type,
+ descriptor.captures.values[index],
+ rewriter.getFactory().createString("f$" + index));
}
final boolean isStateless() {
@@ -222,7 +232,8 @@
// Synthesize bridge methods.
for (DexProto bridgeProto : descriptor.bridges) {
- DexMethod bridgeMethod = rewriter.factory.createMethod(type, bridgeProto, descriptor.name);
+ DexMethod bridgeMethod =
+ rewriter.getFactory().createMethod(type, bridgeProto, descriptor.name);
methods[index++] =
new DexEncodedMethod(
bridgeMethod,
@@ -363,26 +374,30 @@
// If the lambda$ method is an instance-private method on an interface we convert it into a
// public static method as it will be placed on the companion class.
if (implHandle.type.isInvokeDirect()
- && rewriter.converter.appView.definitionFor(implMethod.holder).isInterface()) {
+ && rewriter.getAppView().definitionFor(implMethod.holder).isInterface()) {
DexProto implProto = implMethod.proto;
DexType[] implParams = implProto.parameters.values;
DexType[] newParams = new DexType[implParams.length + 1];
newParams[0] = implMethod.holder;
System.arraycopy(implParams, 0, newParams, 1, implParams.length);
- DexProto newProto = rewriter.factory.createProto(implProto.returnType, newParams);
+ DexProto newProto = rewriter.getFactory().createProto(implProto.returnType, newParams);
return new InterfaceLambdaImplTarget(
- rewriter.factory.createMethod(implMethod.holder, newProto, implMethod.name));
+ rewriter.getFactory().createMethod(implMethod.holder, newProto, implMethod.name));
} else {
// Otherwise we need to ensure the method can be reached publicly by virtual dispatch.
// To avoid potential conflicts on the name of the lambda method once dispatch becomes virtual
// we add the method-holder name as suffix to the lambda-method name.
return new InstanceLambdaImplTarget(
- rewriter.factory.createMethod(
- implMethod.holder,
- implMethod.proto,
- rewriter.factory.createString(
- implMethod.name.toString() + "$" + implMethod.holder.getName())));
+ rewriter
+ .getFactory()
+ .createMethod(
+ implMethod.holder,
+ implMethod.proto,
+ rewriter
+ .getFactory()
+ .createString(
+ implMethod.name.toString() + "$" + implMethod.holder.getName())));
}
}
@@ -408,9 +423,12 @@
DexType[] accessorParams = new DexType[1 + implParams.length];
accessorParams[0] = descriptor.getImplReceiverType();
System.arraycopy(implParams, 0, accessorParams, 1, implParams.length);
- DexProto accessorProto = rewriter.factory.createProto(implProto.returnType, accessorParams);
- DexMethod accessorMethod = rewriter.factory.createMethod(
- accessedFrom, accessorProto, generateUniqueLambdaMethodName());
+ DexProto accessorProto =
+ rewriter.getFactory().createProto(implProto.returnType, accessorParams);
+ DexMethod accessorMethod =
+ rewriter
+ .getFactory()
+ .createMethod(accessedFrom, accessorProto, generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
}
@@ -427,8 +445,13 @@
// We need to generate an accessor method in `accessedFrom` class/interface
// for accessing the original static impl-method. The accessor method will be
// static, package private with exactly same signature and the original method.
- DexMethod accessorMethod = rewriter.factory.createMethod(accessedFrom,
- descriptor.implHandle.asMethod().proto, generateUniqueLambdaMethodName());
+ DexMethod accessorMethod =
+ rewriter
+ .getFactory()
+ .createMethod(
+ accessedFrom,
+ descriptor.implHandle.asMethod().proto,
+ generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
}
@@ -449,10 +472,12 @@
// and return the newly created instance.
DexMethod implMethod = implHandle.asMethod();
DexType returnType = implMethod.holder;
- DexProto accessorProto = rewriter.factory.createProto(
- returnType, implMethod.proto.parameters.values);
- DexMethod accessorMethod = rewriter.factory.createMethod(accessedFrom,
- accessorProto, generateUniqueLambdaMethodName());
+ DexProto accessorProto =
+ rewriter.getFactory().createProto(returnType, implMethod.proto.parameters.values);
+ DexMethod accessorMethod =
+ rewriter
+ .getFactory()
+ .createMethod(accessedFrom, accessorProto, generateUniqueLambdaMethodName());
return new ClassMethodWithAccessorTarget(accessorMethod);
}
@@ -464,8 +489,9 @@
}
private DexString generateUniqueLambdaMethodName() {
- return rewriter.factory.createString(
- LambdaRewriter.EXPECTED_LAMBDA_METHOD_PREFIX + descriptor.uniqueId);
+ return rewriter
+ .getFactory()
+ .createString(LambdaRewriter.EXPECTED_LAMBDA_METHOD_PREFIX + descriptor.uniqueId);
}
// Represents information about the method lambda class need to delegate the call to. It may
@@ -484,18 +510,18 @@
}
// Ensure access of the referenced symbol(s).
- abstract void ensureAccessibility();
+ abstract void ensureAccessibility(IRConverter converter);
DexClass definitionFor(DexType type) {
- return rewriter.converter.appView.appInfo().app().definitionFor(type);
+ return rewriter.getAppInfo().app().definitionFor(type);
}
DexProgramClass programDefinitionFor(DexType type) {
- return rewriter.converter.appView.appInfo().app().programDefinitionFor(type);
+ return rewriter.getAppInfo().app().programDefinitionFor(type);
}
boolean holderIsInterface() {
- InternalOptions options = rewriter.converter.appView.options();
+ InternalOptions options = rewriter.getAppView().options();
if (!options.isGeneratingClassFiles()) {
// When generating dex the value of this flag on invokes does not matter (unused).
// We cannot know if definitionFor(implMethod.holder) is null or not in that case,
@@ -527,7 +553,7 @@
}
@Override
- void ensureAccessibility() {}
+ void ensureAccessibility(IRConverter converter) {}
}
// Used for static private lambda$ methods. Only needs access relaxation.
@@ -538,7 +564,7 @@
}
@Override
- void ensureAccessibility() {
+ void ensureAccessibility(IRConverter converter) {
// We already found the static method to be called, just relax its accessibility.
assert descriptor.getAccessibility() != null;
descriptor.getAccessibility().unsetPrivate();
@@ -558,7 +584,7 @@
}
@Override
- void ensureAccessibility() {
+ void ensureAccessibility(IRConverter converter) {
// For all instantiation points for which the compiler creates lambda$
// methods, it creates these methods in the same class/interface.
DexMethod implMethod = descriptor.implHandle.asMethod();
@@ -587,7 +613,7 @@
rewriter.methodMapping.put(encodedMethod.method, callTarget);
DexEncodedMethod.setDebugInfoWithFakeThisParameter(
- newMethod.getCode(), callTarget.getArity(), rewriter.converter.appView);
+ newMethod.getCode(), callTarget.getArity(), rewriter.getAppView());
implMethodHolder.setDirectMethod(i, newMethod);
return;
}
@@ -605,7 +631,7 @@
}
@Override
- void ensureAccessibility() {
+ void ensureAccessibility(IRConverter converter) {
// For all instantiation points for which the compiler creates lambda$
// methods, it creates these methods in the same class/interface.
DexMethod implMethod = descriptor.implHandle.asMethod();
@@ -647,7 +673,7 @@
}
@Override
- void ensureAccessibility() {
+ void ensureAccessibility(IRConverter converter) {
// Create a static accessor with proper accessibility.
DexProgramClass accessorClass = programDefinitionFor(callTarget.holder);
assert accessorClass != null;
@@ -673,7 +699,7 @@
accessorClass.appendDirectMethod(accessorEncodedMethod);
}
- rewriter.converter.optimizeSynthesizedMethod(accessorEncodedMethod);
+ converter.optimizeSynthesizedMethod(accessorEncodedMethod);
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
index ed49900..92d04f0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaRewriter.java
@@ -66,8 +66,6 @@
private static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
private final AppView<?> appView;
- final IRConverter converter;
- final DexItemFactory factory;
final DexMethod objectInitMethod;
@@ -93,24 +91,34 @@
return clazz.getName().startsWith(LAMBDA_CLASS_NAME_PREFIX);
}
- public LambdaRewriter(AppView<?> appView, IRConverter converter) {
- assert converter != null;
+ public LambdaRewriter(AppView<?> appView) {
this.appView = appView;
- this.converter = converter;
- this.factory = appView.dexItemFactory();
+ this.constructorName = getFactory().createString(Constants.INSTANCE_INITIALIZER_NAME);
+ DexProto initProto = getFactory().createProto(getFactory().voidType);
+ this.objectInitMethod =
+ getFactory().createMethod(getFactory().objectType, initProto, constructorName);
+ this.classConstructorName = getFactory().createString(Constants.CLASS_INITIALIZER_NAME);
+ this.instanceFieldName = getFactory().createString(LAMBDA_INSTANCE_FIELD_NAME);
+ }
- this.constructorName = factory.createString(Constants.INSTANCE_INITIALIZER_NAME);
- DexProto initProto = factory.createProto(factory.voidType);
- this.objectInitMethod = factory.createMethod(factory.objectType, initProto, constructorName);
- this.classConstructorName = factory.createString(Constants.CLASS_INITIALIZER_NAME);
- this.instanceFieldName = factory.createString(LAMBDA_INSTANCE_FIELD_NAME);
+ public AppView<?> getAppView() {
+ return appView;
+ }
+
+ public AppInfo getAppInfo() {
+ return getAppView().appInfo();
+ }
+
+ public DexItemFactory getFactory() {
+ return getAppView().dexItemFactory();
}
public void synthesizeLambdaClassesForWave(
Collection<DexEncodedMethod> wave,
ExecutorService executorService,
OptimizationFeedbackDelayed feedback,
- LensCodeRewriter lensCodeRewriter)
+ LensCodeRewriter lensCodeRewriter,
+ IRConverter converter)
throws ExecutionException {
Set<DexProgramClass> synthesizedLambdaClasses = Sets.newIdentityHashSet();
for (DexEncodedMethod method : wave) {
@@ -133,7 +141,7 @@
}
}
- AppView<AppInfoWithLiveness> appViewWithLiveness = appView.withLiveness();
+ AppView<AppInfoWithLiveness> appViewWithLiveness = getAppView().withLiveness();
appViewWithLiveness.setAppInfo(
appViewWithLiveness.appInfo().withStaticFieldWrites(writesWithContexts));
@@ -160,7 +168,7 @@
// application (and, in particular, the class hierarchy) during wave processing.
code.registerCodeReferences(
method,
- new DefaultUseRegistry(appView.dexItemFactory()) {
+ new DefaultUseRegistry(getFactory()) {
@Override
public void registerCallSite(DexCallSite callSite) {
@@ -199,7 +207,7 @@
// We have a descriptor, get the lambda class. In D8, we synthesize the lambda classes
// during IR processing, and therefore we may need to create it now.
LambdaClass lambdaClass =
- appView.enableWholeProgramOptimizations()
+ getAppView().enableWholeProgramOptimizations()
? getKnownLambdaClass(descriptor, currentType)
: getOrCreateLambdaClass(descriptor, currentType);
assert lambdaClass != null;
@@ -212,7 +220,7 @@
}
}
if (!affectedValues.isEmpty()) {
- new TypeAnalysis(appView).narrowing(affectedValues);
+ new TypeAnalysis(getAppView()).narrowing(affectedValues);
}
assert code.isConsistentSSA();
}
@@ -227,7 +235,7 @@
for (int i = 0; i < methodCount; i++) {
DexEncodedMethod encoded = directMethods.get(i);
DexMethod method = encoded.method;
- if (method.isLambdaDeserializeMethod(appView.dexItemFactory())) {
+ if (method.isLambdaDeserializeMethod(getFactory())) {
assert encoded.accessFlags.isStatic();
assert encoded.accessFlags.isSynthetic();
clazz.removeDirectMethod(i);
@@ -242,17 +250,18 @@
}
/** Adjust accessibility of referenced application symbols or creates necessary accessors. */
- public void adjustAccessibility() {
+ public void adjustAccessibility(IRConverter converter) {
// For each lambda class perform necessary adjustment of the
// referenced symbols to make them accessible. This can result in
// method access relaxation or creation of accessor method.
for (LambdaClass lambdaClass : knownLambdaClasses.values()) {
// This call may cause methodMapping to be updated.
- lambdaClass.target.ensureAccessibility();
+ lambdaClass.target.ensureAccessibility(converter);
}
- if (appView.enableWholeProgramOptimizations() && !methodMapping.isEmpty()) {
- appView.setGraphLense(
- new LambdaRewriterGraphLense(methodMapping, appView.graphLense(), factory));
+ if (getAppView().enableWholeProgramOptimizations() && !methodMapping.isEmpty()) {
+ getAppView()
+ .setGraphLense(
+ new LambdaRewriterGraphLense(methodMapping, getAppView().graphLense(), getFactory()));
}
}
@@ -266,14 +275,16 @@
}
/** Generates lambda classes and adds them to the builder. */
- public void synthesizeLambdaClasses(Builder<?> builder, ExecutorService executorService)
- throws ExecutionException {
- AppInfo appInfo = appView.appInfo();
+ public void synthesizeLambdaClasses(Builder<?> builder) {
for (LambdaClass lambdaClass : knownLambdaClasses.values()) {
DexProgramClass synthesizedClass = lambdaClass.getOrCreateLambdaClass();
- appInfo.addSynthesizedClass(synthesizedClass);
+ getAppInfo().addSynthesizedClass(synthesizedClass);
builder.addSynthesizedClass(synthesizedClass, lambdaClass.addToMainDexList.get());
}
+ }
+
+ public void optimizeSynthesizedClasses(IRConverter converter, ExecutorService executorService)
+ throws ExecutionException {
converter.optimizeSynthesizedClasses(
knownLambdaClasses.values().stream()
.map(LambdaClass::getOrCreateLambdaClass)
@@ -299,12 +310,11 @@
LambdaDescriptor descriptor = getKnown(knownCallSites, callSite);
return descriptor != null
? descriptor
- : putIfAbsent(
- knownCallSites, callSite, LambdaDescriptor.infer(callSite, appView.appInfo()));
+ : putIfAbsent(knownCallSites, callSite, LambdaDescriptor.infer(callSite, getAppInfo()));
}
private boolean isInMainDexList(DexType type) {
- return appView.appInfo().isInMainDexList(type);
+ return getAppInfo().isInMainDexList(type);
}
// Returns a lambda class corresponding to the lambda descriptor and context,
@@ -319,11 +329,11 @@
knownLambdaClasses,
lambdaClassType,
new LambdaClass(this, accessedFrom, lambdaClassType, descriptor));
- if (appView.options().isDesugaredLibraryCompilation()) {
- DexType rewrittenType = appView.rewritePrefix.rewrittenType(accessedFrom);
+ if (getAppView().options().isDesugaredLibraryCompilation()) {
+ DexType rewrittenType = getAppView().rewritePrefix.rewrittenType(accessedFrom);
if (rewrittenType == null) {
rewrittenType =
- appView
+ getAppView()
.options()
.desugaredLibraryConfiguration
.getEmulateLibraryInterface()
@@ -334,7 +344,7 @@
}
}
}
- lambdaClass.addSynthesizedFrom(appView.definitionFor(accessedFrom).asProgramClass());
+ lambdaClass.addSynthesizedFrom(getAppView().definitionFor(accessedFrom).asProgramClass());
if (isInMainDexList(accessedFrom)) {
lambdaClass.addToMainDexList.set(true);
}
@@ -353,11 +363,14 @@
String rewrittenString = rewritten.toString();
String actualRewrittenPrefix = rewrittenString.substring(0, rewrittenString.lastIndexOf('.'));
assert javaName.startsWith(actualPrefix);
- appView.rewritePrefix.rewriteType(
- lambdaClassType,
- factory.createType(
- DescriptorUtils.javaTypeToDescriptor(
- actualRewrittenPrefix + javaName.substring(actualPrefix.length()))));
+ getAppView()
+ .rewritePrefix
+ .rewriteType(
+ lambdaClassType,
+ getFactory()
+ .createType(
+ DescriptorUtils.javaTypeToDescriptor(
+ actualRewrittenPrefix + javaName.substring(actualPrefix.length()))));
}
private static <K, V> V getKnown(Map<K, V> map, K key) {
@@ -397,7 +410,8 @@
// The out value might be empty in case it was optimized out.
lambdaInstanceValue =
code.createValue(
- TypeLatticeElement.fromDexType(lambdaClass.type, Nullability.maybeNull(), appView));
+ TypeLatticeElement.fromDexType(
+ lambdaClass.type, Nullability.maybeNull(), getAppView()));
} else {
affectedValues.add(lambdaInstanceValue);
}
@@ -450,6 +464,6 @@
BasicBlock currentBlock = newInstance.getBlock();
BasicBlock nextBlock = instructions.split(code, blocks);
assert !instructions.hasNext();
- nextBlock.copyCatchHandlers(code, blocks, currentBlock, appView.options());
+ nextBlock.copyCatchHandlers(code, blocks, currentBlock, getAppView().options());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaSynthesizedCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaSynthesizedCode.java
index 2565687..7e50b88 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaSynthesizedCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaSynthesizedCode.java
@@ -21,7 +21,7 @@
}
final DexItemFactory dexItemFactory() {
- return lambda.rewriter.factory;
+ return lambda.rewriter.getFactory();
}
final LambdaDescriptor descriptor() {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
index 786b23c..7677cee 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/SynthesizedLambdaSourceCode.java
@@ -40,7 +40,7 @@
}
final DexItemFactory factory() {
- return lambda.rewriter.factory;
+ return lambda.rewriter.getFactory();
}
final int enforceParameterType(int register, DexType paramType, DexType enforcedType) {