Reland "Add D8R8SynthesizedFlag"
Change-Id: I8b79f86549f9e289353a296c13e2e3fd2c23d80f
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 39977cc..d7dc501 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -137,7 +137,7 @@
private CompilationState compilationState = CompilationState.NOT_PROCESSED;
private MethodOptimizationInfo optimizationInfo = DefaultMethodOptimizationInfo.DEFAULT_INSTANCE;
private CallSiteOptimizationInfo callSiteOptimizationInfo = CallSiteOptimizationInfo.BOTTOM;
- private int classFileVersion = -1;
+ private int classFileVersion;
private DexEncodedMethod defaultInterfaceMethodImplementation = null;
@@ -151,6 +151,18 @@
// Any newly added `public` method should check if `this` instance is obsolete.
private boolean obsolete = false;
+ // This flag indicates if the method has been synthesized by D8/R8. Such method do not require
+ // a proguard mapping file entry. This flag is different from the synthesized access flag. When a
+ // non synthesized method is inlined into a synthesized method, the method no longer has the
+ // synthesized access flag, but the d8R8Synthesized flag is still there. Methods can also have
+ // the synthesized access flag prior to D8/R8 compilation, in which case d8R8Synthesized is not
+ // set.
+ private final boolean d8R8Synthesized;
+
+ public boolean isD8R8Synthesized() {
+ return d8R8Synthesized;
+ }
+
private void checkIfObsolete() {
assert !obsolete;
}
@@ -200,26 +212,49 @@
DexAnnotationSet annotations,
ParameterAnnotationsList parameterAnnotationsList,
Code code) {
+ this(method, accessFlags, annotations, parameterAnnotationsList, code, -1);
+ }
+
+ public DexEncodedMethod(
+ DexMethod method,
+ MethodAccessFlags accessFlags,
+ DexAnnotationSet annotations,
+ ParameterAnnotationsList parameterAnnotationsList,
+ Code code,
+ int classFileVersion) {
+ this(method, accessFlags, annotations, parameterAnnotationsList, code, classFileVersion, false);
+ }
+
+ public DexEncodedMethod(
+ DexMethod method,
+ MethodAccessFlags accessFlags,
+ DexAnnotationSet annotations,
+ ParameterAnnotationsList parameterAnnotationsList,
+ Code code,
+ boolean d8R8Synthesized) {
+ this(method, accessFlags, annotations, parameterAnnotationsList, code, -1, d8R8Synthesized);
+ }
+
+ public DexEncodedMethod(
+ DexMethod method,
+ MethodAccessFlags accessFlags,
+ DexAnnotationSet annotations,
+ ParameterAnnotationsList parameterAnnotationsList,
+ Code code,
+ int classFileVersion,
+ boolean d8R8Synthesized) {
this.method = method;
this.accessFlags = accessFlags;
this.annotations = annotations;
this.parameterAnnotationsList = parameterAnnotationsList;
this.code = code;
+ this.classFileVersion = classFileVersion;
+ this.d8R8Synthesized = d8R8Synthesized;
+
assert code == null || !shouldNotHaveCode();
assert parameterAnnotationsList != null;
}
- public DexEncodedMethod(
- DexMethod method,
- MethodAccessFlags flags,
- DexAnnotationSet annotationSet,
- ParameterAnnotationsList annotationsList,
- Code code,
- int classFileVersion) {
- this(method, flags, annotationSet, annotationsList, code);
- this.classFileVersion = classFileVersion;
- }
-
public OptionalBool isLibraryMethodOverride() {
return isNonPrivateVirtualMethod() ? isLibraryMethodOverride : OptionalBool.FALSE;
}
@@ -909,23 +944,11 @@
return builder.build();
}
- public DexEncodedMethod toRenamedMethod(DexString name, DexItemFactory factory) {
- checkIfObsolete();
- if (method.name == name) {
- return this;
- }
- DexMethod newMethod = factory.createMethod(method.holder, method.proto, name);
- Builder builder = builder(this);
- builder.setMethod(newMethod);
- setObsolete();
- return builder.build();
- }
-
public DexEncodedMethod toInitializerForwardingBridge(DexClass holder, DexMethod newMethod) {
assert accessFlags.isPrivate()
: "Expected to create bridge for private constructor as part of nest-based access"
+ " desugaring";
- Builder builder = builder(this);
+ Builder builder = syntheticBuilder(this);
builder.setMethod(newMethod);
ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
ForwardMethodSourceCode.builder(newMethod);
@@ -973,7 +996,12 @@
}
});
return new DexEncodedMethod(
- newMethod, accessFlags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
+ newMethod,
+ accessFlags,
+ DexAnnotationSet.empty(),
+ ParameterAnnotationsList.empty(),
+ code,
+ true);
}
public DexEncodedMethod toRenamedHolderMethod(DexType newHolderType, DexItemFactory factory) {
@@ -997,13 +1025,18 @@
interfaceType, companionMethod, libraryMethod, extraDispatchCases, appView)
.generateCfCode();
return new DexEncodedMethod(
- newMethod, accessFlags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
+ newMethod,
+ accessFlags,
+ DexAnnotationSet.empty(),
+ ParameterAnnotationsList.empty(),
+ code,
+ true);
}
public DexEncodedMethod toStaticForwardingBridge(DexClass holder, DexMethod newMethod) {
assert accessFlags.isPrivate()
: "Expected to create bridge for private method as part of nest-based access desugaring";
- Builder builder = builder(this);
+ Builder builder = syntheticBuilder(this);
builder.setMethod(newMethod);
ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
ForwardMethodSourceCode.builder(newMethod);
@@ -1041,7 +1074,7 @@
DexMethod newMethod =
definitions.dexItemFactory().createMethod(holder.type, method.proto, method.name);
Invoke.Type type = accessFlags.isStatic() ? Invoke.Type.STATIC : Invoke.Type.SUPER;
- Builder builder = builder(this);
+ Builder builder = syntheticBuilder(this);
builder.setMethod(newMethod);
if (accessFlags.isAbstract()) {
// If the forwarding target is abstract, we can just create an abstract method. While it
@@ -1098,7 +1131,8 @@
newFlags,
target.annotations,
target.parameterAnnotationsList,
- new SynthesizedCode(forwardSourceCodeBuilder::build));
+ new SynthesizedCode(forwardSourceCodeBuilder::build),
+ true);
}
public DexEncodedMethod toStaticMethodWithoutThis() {
@@ -1232,6 +1266,10 @@
}
}
+ private static Builder syntheticBuilder(DexEncodedMethod from) {
+ return new Builder(from, true);
+ }
+
private static Builder builder(DexEncodedMethod from) {
return new Builder(from);
}
@@ -1246,8 +1284,13 @@
private CompilationState compilationState;
private MethodOptimizationInfo optimizationInfo;
private final int classFileVersion;
+ private boolean d8R8Synthesized;
private Builder(DexEncodedMethod from) {
+ this(from, from.d8R8Synthesized);
+ }
+
+ private Builder(DexEncodedMethod from, boolean d8R8Synthesized) {
// Copy all the mutable state of a DexEncodedMethod here.
method = from.method;
accessFlags = from.accessFlags.copy();
@@ -1256,6 +1299,7 @@
compilationState = from.compilationState;
optimizationInfo = from.optimizationInfo.mutableCopy();
classFileVersion = from.classFileVersion;
+ this.d8R8Synthesized = d8R8Synthesized;
if (from.parameterAnnotationsList.isEmpty()
|| from.parameterAnnotationsList.size() == method.proto.parameters.size()) {
@@ -1341,7 +1385,13 @@
|| parameterAnnotations.size() == method.proto.parameters.size();
DexEncodedMethod result =
new DexEncodedMethod(
- method, accessFlags, annotations, parameterAnnotations, code, classFileVersion);
+ method,
+ accessFlags,
+ annotations,
+ parameterAnnotations,
+ code,
+ classFileVersion,
+ d8R8Synthesized);
result.compilationState = compilationState;
result.optimizationInfo = optimizationInfo;
return result;
diff --git a/src/main/java/com/android/tools/r8/graph/GraphLense.java b/src/main/java/com/android/tools/r8/graph/GraphLense.java
index 1fc834d..09a9055 100644
--- a/src/main/java/com/android/tools/r8/graph/GraphLense.java
+++ b/src/main/java/com/android/tools/r8/graph/GraphLense.java
@@ -719,10 +719,8 @@
: "Unable to map field `" + field.field.toSourceString() + "` back to original program";
}
for (DexEncodedMethod method : clazz.methods()) {
- if (method.accessFlags.isSynthetic()) {
- // This could be a bridge that has been inserted, for example, as a result of member
- // rebinding. Consider only skipping the check below for methods that have been
- // synthesized by R8.
+ if (method.isD8R8Synthesized()) {
+ // Methods synthesized by D8/R8 may not be mapped.
continue;
}
DexMethod originalMethod = getOriginalMethodSignature(method.method);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 1da29d2..8c632a2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -214,7 +214,7 @@
Code code = provider.generateTemplateMethod(appView.options(), method);
DexEncodedMethod dexEncodedMethod =
new DexEncodedMethod(
- method, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
+ method, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code, true);
boolean addToMainDexList =
referencingClasses.stream()
.anyMatch(clazz -> appView.appInfo().isInMainDexList(clazz.type));
@@ -392,7 +392,7 @@
factory.createMethod(
interfaceType, emulatedDispatchMethod.proto, emulatedDispatchMethod.name);
return new DexEncodedMethod(
- newMethod, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
+ newMethod, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null, true);
}
private DexEncodedMethod generateHolderDispatchMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index 565af2f..0204455 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -365,7 +365,8 @@
new SynthesizedCode(
callerPosition ->
new ExceptionThrowingSourceCode(
- clazz.type, method, callerPosition, dexItemFactory.icceType)));
+ clazz.type, method, callerPosition, dexItemFactory.icceType)),
+ true);
addSyntheticMethod(clazz.asProgramClass(), newEncodedMethod);
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
index e13f26f..a0fb1c8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
@@ -164,7 +164,8 @@
newAccessFlags,
method.annotations.keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)),
method.parameterAnnotationsList.keepIf(Predicates.alwaysTrue()),
- new SynthesizedCode(forwardSourceCodeBuilder::build));
+ new SynthesizedCode(forwardSourceCodeBuilder::build),
+ true);
// Optimize to generate DexCode instead of SynthesizedCode.
converter.optimizeSynthesizedMethod(newVirtualMethod);
return newVirtualMethod;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
index e3e7ab0..bf48a16 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
@@ -403,7 +403,8 @@
newFlags,
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- code);
+ code,
+ true);
}
private List<DexEncodedMethod> allImplementedMethods(DexClass libraryClass) {
@@ -474,7 +475,8 @@
accessFlags,
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- code);
+ code,
+ true);
}
// Wrapper finalization section.
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 9599834..ccb0f3c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -94,7 +94,7 @@
DexEncodedMethod.setDebugInfoWithFakeThisParameter(
code, companionMethod.getArity(), appView);
DexEncodedMethod implMethod = new DexEncodedMethod(
- companionMethod, newFlags, virtual.annotations, virtual.parameterAnnotationsList, code);
+ companionMethod, newFlags, virtual.annotations, virtual.parameterAnnotationsList, code, true);
virtual.setDefaultInterfaceMethodImplementation(implMethod);
companionMethods.add(implMethod);
graphLensBuilder.move(virtual.method, implMethod.method);
@@ -128,7 +128,7 @@
+ "either be public or private in " + iface.origin;
DexMethod companionMethod = rewriter.staticAsMethodOfCompanionClass(oldMethod);
companionMethods.add(new DexEncodedMethod(companionMethod, newFlags,
- direct.annotations, direct.parameterAnnotationsList, direct.getCode()));
+ direct.annotations, direct.parameterAnnotationsList, direct.getCode(),true));
graphLensBuilder.move(oldMethod, companionMethod);
} else {
if (originalFlags.isPrivate()) {
@@ -147,7 +147,7 @@
DexEncodedMethod.setDebugInfoWithFakeThisParameter(
code, companionMethod.getArity(), appView);
companionMethods.add(new DexEncodedMethod(companionMethod,
- newFlags, direct.annotations, direct.parameterAnnotationsList, code));
+ newFlags, direct.annotations, direct.parameterAnnotationsList, code,true));
graphLensBuilder.move(oldMethod, companionMethod);
} else {
// Since there are no interface constructors at this point,
@@ -247,7 +247,8 @@
Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new SynthesizedCode(forwardSourceCodeBuilder::build));
+ new SynthesizedCode(forwardSourceCodeBuilder::build),
+ true);
newEncodedMethod.getMutableOptimizationInfo().markNeverInline();
dispatchMethods.add(newEncodedMethod);
}
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 cf9eca4..18edf5f 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
@@ -228,7 +228,8 @@
Constants.ACC_PUBLIC | Constants.ACC_FINAL, false),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new LambdaMainMethodSynthesizedCode(this, mainMethod));
+ new LambdaMainMethodSynthesizedCode(this, mainMethod),
+ true);
// Synthesize bridge methods.
for (DexProto bridgeProto : descriptor.bridges) {
@@ -245,7 +246,8 @@
false),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new LambdaBridgeMethodSynthesizedCode(this, mainMethod, bridgeMethod));
+ new LambdaBridgeMethodSynthesizedCode(this, mainMethod, bridgeMethod),
+ true);
}
return methods;
}
@@ -265,7 +267,8 @@
true),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new LambdaConstructorSynthesizedCode(this));
+ new LambdaConstructorSynthesizedCode(this),
+ true);
// Class constructor for stateless lambda classes.
if (stateless) {
@@ -276,7 +279,8 @@
Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, true),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new LambdaClassConstructorSynthesizedCode(this));
+ new LambdaClassConstructorSynthesizedCode(this),
+ true);
}
return methods;
}
@@ -360,10 +364,6 @@
assert implMethod.holder == accessedFrom;
assert descriptor.targetFoundInClass(accessedFrom);
assert descriptor.getAccessibility() != null;
- // When coming from javac these are also private, but we don't assert that, as the
- // accessibility could have been modified (e.g. due to -allowaccessmodification).
-
- assert descriptor.getAccessibility().isSynthetic();
if (implHandle.type.isInvokeStatic()) {
return new StaticLambdaImplTarget();
@@ -608,7 +608,8 @@
newAccessFlags,
encodedMethod.annotations,
encodedMethod.parameterAnnotationsList,
- encodedMethod.getCode());
+ encodedMethod.getCode(),
+ true);
newMethod.copyMetadata(encodedMethod);
rewriter.methodMapping.put(encodedMethod.method, callTarget);
@@ -652,7 +653,8 @@
newAccessFlags,
encodedMethod.annotations,
encodedMethod.parameterAnnotationsList,
- encodedMethod.getCode());
+ encodedMethod.getCode(),
+ true);
newMethod.copyMetadata(encodedMethod);
rewriter.methodMapping.put(encodedMethod.method, callTarget);
// Move the method from the direct methods to the virtual methods set.
@@ -692,7 +694,8 @@
ParameterAnnotationsList.empty(),
new SynthesizedCode(
callerPosition ->
- new AccessorMethodSourceCode(LambdaClass.this, callerPosition)));
+ new AccessorMethodSourceCode(LambdaClass.this, callerPosition)),
+ true);
// We may arrive here concurrently so we need must update the methods of the class atomically.
synchronized (accessorClass) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index cf66050..4c2a36d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -40,7 +40,7 @@
public abstract class NestBasedAccessDesugaring {
// Short names to avoid creating long strings
- private static final String NEST_ACCESS_NAME_PREFIX = "-$$Nest$";
+ public static final String NEST_ACCESS_NAME_PREFIX = "-$$Nest$";
private static final String NEST_ACCESS_METHOD_NAME_PREFIX = NEST_ACCESS_NAME_PREFIX + "m";
private static final String NEST_ACCESS_STATIC_METHOD_NAME_PREFIX =
NEST_ACCESS_NAME_PREFIX + "sm";
@@ -69,6 +69,7 @@
}
DexType getNestConstructorType() {
+ assert nestConstructor != null;
return nestConstructor.type;
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
index 817fdb2..17250cf 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
@@ -134,7 +134,7 @@
MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(
Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false);
DexEncodedMethod method = new DexEncodedMethod(twrCloseResourceMethod,
- flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
+ flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code, true);
// Create utility class.
DexProgramClass utilityClass =
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 6de35d0..ab3274d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -971,12 +971,13 @@
classInitializationAnalysis.notifyCodeHasChanged();
strategy.updateTypeInformationIfNeeded(inlinee.code, blockIterator, block);
- // TODO(b/146114533): Fix inlining in synthetic methods.
- // If we inlined the invoke from a bridge method, it is no longer a bridge method.
- if (context.accessFlags.isBridge()) {
- context.accessFlags.unsetSynthetic();
+ // The synthetic and bridge flags are maintained only if the inlinee has also these flags.
+ if (context.accessFlags.isBridge() && !inlinee.code.method.accessFlags.isBridge()) {
context.accessFlags.unsetBridge();
}
+ if (context.accessFlags.isSynthetic() && !inlinee.code.method.accessFlags.isSynthetic()) {
+ context.accessFlags.unsetSynthetic();
+ }
context.copyMetadata(singleTarget);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 2ac3abd..e17e419 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -1343,7 +1343,8 @@
methodAccess,
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new OutlineCode(outline));
+ new OutlineCode(outline),
+ true);
if (appView.options().isGeneratingClassFiles()) {
direct[count].upgradeClassFileVersion(sites.get(0).getClassFileVersion());
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
index 29ad438..856baa9 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
@@ -225,7 +225,8 @@
methodAccess,
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- ServiceLoaderSourceCode.generate(serviceType, classes, appView.dexItemFactory()));
+ ServiceLoaderSourceCode.generate(serviceType, classes, appView.dexItemFactory()),
+ true);
synthesizedClass.addDirectMethod(encodedMethod);
return encodedMethod;
}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
index 74a5236..6bc95f2 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
@@ -127,7 +127,8 @@
method,
group.getLambdaIdField(factory),
implMethods,
- callerPosition))));
+ callerPosition)),
+ true));
}
}
@@ -177,7 +178,8 @@
new SynthesizedCode(
callerPosition ->
createInstanceInitializerSourceCode(
- groupClassType, initializerMethod, callerPosition)));
+ groupClassType, initializerMethod, callerPosition)),
+ true);
// Static class initializer for stateless lambdas.
if (needsSingletonInstances) {
@@ -194,7 +196,8 @@
ParameterAnnotationsList.empty(),
new SynthesizedCode(
callerPosition ->
- new ClassInitializerSourceCode(method, factory, group, callerPosition)));
+ new ClassInitializerSourceCode(method, factory, group, callerPosition)),
+ true);
}
return result;
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index c518937..ae8eb7e 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -1214,7 +1214,8 @@
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
code,
- method.hasClassFileVersion() ? method.getClassFileVersion() : -1);
+ method.hasClassFileVersion() ? method.getClassFileVersion() : -1,
+ true);
if (method.accessFlags.isPromotedToPublic()) {
// The bridge is now the public method serving the role of the original method, and should
// reflect that this method was publicized.
diff --git a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java
index 8322b11..9d01c91 100644
--- a/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java
+++ b/src/test/java/com/android/tools/r8/desugar/nestaccesscontrol/MinimumNumberOfBridgesGenerated.java
@@ -12,6 +12,8 @@
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.ir.desugar.NestBasedAccessDesugaring;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
@@ -58,19 +60,30 @@
int methodNumBridges = parameters.isCfRuntime() ? 0 : 2;
ClassSubject methodMainClass = inspector.clazz(getMainClass("methods"));
assertEquals(
- methodNumBridges, methodMainClass.allMethods(FoundMethodSubject::isSynthetic).size());
+ methodNumBridges, methodMainClass.allMethods(this::isNestBridge).size());
// Two bridges for method and staticMethod.
int constructorNumBridges = parameters.isCfRuntime() ? 0 : 1;
ClassSubject constructorMainClass = inspector.clazz(getMainClass("constructors"));
assertEquals(
constructorNumBridges,
- constructorMainClass.allMethods(FoundMethodSubject::isSynthetic).size());
+ constructorMainClass.allMethods(this::isNestBridge).size());
// Four bridges for field and staticField, both get & set.
int fieldNumBridges = parameters.isCfRuntime() ? 0 : 4;
ClassSubject fieldMainClass = inspector.clazz(getMainClass("fields"));
assertEquals(
- fieldNumBridges, fieldMainClass.allMethods(FoundMethodSubject::isSynthetic).size());
+ fieldNumBridges, fieldMainClass.allMethods(this::isNestBridge).size());
+ }
+
+ private boolean isNestBridge(FoundMethodSubject methodSubject) {
+ DexEncodedMethod method = methodSubject.getMethod();
+ if (method.isInstanceInitializer()) {
+ return method.method.proto.parameters.size() > 0 && method.method.proto.parameters.values[
+ method.method.proto.parameters.size() - 1].toSourceString()
+ .contains(NestBasedAccessDesugaring.NEST_CONSTRUCTOR_NAME);
+ }
+ return method.method.name.toString()
+ .startsWith(NestBasedAccessDesugaring.NEST_ACCESS_NAME_PREFIX);
}
}