Add builder for ForwardedSourceCode
Bug: 131885814
Change-Id: If91617dd57c95832c0431b08929fe8a69a370901
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 97fd72c..d916ee0 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -742,22 +742,19 @@
definitions.dexItemFactory().createMethod(method.holder, newProto, method.name);
Builder builder = builder(this);
builder.setMethod(newMethod);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setReceiver(holder.type)
+ .setTargetReceiver(holder.type)
+ .setTarget(method)
+ .setInvokeType(Invoke.Type.DIRECT)
+ .setExtraNullParameter();
builder.setCode(
new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- holder.type,
- newMethod,
- newMethod,
- holder.type,
- method,
- Invoke.Type.DIRECT,
- callerPosition,
- holder.isInterface(),
- false,
- true),
- registry -> registry.registerInvokeDirect(method)));
+ forwardSourceCodeBuilder::build, registry -> registry.registerInvokeDirect(method)));
assert !builder.accessFlags.isStatic();
+ assert !holder.isInterface();
builder.accessFlags.unsetPrivate();
builder.accessFlags.setSynthetic();
builder.accessFlags.setConstructor();
@@ -820,18 +817,16 @@
DexMethod newMethod = definitions.dexItemFactory().createMethod(holder.type, proto, newName);
Builder builder = builder(this);
builder.setMethod(newMethod);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setTargetReceiver(accessFlags.isStatic() ? null : method.holder)
+ .setTarget(method)
+ .setInvokeType(accessFlags.isStatic() ? Invoke.Type.STATIC : Invoke.Type.DIRECT)
+ .setIsInterface(holder.isInterface());
builder.setCode(
new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- null,
- newMethod,
- newMethod,
- accessFlags.isStatic() ? null : method.holder,
- method,
- accessFlags.isStatic() ? Invoke.Type.STATIC : Invoke.Type.DIRECT,
- callerPosition,
- holder.isInterface()),
+ forwardSourceCodeBuilder::build,
registry -> {
if (accessFlags.isStatic()) {
registry.registerInvokeStatic(method);
@@ -867,18 +862,17 @@
} else {
// Create code that forwards the call to the target.
DexClass target = definitions.definitionFor(method.holder);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setReceiver(accessFlags.isStatic() ? null : holder.type)
+ .setTargetReceiver(accessFlags.isStatic() ? null : method.holder)
+ .setTarget(method)
+ .setInvokeType(type)
+ .setIsInterface(target.isInterface());
builder.setCode(
new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- accessFlags.isStatic() ? null : holder.type,
- newMethod,
- newMethod,
- accessFlags.isStatic() ? null : method.holder,
- method,
- type,
- callerPosition,
- target.isInterface()),
+ forwardSourceCodeBuilder::build,
registry -> {
if (accessFlags.isStatic()) {
registry.registerInvokeStatic(method);
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 7f2bdf0..83ef838 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
@@ -112,22 +112,19 @@
MethodAccessFlags newFlags = defaultMethod.accessFlags.copy();
// Some debuggers (like IntelliJ) automatically skip synthetic methods on single step.
newFlags.setSynthetic();
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setReceiver(clazz.type)
+ .setTarget(rewriter.defaultAsMethodOfCompanionClass(method))
+ .setInvokeType(Invoke.Type.STATIC)
+ .setIsInterface(target.isInterface());
return new DexEncodedMethod(
newMethod,
newFlags,
defaultMethod.annotations,
defaultMethod.parameterAnnotationsList,
- new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- clazz.type,
- newMethod,
- newMethod,
- null /* static method */,
- rewriter.defaultAsMethodOfCompanionClass(method),
- Invoke.Type.STATIC,
- callerPosition,
- target.isInterface())));
+ new SynthesizedCode(forwardSourceCodeBuilder::build));
}
// For a given class `clazz` inspects all interfaces it implements directly or
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 9c0c542..b2b88aa 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
@@ -150,24 +150,21 @@
newAccessFlags.setBridge();
newAccessFlags.setSynthetic();
DexMethod newMethod = factory.createMethod(method.method.holder, newProto, method.method.name);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setReceiver(clazz.type)
+ .setTargetReceiver(method.method.holder)
+ .setTarget(method.method)
+ .setInvokeType(Invoke.Type.VIRTUAL)
+ .setCastResult();
DexEncodedMethod newVirtualMethod =
new DexEncodedMethod(
newMethod,
newAccessFlags,
method.annotations.keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)),
method.parameterAnnotationsList.keepIf(Predicates.alwaysTrue()),
- new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- clazz.type,
- newMethod,
- newMethod,
- method.method.holder,
- method.method,
- Invoke.Type.VIRTUAL,
- callerPosition,
- false /* isInterface */,
- true /* castResult */)));
+ new SynthesizedCode(forwardSourceCodeBuilder::build));
// Optimize to generate DexCode instead of SynthesizedCode.
converter.optimizeSynthesizedMethod(newVirtualMethod);
return newVirtualMethod;
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 48de822..e044477 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
@@ -227,6 +227,12 @@
DexMethod origMethod = direct.method;
DexMethod newMethod = rewriter.staticAsMethodOfDispatchClass(origMethod);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(newMethod);
+ forwardSourceCodeBuilder
+ .setTarget(origMethod)
+ .setInvokeType(Type.STATIC)
+ .setIsInterface(true);
DexEncodedMethod newEncodedMethod =
new DexEncodedMethod(
newMethod,
@@ -234,17 +240,7 @@
Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false),
DexAnnotationSet.empty(),
ParameterAnnotationsList.empty(),
- new SynthesizedCode(
- callerPosition ->
- new ForwardMethodSourceCode(
- null,
- newMethod,
- newMethod,
- null,
- origMethod,
- Type.STATIC,
- callerPosition,
- true /* isInterface */)));
+ new SynthesizedCode(forwardSourceCodeBuilder::build));
newEncodedMethod.getMutableOptimizationInfo().markNeverInline();
dispatchMethods.add(newEncodedMethod);
}
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
index c49c3e1..e5a79bb 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/ForwardMethodSourceCode.java
@@ -20,6 +20,87 @@
// Source code representing simple forwarding method.
public final class ForwardMethodSourceCode extends SyntheticSourceCode {
+ public static Builder builder(DexMethod method) {
+ return new Builder(method);
+ }
+
+ public static class Builder {
+
+ private DexType receiver;
+ private DexMethod method;
+ private DexMethod originalMethod;
+ private DexType targetReceiver;
+ private DexMethod target;
+ private Invoke.Type invokeType;
+ private boolean castResult;
+ private boolean isInterface;
+ private boolean extraNullParameter;
+
+ public Builder(DexMethod method) {
+ this.method = method;
+ this.originalMethod = method;
+ }
+
+ public Builder setReceiver(DexType receiver) {
+ this.receiver = receiver;
+ return this;
+ }
+
+ public Builder setMethod(DexMethod method) {
+ this.method = method;
+ return this;
+ }
+
+ public Builder setOriginalMethod(DexMethod originalMethod) {
+ this.originalMethod = originalMethod;
+ return this;
+ }
+
+ public Builder setTargetReceiver(DexType targetReceiver) {
+ this.targetReceiver = targetReceiver;
+ return this;
+ }
+
+ public Builder setTarget(DexMethod target) {
+ this.target = target;
+ return this;
+ }
+
+ public Builder setInvokeType(Type invokeType) {
+ this.invokeType = invokeType;
+ return this;
+ }
+
+ public Builder setCastResult() {
+ this.castResult = true;
+ return this;
+ }
+
+ public Builder setIsInterface(boolean isInterface) {
+ this.isInterface = isInterface;
+ return this;
+ }
+
+ public Builder setExtraNullParameter() {
+ this.extraNullParameter = true;
+ return this;
+ }
+
+ public ForwardMethodSourceCode build(Position callerPosition) {
+ return new ForwardMethodSourceCode(
+ receiver,
+ method,
+ originalMethod,
+ targetReceiver,
+ target,
+ invokeType,
+ callerPosition,
+ isInterface,
+ castResult,
+ extraNullParameter);
+ }
+ }
+
private final DexType targetReceiver;
private final DexMethod target;
private final Invoke.Type invokeType;
@@ -27,51 +108,7 @@
private final boolean isInterface;
private final boolean extraNullParameter;
- public ForwardMethodSourceCode(
- DexType receiver,
- DexMethod method,
- DexMethod originalMethod,
- DexType targetReceiver,
- DexMethod target,
- Type invokeType,
- Position callerPosition,
- boolean isInterface) {
- this(
- receiver,
- method,
- originalMethod,
- targetReceiver,
- target,
- invokeType,
- callerPosition,
- isInterface,
- false);
- }
-
- public ForwardMethodSourceCode(
- DexType receiver,
- DexMethod method,
- DexMethod originalMethod,
- DexType targetReceiver,
- DexMethod target,
- Type invokeType,
- Position callerPosition,
- boolean isInterface,
- boolean castResult) {
- this(
- receiver,
- method,
- originalMethod,
- targetReceiver,
- target,
- invokeType,
- callerPosition,
- isInterface,
- castResult,
- false);
- }
-
- public ForwardMethodSourceCode(
+ protected ForwardMethodSourceCode(
DexType receiver,
DexMethod method,
DexMethod originalMethod,
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 25c61d8..e470a9b 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -1886,16 +1886,16 @@
@Override
public SourceCodeProvider getSourceCodeProvider() {
- return callerPosition ->
- new ForwardMethodSourceCode(
- method.holder,
- method,
- originalMethod,
- type == DIRECT ? method.holder : null,
- invocationTarget,
- type,
- callerPosition,
- isInterface);
+ ForwardMethodSourceCode.Builder forwardSourceCodeBuilder =
+ ForwardMethodSourceCode.builder(method);
+ forwardSourceCodeBuilder
+ .setReceiver(method.holder)
+ .setOriginalMethod(originalMethod)
+ .setTargetReceiver(type == DIRECT ? method.holder : null)
+ .setTarget(invocationTarget)
+ .setInvokeType(type)
+ .setIsInterface(isInterface);
+ return forwardSourceCodeBuilder::build;
}
@Override