Delete dead lambda desugaring code
Bug: 129458850
Change-Id: I6aabef1fe0c2e83357f473e88e053675513e48cf
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 45be243..9f5a62a 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
@@ -296,7 +296,7 @@
: null;
this.lambdaMerger =
options.enableLambdaMerging ? new LambdaMerger(appViewWithLiveness) : null;
- this.lensCodeRewriter = new LensCodeRewriter(appViewWithLiveness, lambdaRewriter);
+ this.lensCodeRewriter = new LensCodeRewriter(appViewWithLiveness);
this.inliner =
new Inliner(appViewWithLiveness, mainDexClasses, lambdaMerger, lensCodeRewriter);
this.outliner = new Outliner(appViewWithLiveness);
@@ -1111,10 +1111,6 @@
lensCodeRewriter.rewrite(code, method);
} else {
assert appView.graphLense().isIdentityLense();
- if (lambdaRewriter != null && options.testing.desugarLambdasThroughLensCodeRewriter()) {
- lambdaRewriter.desugarLambdas(method, code);
- assert code.isConsistentSSA();
- }
}
}
@@ -1277,9 +1273,7 @@
stringConcatRewriter.desugarStringConcats(method.method, code);
- if (options.testing.desugarLambdasThroughLensCodeRewriter()) {
- assert !options.enableDesugaring || lambdaRewriter.verifyNoLambdasToDesugar(code);
- } else if (lambdaRewriter != null) {
+ if (lambdaRewriter != null) {
lambdaRewriter.desugarLambdas(method, code);
assert code.isConsistentSSA();
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 21f800c..bf556c8 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -60,7 +60,6 @@
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.desugar.LambdaRewriter;
import com.android.tools.r8.logging.Log;
import com.google.common.collect.Sets;
import java.util.ArrayList;
@@ -77,11 +76,9 @@
private final AppView<? extends AppInfoWithSubtyping> appView;
private final Map<DexProto, DexProto> protoFixupCache = new ConcurrentHashMap<>();
- private final LambdaRewriter lambdaRewriter;
- LensCodeRewriter(AppView<? extends AppInfoWithSubtyping> appView, LambdaRewriter lambdaRewriter) {
+ LensCodeRewriter(AppView<? extends AppInfoWithSubtyping> appView) {
this.appView = appView;
- this.lambdaRewriter = lambdaRewriter;
}
private Value makeOutValue(Instruction insn, IRCode code) {
@@ -128,13 +125,6 @@
affectedPhis.addAll(newOutValue.uniquePhiUsers());
}
}
- if (lambdaRewriter != null
- && appView.options().testing.desugarLambdasThroughLensCodeRewriter()) {
- Instruction previous = iterator.peekPrevious();
- assert previous.isInvokeCustom();
- lambdaRewriter.desugarLambda(
- method.method.holder, iterator, previous.asInvokeCustom(), code);
- }
} else if (current.isConstMethodHandle()) {
DexMethodHandle handle = current.asConstMethodHandle().getValue();
DexMethodHandle newHandle = rewriteDexMethodHandle(
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 9998c94..025ecb0 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
@@ -62,7 +62,6 @@
final LambdaDescriptor descriptor;
final DexMethod constructor;
final DexMethod classConstructor;
- final DexMethod createInstanceMethod;
final DexField lambdaField;
final Target target;
final AtomicBoolean addToMainDexList = new AtomicBoolean(false);
@@ -98,13 +97,6 @@
!stateless
? null
: factory.createField(lambdaClassType, lambdaClassType, rewriter.instanceFieldName);
- this.createInstanceMethod =
- stateless
- ? null
- : factory.createMethod(
- lambdaClassType,
- factory.createProto(lambdaClassType, descriptor.captures.values),
- rewriter.createInstanceMethodName);
}
// Generate unique lambda class type for lambda descriptor and instantiation point context.
@@ -137,11 +129,6 @@
return lazyDexClass.get();
}
- DexMethod getCreateInstanceMethod() {
- assert createInstanceMethod != null;
- return createInstanceMethod;
- }
-
private DexProgramClass synthesizeLambdaClass() {
DexMethod mainMethod =
rewriter.factory.createMethod(type, descriptor.erasedProto, descriptor.name);
@@ -261,10 +248,7 @@
// Synthesize direct methods.
private DexEncodedMethod[] synthesizeDirectMethods() {
boolean stateless = isStateless();
- boolean enableStatefulLambdaCreateInstanceMethod =
- rewriter.converter.appView.options().testing.enableStatefulLambdaCreateInstanceMethod;
- DexEncodedMethod[] methods =
- new DexEncodedMethod[(stateless || enableStatefulLambdaCreateInstanceMethod) ? 2 : 1];
+ DexEncodedMethod[] methods = new DexEncodedMethod[stateless ? 2 : 1];
// Constructor.
methods[0] =
@@ -290,16 +274,6 @@
ParameterAnnotationsList.empty(),
new SynthesizedCode(
callerPosition -> new LambdaClassConstructorSourceCode(this, callerPosition)));
- } else if (enableStatefulLambdaCreateInstanceMethod) {
- methods[1] =
- new DexEncodedMethod(
- createInstanceMethod,
- MethodAccessFlags.fromSharedAccessFlags(
- Constants.ACC_SYNTHETIC | Constants.ACC_STATIC | Constants.ACC_PUBLIC, false),
- DexAnnotationSet.empty(),
- ParameterAnnotationsList.empty(),
- new SynthesizedCode(
- callerPosition -> new LambdaCreateInstanceSourceCode(this, callerPosition)));
}
return methods;
}
@@ -518,7 +492,7 @@
}
// Ensure access of the referenced symbol(s).
- abstract boolean ensureAccessibility();
+ abstract void ensureAccessibility();
DexClass definitionFor(DexType type) {
return rewriter.converter.appView.appInfo().app().definitionFor(type);
@@ -563,9 +537,7 @@
}
@Override
- boolean ensureAccessibility() {
- return true;
- }
+ void ensureAccessibility() {}
}
// Used for static private lambda$ methods. Only needs access relaxation.
@@ -576,7 +548,7 @@
}
@Override
- boolean ensureAccessibility() {
+ void ensureAccessibility() {
// We already found the static method to be called, just relax its accessibility.
assert descriptor.getAccessibility() != null;
descriptor.getAccessibility().unsetPrivate();
@@ -584,7 +556,6 @@
if (implMethodHolder.isInterface()) {
descriptor.getAccessibility().setPublic();
}
- return true;
}
}
@@ -597,7 +568,7 @@
}
@Override
- boolean ensureAccessibility() {
+ void ensureAccessibility() {
// 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();
@@ -628,12 +599,11 @@
DexEncodedMethod.setDebugInfoWithFakeThisParameter(
newMethod.getCode(), callTarget.getArity(), rewriter.converter.appView);
implMethodHolder.setDirectMethod(i, newMethod);
- return true;
+ return;
}
}
assert false
: "Unexpected failure to find direct lambda target for: " + implMethod.qualifiedName();
- return false;
}
}
@@ -645,7 +615,7 @@
}
@Override
- boolean ensureAccessibility() {
+ void ensureAccessibility() {
// 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();
@@ -672,10 +642,9 @@
// Move the method from the direct methods to the virtual methods set.
implMethodHolder.removeDirectMethod(i);
implMethodHolder.appendVirtualMethod(newMethod);
- return true;
+ return;
}
}
- return false;
}
}
@@ -688,7 +657,7 @@
}
@Override
- boolean ensureAccessibility() {
+ void ensureAccessibility() {
// Create a static accessor with proper accessibility.
DexProgramClass accessorClass = programDefinitionFor(callTarget.holder);
assert accessorClass != null;
@@ -715,7 +684,6 @@
}
rewriter.converter.optimizeSynthesizedMethod(accessorEncodedMethod);
- return true;
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaCreateInstanceSourceCode.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaCreateInstanceSourceCode.java
deleted file mode 100644
index eacad03..0000000
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaCreateInstanceSourceCode.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2019, 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.ir.desugar;
-
-import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.ValueType;
-import java.util.ArrayList;
-import java.util.List;
-
-// Source code for the static method in a stateful lambda class which creates and initializes
-// a new instance.
-final class LambdaCreateInstanceSourceCode extends SynthesizedLambdaSourceCode {
-
- LambdaCreateInstanceSourceCode(LambdaClass lambda, Position callerPosition) {
- super(lambda, lambda.createInstanceMethod, callerPosition, null);
- }
-
- @Override
- protected void prepareInstructions() {
- // Create and initialize an instance.
- int instance = nextRegister(ValueType.OBJECT);
- add(builder -> builder.addNewInstance(instance, lambda.type));
- int paramCount = proto.parameters.values.length;
- List<ValueType> types = new ArrayList<>(paramCount + 1);
- List<Integer> registers = new ArrayList<>(paramCount + 1);
- types.add(ValueType.OBJECT);
- registers.add(instance);
- for (int i = 0; i < paramCount; ++i) {
- types.add(ValueType.fromDexType(proto.parameters.values[i]));
- registers.add(getParamRegister(i));
- }
- add(
- builder ->
- builder.addInvoke(
- Invoke.Type.DIRECT,
- lambda.constructor,
- lambda.constructor.proto,
- types,
- registers,
- false /* isInterface */));
- add(builder -> builder.addReturn(instance));
- }
-}
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 8cc6d15..06884b8 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
@@ -27,7 +27,6 @@
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.InvokeCustom;
import com.android.tools.r8.ir.code.InvokeDirect;
-import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.Value;
@@ -59,8 +58,7 @@
public static final String LAMBDA_CLASS_NAME_PREFIX = "-$$Lambda$";
public static final String LAMBDA_GROUP_CLASS_NAME_PREFIX = "-$$LambdaGroup$";
static final String EXPECTED_LAMBDA_METHOD_PREFIX = "lambda$";
- static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
- static final String LAMBDA_CREATE_INSTANCE_METHOD_NAME = "$$createInstance";
+ private static final String LAMBDA_INSTANCE_FIELD_NAME = "INSTANCE";
private final AppView<?> appView;
final IRConverter converter;
@@ -71,7 +69,6 @@
final DexString constructorName;
final DexString classConstructorName;
final DexString instanceFieldName;
- final DexString createInstanceMethodName;
final BiMap<DexMethod, DexMethod> methodMapping = HashBiMap.create();
@@ -102,7 +99,6 @@
this.objectInitMethod = factory.createMethod(factory.objectType, initProto, constructorName);
this.classConstructorName = factory.createString(Constants.CLASS_INITIALIZER_NAME);
this.instanceFieldName = factory.createString(LAMBDA_INSTANCE_FIELD_NAME);
- this.createInstanceMethodName = factory.createString(LAMBDA_CREATE_INSTANCE_METHOD_NAME);
}
public void synthesizeLambdaClassesFor(
@@ -177,34 +173,6 @@
assert code.isConsistentSSA();
}
- public void desugarLambda(
- DexType currentType,
- InstructionListIterator instructions,
- InvokeCustom lenseRewrittenInvokeCustom,
- IRCode code) {
- LambdaDescriptor descriptor = inferLambdaDescriptor(lenseRewrittenInvokeCustom.getCallSite());
- if (descriptor == LambdaDescriptor.MATCH_FAILED) {
- return;
- }
-
- // We have a descriptor, get or create lambda class.
- LambdaClass lambdaClass = getOrCreateLambdaClass(descriptor, currentType);
- assert lambdaClass != null;
-
- // We rely on patch performing its work in a way which
- // keeps `instructions` iterator in valid state so that we can continue iteration.
- patchInstructionSimple(lambdaClass, code, instructions, lenseRewrittenInvokeCustom);
- }
-
- public boolean verifyNoLambdasToDesugar(IRCode code) {
- for (Instruction instruction : code.instructions()) {
- assert !instruction.isInvokeCustom()
- || inferLambdaDescriptor(instruction.asInvokeCustom().getCallSite())
- == LambdaDescriptor.MATCH_FAILED;
- }
- return true;
- }
-
/** Remove lambda deserialization methods. */
public boolean removeLambdaDeserializationMethods(Iterable<DexProgramClass> classes) {
for (DexProgramClass clazz : classes) {
@@ -400,108 +368,44 @@
return;
}
- if (!converter.appView.options().testing.enableStatefulLambdaCreateInstanceMethod) {
- // For stateful lambdas we always create a new instance since we need to pass
- // captured values to the constructor.
- //
- // We replace InvokeCustom instruction with a new NewInstance instruction
- // instantiating lambda followed by InvokeDirect instruction calling a
- // constructor on it.
- //
- // original:
- // Invoke-Custom rResult <- { rArg0, rArg1, ... }; call site: ...
- //
- // result:
- // NewInstance rResult <- LambdaClass
- // Invoke-Direct { rResult, rArg0, rArg1, ... }; method: void LambdaClass.<init>(...)
- lambdaInstanceValue.setTypeLattice(
- lambdaInstanceValue
- .getTypeLattice()
- .asReferenceTypeLatticeElement()
- .asDefinitelyNotNull());
- NewInstance newInstance = new NewInstance(lambdaClass.type, lambdaInstanceValue);
- instructions.replaceCurrentInstruction(newInstance);
-
- List<Value> arguments = new ArrayList<>();
- arguments.add(lambdaInstanceValue);
- arguments.addAll(invoke.arguments()); // Optional captures.
- InvokeDirect constructorCall =
- new InvokeDirect(lambdaClass.constructor, null /* no return value */, arguments);
- instructions.add(constructorCall);
- constructorCall.setPosition(newInstance.getPosition());
-
- // If we don't have catch handlers we are done.
- if (!constructorCall.getBlock().hasCatchHandlers()) {
- return;
- }
-
- // Move the iterator back to position it between the two instructions, split
- // the block between the two instructions, and copy the catch handlers.
- instructions.previous();
- assert instructions.peekNext().isInvokeDirect();
- BasicBlock currentBlock = newInstance.getBlock();
- BasicBlock nextBlock = instructions.split(code, blocks);
- assert !instructions.hasNext();
- nextBlock.copyCatchHandlers(code, blocks, currentBlock, appView.options());
- } else {
- // For stateful lambdas we call the createInstance method.
- //
- // original:
- // Invoke-Custom rResult <- { rArg0, rArg1, ... }; call site: ...
- //
- // result:
- // Invoke-Static rResult <- { rArg0, rArg1, ... }; method void
- // LambdaClass.createInstance(...)
- InvokeStatic invokeStatic =
- new InvokeStatic(
- lambdaClass.getCreateInstanceMethod(), lambdaInstanceValue, invoke.arguments());
- instructions.replaceCurrentInstruction(invokeStatic);
- }
- }
-
- // Patches invoke-custom instruction to create or get an instance
- // of the generated lambda class. Assumes that for stateful lambdas the createInstance method
- // is enabled so invokeCustom is always replaced by a single instruction.
- private void patchInstructionSimple(
- LambdaClass lambdaClass,
- IRCode code,
- InstructionListIterator instructions,
- InvokeCustom invoke) {
- assert lambdaClass != null;
- assert instructions != null;
-
- // The value representing new lambda instance: we reuse the value from the original
- // invoke-custom instruction, and thus all its usages.
- Value lambdaInstanceValue = invoke.outValue();
- if (lambdaInstanceValue == null) {
- // The out value might be empty in case it was optimized out.
- lambdaInstanceValue =
- code.createValue(
- TypeLatticeElement.fromDexType(lambdaClass.type, Nullability.maybeNull(), appView));
- }
-
- // For stateless lambdas we replace InvokeCustom instruction with StaticGet reading the value of
- // INSTANCE field created for singleton lambda class.
- if (lambdaClass.isStateless()) {
- instructions.replaceCurrentInstruction(
- new StaticGet(lambdaInstanceValue, lambdaClass.lambdaField));
- // Note that since we replace one throwing operation with another we don't need
- // to have any special handling for catch handlers.
- return;
- }
-
- assert appView.options().testing.enableStatefulLambdaCreateInstanceMethod;
- // For stateful lambdas we call the createInstance method.
+ // For stateful lambdas we always create a new instance since we need to pass
+ // captured values to the constructor.
+ //
+ // We replace InvokeCustom instruction with a new NewInstance instruction
+ // instantiating lambda followed by InvokeDirect instruction calling a
+ // constructor on it.
//
// original:
// Invoke-Custom rResult <- { rArg0, rArg1, ... }; call site: ...
//
// result:
- // Invoke-Static rResult <- { rArg0, rArg1, ... }; method void
- // LambdaClass.createInstance(...)
- InvokeStatic invokeStatic =
- new InvokeStatic(
- lambdaClass.getCreateInstanceMethod(), lambdaInstanceValue, invoke.arguments());
- instructions.replaceCurrentInstruction(invokeStatic);
+ // NewInstance rResult <- LambdaClass
+ // Invoke-Direct { rResult, rArg0, rArg1, ... }; method: void LambdaClass.<init>(...)
+ lambdaInstanceValue.setTypeLattice(
+ lambdaInstanceValue.getTypeLattice().asReferenceTypeLatticeElement().asDefinitelyNotNull());
+ NewInstance newInstance = new NewInstance(lambdaClass.type, lambdaInstanceValue);
+ instructions.replaceCurrentInstruction(newInstance);
+
+ List<Value> arguments = new ArrayList<>();
+ arguments.add(lambdaInstanceValue);
+ arguments.addAll(invoke.arguments()); // Optional captures.
+ InvokeDirect constructorCall =
+ new InvokeDirect(lambdaClass.constructor, null /* no return value */, arguments);
+ instructions.add(constructorCall);
+ constructorCall.setPosition(newInstance.getPosition());
+
+ // If we don't have catch handlers we are done.
+ if (!constructorCall.getBlock().hasCatchHandlers()) {
+ return;
+ }
+
+ // Move the iterator back to position it between the two instructions, split
+ // the block between the two instructions, and copy the catch handlers.
+ instructions.previous();
+ assert instructions.peekNext().isInvokeDirect();
+ BasicBlock currentBlock = newInstance.getBlock();
+ BasicBlock nextBlock = instructions.split(code, blocks);
+ assert !instructions.hasNext();
+ nextBlock.copyCatchHandlers(code, blocks, currentBlock, appView.options());
}
}
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index e815737..4e18f84 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1013,8 +1013,6 @@
public boolean forceNameReflectionOptimization = false;
public boolean enableNarrowingChecksInD8 = false;
public Consumer<IRCode> irModifier = null;
- // TODO(b/129458850) When fixed, remove this and change all usages to "true".
- public boolean enableStatefulLambdaCreateInstanceMethod = false;
public int basicBlockMuncherIterationLimit = NO_LIMIT;
public boolean dontReportFailingCheckDiscarded = false;
public boolean deterministicSortingBasedOnDexType = true;
@@ -1033,10 +1031,6 @@
// deleted. Useful to check that our dump functionality does not cause compilation failure.
public boolean dumpAll = false;
- public boolean desugarLambdasThroughLensCodeRewriter() {
- return enableStatefulLambdaCreateInstanceMethod;
- }
-
public boolean readInputStackMaps = false;
// Option for testing outlining with interface array arguments, see b/132420510.
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index 5f328d3..c85098d 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -137,37 +137,6 @@
.run();
}
- @Override
- @Test
- public void lambdaDesugaringCreateMethod() throws Throwable {
- test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
- .withMinApiLevel(ToolHelper.getMinApiLevelForDexVmNoHigherThan(AndroidApiLevel.K))
- .withOptionConsumer(
- opts -> {
- opts.enableClassInlining = false;
- opts.testing.enableStatefulLambdaCreateInstanceMethod = true;
- })
- .withBuilderTransformation(
- b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
- .withDexCheck(inspector -> checkLambdaCount(inspector, 180, "lambdadesugaring"))
- .run();
-
- test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
- .withMinApiLevel(ToolHelper.getMinApiLevelForDexVmNoHigherThan(AndroidApiLevel.K))
- .withOptionConsumer(
- opts -> {
- opts.enableClassInlining = true;
- opts.testing.enableStatefulLambdaCreateInstanceMethod = true;
- })
- .withBuilderTransformation(
- b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
- // TODO(b/120814598): Should be 24. Some lambdas are not class inlined because parameter
- // usages for lambda methods are not present for the class inliner.
- // TODO(b/141719453): Also, some are not inined due to instruction limits.
- .withDexCheck(inspector -> checkLambdaCount(inspector, 39, "lambdadesugaring"))
- .run();
- }
-
@Test
@IgnoreIfVmOlderThan(Version.V7_0_0)
public void lambdaDesugaringWithDefaultMethods() throws Throwable {
diff --git a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
index a6522b1..daab81d 100644
--- a/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/RunExamplesAndroidOTest.java
@@ -369,15 +369,6 @@
}
@Test
- public void lambdaDesugaringCreateMethod() throws Throwable {
- test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
- .withMinApiLevel(ToolHelper.getMinApiLevelForDexVmNoHigherThan(AndroidApiLevel.K))
- .withKeepAll()
- .withOptionConsumer(o -> o.testing.enableStatefulLambdaCreateInstanceMethod = true)
- .run();
- }
-
- @Test
public void lambdaDesugaringNPlus() throws Throwable {
test("lambdadesugaringnplus", "lambdadesugaringnplus", "LambdasWithStaticAndDefaultMethods")
.withMinApiLevel(ToolHelper.getMinApiLevelForDexVmNoHigherThan(AndroidApiLevel.K))