Add position information for backport instruction rewriting
Bug: b/326196974
Change-Id: I651f3079cc1264beadfbce06150ed536f619638b
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 37a55ce..6694cb0 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -294,7 +294,7 @@
}
private boolean willComputeProguardMap() {
- return options.mapConsumer != null;
+ return options.hasMappingFileSupport();
}
/** Writer that never needs the input app to deal with mapping info for kotlin. */
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 82314cf..3db1504 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
@@ -9,8 +9,10 @@
import com.android.tools.r8.cf.code.CfInstanceFieldWrite;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
+import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfNew;
+import com.android.tools.r8.cf.code.CfPosition;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfStackInstruction;
@@ -39,6 +41,8 @@
import com.android.tools.r8.graph.FieldAccessFlags;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.desugar.backports.BackportedMethodDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.backports.BackportedMethods;
@@ -114,7 +118,8 @@
private DesugarDescription desugarInstruction(CfInvoke invoke, MethodProvider methodProvider) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -123,7 +128,12 @@
desugaringCollection,
dexItemFactory) ->
methodProvider.rewriteInvoke(
- invoke, appView, eventConsumer, methodProcessingContext, localStackAllocator))
+ position,
+ invoke,
+ appView,
+ eventConsumer,
+ methodProcessingContext,
+ localStackAllocator))
.build();
}
@@ -1823,6 +1833,7 @@
}
public abstract Collection<CfInstruction> rewriteInvoke(
+ Position position,
CfInvoke invoke,
AppView<?> appView,
BackportedMethodDesugaringEventConsumer eventConsumer,
@@ -1841,12 +1852,32 @@
@Override
public Collection<CfInstruction> rewriteInvoke(
+ Position position,
CfInvoke invoke,
AppView<?> appView,
BackportedMethodDesugaringEventConsumer eventConsumer,
MethodProcessingContext methodProcessingContext,
LocalStackAllocator localStackAllocator) {
- return rewriter.rewrite(invoke, appView.dexItemFactory(), localStackAllocator);
+ Collection<CfInstruction> instructions =
+ rewriter.rewrite(invoke, appView.dexItemFactory(), localStackAllocator);
+ if (position == null) {
+ return instructions;
+ }
+ ArrayList<CfInstruction> instructionsWithPositions = new ArrayList<>(instructions.size() + 4);
+ CfLabel start = new CfLabel();
+ CfLabel end = new CfLabel();
+ Position inlinePosition =
+ SourcePosition.builder()
+ .setCallerPosition(position)
+ .setMethod(invoke.getMethod())
+ .setLine(0)
+ .build();
+ instructionsWithPositions.add(start);
+ instructionsWithPositions.add(new CfPosition(start, inlinePosition));
+ instructionsWithPositions.addAll(instructions);
+ instructionsWithPositions.add(end);
+ instructionsWithPositions.add(new CfPosition(end, position));
+ return instructionsWithPositions;
}
}
@@ -1870,6 +1901,7 @@
@Override
public Collection<CfInstruction> rewriteInvoke(
+ Position position,
CfInvoke invoke,
AppView<?> appView,
BackportedMethodDesugaringEventConsumer eventConsumer,
@@ -1974,6 +2006,7 @@
@Override
public Collection<CfInstruction> rewriteInvoke(
+ Position position,
CfInvoke invoke,
AppView<?> appView,
BackportedMethodDesugaringEventConsumer eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java
index 0d2810f..67c2bf3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BufferCovariantReturnTypeRewriter.java
@@ -48,7 +48,8 @@
private DesugarDescription desugarInstruction(DexMethod invokedMethod, CfInvoke newInvoke) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
index a2dd4ef..d28ac39 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CfInstructionDesugaringCollection.java
@@ -10,6 +10,7 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
@@ -66,6 +67,7 @@
/** Selective desugaring of a single invoke instruction assuming a given context. */
public abstract Collection<CfInstruction> desugarInstruction(
CfInstruction instruction,
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugarDescription.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugarDescription.java
index 635f975..f3bbcf1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugarDescription.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugarDescription.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.Position;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -33,6 +34,7 @@
}
public Collection<CfInstruction> desugarInstruction(
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
@@ -61,6 +63,7 @@
@FunctionalInterface
public interface DesugarCallback {
Collection<CfInstruction> desugarInstruction(
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
@@ -141,6 +144,7 @@
@Override
public Collection<CfInstruction> desugarInstruction(
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
@@ -152,6 +156,7 @@
return desugarRewrite == null
? null
: desugarRewrite.desugarInstruction(
+ position,
freshLocalProvider,
localStackAllocator,
desugaringInfo,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
index b8a7565..46ff0f0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/EmptyCfInstructionDesugaringCollection.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.contexts.CompilationContext.MethodProcessingContext;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodProcessorFacade;
import com.android.tools.r8.ir.desugar.itf.InterfaceMethodRewriter.Flavor;
@@ -53,6 +54,7 @@
@Override
public Collection<CfInstruction> desugarInstruction(
CfInstruction instruction,
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java
index 867a9c7..151eb36 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InvokeToPrivateRewriter.java
@@ -41,7 +41,8 @@
private DesugarDescription desugarInstruction(CfInvoke invoke, DexMethod method) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
index 3ae702e..485322e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NonEmptyCfInstructionDesugaringCollection.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.desugar.apimodel.ApiInvokeOutlinerDesugaring;
import com.android.tools.r8.ir.desugar.constantdynamic.ConstantDynamicInstructionDesugaring;
import com.android.tools.r8.ir.desugar.desugaredlibrary.apiconversion.DesugaredLibraryAPIConverter;
@@ -34,6 +35,7 @@
import com.android.tools.r8.ir.desugar.twr.TwrInstructionDesugaring;
import com.android.tools.r8.ir.desugar.varhandle.VarHandleDesugaring;
import com.android.tools.r8.position.MethodPosition;
+import com.android.tools.r8.utils.Box;
import com.android.tools.r8.utils.IntBox;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.SetUtils;
@@ -249,13 +251,33 @@
CfDesugaringInfoImpl desugaringInfo = new CfDesugaringInfoImpl(cfCode.bytecodeSizeUpperBound());
+ Box<Position> currentPosition = new Box<>();
+ boolean maintainPositionForInlineInfo = appView.options().hasMappingFileSupport();
+ if (maintainPositionForInlineInfo) {
+ currentPosition.set(cfCode.getPreamblePosition());
+ if (!currentPosition.isSet()) {
+ currentPosition.set(
+ Position.SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(method.getReference())
+ .setIsD8R8Synthesized(method.getDefinition().isD8R8Synthesized())
+ .build());
+ }
+ }
List<CfInstruction> desugaredInstructions =
ListUtils.flatMapSameType(
cfCode.getInstructions(),
instruction -> {
+ if (instruction.isPosition()) {
+ if (maintainPositionForInlineInfo) {
+ currentPosition.set(instruction.asPosition().getPosition());
+ }
+ return null;
+ }
Collection<CfInstruction> replacement =
desugarInstruction(
instruction,
+ currentPosition.get(),
maxLocalsForInstruction::getAndIncrement,
maxStackForInstruction::getAndIncrement,
desugaringInfo,
@@ -315,6 +337,7 @@
@Override
public Collection<CfInstruction> desugarInstruction(
CfInstruction instruction,
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
@@ -325,6 +348,7 @@
Collection<CfInstruction> replacement =
applyDesugaring(
instruction,
+ position,
freshLocalProvider,
localStackAllocator,
desugaringInfo,
@@ -339,6 +363,7 @@
// desugaring and no other desugaring happened.
return applyDesugaring(
instruction,
+ position,
freshLocalProvider,
localStackAllocator,
desugaringInfo,
@@ -350,6 +375,7 @@
private Collection<CfInstruction> applyDesugaring(
CfInstruction instruction,
+ Position position,
FreshLocalProvider freshLocalProvider,
LocalStackAllocator localStackAllocator,
CfDesugaringInfo desugaringInfo,
@@ -363,6 +389,7 @@
desugaring
.compute(instruction, context)
.desugarInstruction(
+ position,
freshLocalProvider,
localStackAllocator,
desugaringInfo,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/UnrepresentableInDexInstructionRemover.java b/src/main/java/com/android/tools/r8/ir/desugar/UnrepresentableInDexInstructionRemover.java
index 4a64cba..f713b03 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/UnrepresentableInDexInstructionRemover.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/UnrepresentableInDexInstructionRemover.java
@@ -165,7 +165,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -219,7 +220,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -269,7 +271,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -313,7 +316,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -358,7 +362,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
index a1657bd..bc82617 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/apimodel/ApiInvokeOutlinerDesugaring.java
@@ -74,7 +74,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java
index d8796a6..4577688 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/constantdynamic/ConstantDynamicInstructionDesugaring.java
@@ -95,7 +95,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
index 0bb4dff..9a5056b 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/apiconversion/DesugaredLibraryAPIConverter.java
@@ -96,7 +96,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/disabledesugarer/DesugaredLibraryDisableDesugarer.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/disabledesugarer/DesugaredLibraryDisableDesugarer.java
index 5028df9..f3d1a6d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/disabledesugarer/DesugaredLibraryDisableDesugarer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/disabledesugarer/DesugaredLibraryDisableDesugarer.java
@@ -49,7 +49,8 @@
private DesugarDescription compute(CfInstruction replacement) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryLibRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryLibRewriter.java
index 7776a31..17c3a51 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryLibRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryLibRewriter.java
@@ -98,7 +98,8 @@
if (instruction.isInvoke() && rewritings.containsKey(instruction.asInvoke().getMethod())) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
index d83a724..c3a58c1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/retargeter/DesugaredLibraryRetargeter.java
@@ -107,7 +107,8 @@
methodProvider) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -134,7 +135,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
index 0d70826..1204cd0 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/icce/AlwaysThrowingInstructionDesugaring.java
@@ -70,7 +70,8 @@
AppView<?> appView, CfInvoke invoke, MethodResolutionResult resolutionResult) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -94,7 +95,8 @@
DesugarDescription.Builder builder =
DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
index 0dd9fec..56c3342 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/invokespecial/InvokeSpecialToSelfDesugaring.java
@@ -68,7 +68,8 @@
private DesugarDescription desugarToInvokeVirtual(CfInvoke invoke) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -84,7 +85,8 @@
private DesugarDescription desugarWithBridge(CfInvoke invoke, ProgramMethod method) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
index 275d2c2..2ff0fe6 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/InterfaceMethodRewriter.java
@@ -431,7 +431,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -481,7 +482,8 @@
DexClassAndMethod method = resolutionResult.getResolutionPair();
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -528,7 +530,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -577,7 +580,8 @@
assert directTarget.getDefinition() == singleResolution.getResolutionPair().getDefinition();
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -618,7 +622,8 @@
== singleResolution.getResolutionPair().getDefinition();
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -739,7 +744,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -763,7 +769,8 @@
} else {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -828,7 +835,8 @@
if (holder.isLibraryClass() && holder.isInterface()) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -856,7 +864,8 @@
}
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
index 6eb429f..e721972 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/lambda/LambdaInstructionDesugaring.java
@@ -78,7 +78,8 @@
private DesugarDescription desugarInstruction(CfInstruction instruction) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -97,6 +98,7 @@
(invoke, localProvider, stackAllocator) ->
desugaringCollection.desugarInstruction(
invoke,
+ position,
localProvider,
stackAllocator,
desugaringInfo,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
index 6678a66..127dff5 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/nest/NestBasedAccessDesugaring.java
@@ -335,7 +335,8 @@
private DesugarDescription desugarFieldInstruction(CfFieldInstruction instruction) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -366,7 +367,8 @@
private DesugarDescription desugarInvokeInstruction(CfInvoke invoke) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
index cb8592e..7aea6c8 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/records/RecordDesugaring.java
@@ -197,7 +197,8 @@
private DesugarDescription desugarInvokeDynamic(CfInstruction instruction) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -217,7 +218,8 @@
private DesugarDescription desugarInvoke(CfInvoke invoke, DexMethod newMethod) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java
index eda990b..5d5672a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/stringconcat/StringConcatInstructionDesugaring.java
@@ -91,7 +91,8 @@
private DesugarDescription desugarMakeConcat(CfInvokeDynamic invoke) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -127,7 +128,8 @@
private DesugarDescription desugarMakeConcatWithConstants(CfInvokeDynamic invoke) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java
index a0ec6dd..bb9ac0e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/twr/TwrInstructionDesugaring.java
@@ -68,7 +68,8 @@
factory.createProto(factory.voidType, factory.throwableType, factory.throwableType);
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -93,7 +94,8 @@
factory.createArrayType(1, factory.throwableType), factory.throwableType);
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -115,7 +117,8 @@
// Synthesize a new method.
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
index 18ddcef..273ab78 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/varhandle/VarHandleDesugaring.java
@@ -324,7 +324,8 @@
public DesugarDescription computeMethodHandlesLookup(DexItemFactory factory) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -351,7 +352,8 @@
public DesugarDescription computeMethodHandlesPrivateLookupIn(DexItemFactory factory) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -378,7 +380,8 @@
public DesugarDescription computeMethodHandlesArrayElementVarHandle(DexItemFactory factory) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
@@ -406,7 +409,8 @@
CfInvoke invoke, int coordinates) {
return DesugarDescription.builder()
.setDesugarRewrite(
- (freshLocalProvider,
+ (position,
+ freshLocalProvider,
localStackAllocator,
desugaringInfo,
eventConsumer,
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 5756529..ee0ce51 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -112,7 +112,7 @@
}
public void write(ClassFileConsumer consumer) {
- assert options.mapConsumer == null;
+ assert !options.hasMappingFileSupport();
write(consumer, null);
}
@@ -138,7 +138,7 @@
private void writeApplication(AndroidApp inputApp, ClassFileConsumer consumer) {
ProguardMapId proguardMapId = null;
- if (options.mapConsumer != null) {
+ if (options.hasMappingFileSupport()) {
assert marker.isPresent();
proguardMapId =
runAndWriteMap(
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 6ea5e06..662c236 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1158,6 +1158,10 @@
// If non null it must be and passed to the consumer.
public MapConsumer mapConsumer = null;
+ public boolean hasMappingFileSupport() {
+ return mapConsumer != null;
+ }
+
// If null, no usage information needs to be computed.
// If non-null, it must be and is passed to the consumer.
public StringConsumer usageInformationConsumer = null;
diff --git a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
index 12a6f21..06f9e6d 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/LineNumberOptimizer.java
@@ -46,7 +46,7 @@
Timing timing,
OriginalSourceFiles originalSourceFiles,
DebugRepresentationPredicate representation) {
- assert appView.options().mapConsumer != null;
+ assert appView.options().hasMappingFileSupport();
if (shouldEmitOriginalMappingFile(appView)) {
appView.options().reporter.warning(new NotSupportedMapVersionForMappingComposeDiagnostic());
timing.begin("Write proguard map");
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullClass.java b/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullClass.java
new file mode 100644
index 0000000..af6f091
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullClass.java
@@ -0,0 +1,24 @@
+// Copyright (c) 2024, 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.retrace;
+
+import java.util.Objects;
+
+public class RetraceObjectsRequireNonNullClass {
+
+ public static class A {
+
+ public void run(Object o) {
+ Objects.requireNonNull(o);
+ }
+ }
+
+ public static class Main {
+
+ public static void main(String[] args) {
+ (System.nanoTime() > 0 ? new A() : null).run(System.nanoTime() > 0 ? null : new A());
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullTest.java b/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullTest.java
new file mode 100644
index 0000000..de82421
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNonNullTest.java
@@ -0,0 +1,190 @@
+// Copyright (c) 2024, 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.retrace;
+
+import static com.android.tools.r8.naming.retrace.StackTrace.isSame;
+import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForLineNumbers;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import com.android.tools.r8.SingleTestRunResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.TestRuntime.CfVm;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.naming.retrace.StackTrace;
+import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
+import com.android.tools.r8.references.ClassReference;
+import com.android.tools.r8.references.Reference;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.Objects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class RetraceObjectsRequireNonNullTest extends TestBase {
+
+ static final Class<?> CLASS = RetraceObjectsRequireNonNullClass.class;
+ static final Class<?> CLASS_A = RetraceObjectsRequireNonNullClass.A.class;
+ static final Class<?> CLASS_MAIN = RetraceObjectsRequireNonNullClass.Main.class;
+
+ static List<Class<?>> getInputClasses() {
+ return ImmutableList.of(CLASS, CLASS_A, CLASS_MAIN);
+ }
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection parameters() {
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
+ }
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ private boolean isCfVmWithModulePrefix() {
+ return parameters.isCfRuntime() && !parameters.isCfRuntime(CfVm.JDK8);
+ }
+
+ private boolean isApiWithRequireNonNullSupport() {
+ return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.K);
+ }
+
+ @Test
+ public void testReference() throws Exception {
+ parameters.assumeJvmTestParameters();
+ boolean includeObjectsFrame = true;
+ boolean includeJvmModule = isCfVmWithModulePrefix();
+ boolean doNotCheckLines = true;
+ testForJvm(parameters)
+ .addProgramClasses(getInputClasses())
+ .run(parameters.getRuntime(), CLASS_MAIN)
+ .apply(this::checkRunResult)
+ .inspectStackTrace(
+ stackTrace ->
+ checkExpectedStackTrace(
+ stackTrace, includeObjectsFrame, includeJvmModule, doNotCheckLines));
+ }
+
+ @Test
+ public void testD8() throws Exception {
+ boolean includeObjectsFrame = isApiWithRequireNonNullSupport();
+ boolean includeJvmModule = includeObjectsFrame && isCfVmWithModulePrefix();
+ boolean doNotCheckLines = includeObjectsFrame;
+ testForD8(parameters.getBackend())
+ .addProgramClasses(getInputClasses())
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), CLASS_MAIN)
+ .apply(this::checkRunResult)
+ .inspectStackTrace(
+ stackTrace ->
+ checkExpectedStackTrace(
+ stackTrace, includeObjectsFrame, includeJvmModule, doNotCheckLines));
+ }
+
+ @Test
+ public void testD8DebugRetrace() throws Exception {
+ boolean includeObjectsFrame = true;
+ boolean includeJvmModule = isApiWithRequireNonNullSupport() && isCfVmWithModulePrefix();
+ boolean doNotCheckLines = isApiWithRequireNonNullSupport();
+ testForD8(parameters.getBackend())
+ .debug()
+ .internalEnableMappingOutput()
+ .addProgramClasses(getInputClasses())
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), CLASS_MAIN)
+ .apply(this::checkRunResult)
+ .inspectStackTrace(
+ stackTrace ->
+ checkExpectedStackTrace(
+ stackTrace, includeObjectsFrame, includeJvmModule, doNotCheckLines));
+ }
+
+ @Test
+ public void testD8ReleaseRetrace() throws Exception {
+ boolean includeObjectsFrame = true;
+ boolean includeJvmModule = isApiWithRequireNonNullSupport() && isCfVmWithModulePrefix();
+ boolean doNotCheckLines = isApiWithRequireNonNullSupport();
+ testForD8(parameters.getBackend())
+ .release()
+ .internalEnableMappingOutput()
+ .addProgramClasses(getInputClasses())
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), CLASS_MAIN)
+ .apply(this::checkRunResult)
+ .inspectStackTrace(
+ stackTrace ->
+ checkExpectedStackTrace(
+ stackTrace, includeObjectsFrame, includeJvmModule, doNotCheckLines));
+ }
+
+ @Test
+ public void testR8() throws Exception {
+ parameters.assumeR8TestParameters();
+ boolean includeObjectsFrame = true;
+ boolean includeJvmModule = isCfVmWithModulePrefix();
+ boolean doNotCheckLines = parameters.isCfRuntime() || isApiWithRequireNonNullSupport();
+ testForR8(parameters.getBackend())
+ .addProgramClasses(getInputClasses())
+ .addKeepMainRule(CLASS_MAIN)
+ .addKeepAttributeSourceFile()
+ .addKeepAttributeLineNumberTable()
+ .setMinApi(parameters)
+ .run(parameters.getRuntime(), CLASS_MAIN)
+ .apply(this::checkRunResult)
+ .inspectStackTrace(
+ stackTrace ->
+ checkExpectedStackTrace(
+ stackTrace, includeObjectsFrame, includeJvmModule, doNotCheckLines));
+ }
+
+ private void checkRunResult(SingleTestRunResult<?> runResult) {
+ runResult.assertFailureWithErrorThatThrows(NullPointerException.class);
+ }
+
+ private void checkExpectedStackTrace(
+ StackTrace stackTrace,
+ boolean includeObjectsFrame,
+ boolean includeJvmModule,
+ boolean doNotCheckLines) {
+ StackTrace.Builder builder = StackTrace.builder();
+ if (includeObjectsFrame) {
+ ClassReference objects = Reference.classFromClass(Objects.class);
+ String objectsFrameFormat = (includeJvmModule ? "java.base/" : "") + objects.getTypeName();
+ builder.add(
+ StackTraceLine.builder()
+ .setFileName("Objects.java")
+ .setClassName(objectsFrameFormat)
+ .setMethodName("requireNonNull")
+ .setLineNumber(-1)
+ .build());
+ }
+ String fileName = ToolHelper.getSourceFileForTestClass(CLASS).getFileName().toString();
+ builder
+ .add(
+ StackTraceLine.builder()
+ .setFileName(fileName)
+ .setClassName(typeName(CLASS_A))
+ .setMethodName("run")
+ .setLineNumber(14)
+ .build())
+ .add(
+ StackTraceLine.builder()
+ .setFileName(fileName)
+ .setClassName(typeName(CLASS_MAIN))
+ .setMethodName("main")
+ .setLineNumber(21)
+ .build());
+ if (doNotCheckLines) {
+ // We can't check the line numbers when using the native support of Objects.requireNonNull.
+ assertThat(stackTrace, isSameExceptForLineNumbers(builder.build()));
+ } else {
+ assertThat(stackTrace, isSame(builder.build()));
+ }
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNotNullTest.java b/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNotNullTest.java
deleted file mode 100644
index 91628fc..0000000
--- a/src/test/java/com/android/tools/r8/retrace/RetraceObjectsRequireNotNullTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2024, 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.retrace;
-
-import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import com.android.tools.r8.SingleTestRunResult;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.TestRuntime.CfVm;
-import com.android.tools.r8.naming.retrace.StackTrace;
-import com.android.tools.r8.references.ClassReference;
-import com.android.tools.r8.references.Reference;
-import com.android.tools.r8.utils.AndroidApiLevel;
-import java.util.Objects;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class RetraceObjectsRequireNotNullTest extends TestBase {
-
- @Parameters(name = "{0}")
- public static TestParametersCollection parameters() {
- return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
- }
-
- @Parameter(0)
- public TestParameters parameters;
-
- private boolean isCfVmWithModulePrefix() {
- return parameters.isCfRuntime() && !parameters.isCfRuntime(CfVm.JDK8);
- }
-
- private boolean isApiWithRequireNonNullSupport() {
- return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.K);
- }
-
- @Test
- public void testReference() throws Exception {
- parameters.assumeJvmTestParameters();
- testForJvm(parameters)
- .addInnerClasses(getClass())
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkRunResult)
- .inspectStackTrace(
- stackTrace -> checkExpectedStackTrace(stackTrace, true, isCfVmWithModulePrefix()));
- }
-
- @Test
- public void testD8() throws Exception {
- boolean includeObjectsFrame = isApiWithRequireNonNullSupport();
- boolean includeJvmModule = isApiWithRequireNonNullSupport() && isCfVmWithModulePrefix();
- testForD8(parameters.getBackend())
- .addInnerClasses(getClass())
- .setMinApi(parameters)
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkRunResult)
- .inspectStackTrace(
- stackTrace ->
- checkExpectedStackTrace(stackTrace, includeObjectsFrame, includeJvmModule));
- }
-
- @Test
- public void testD8DebugRetrace() throws Exception {
- boolean includeObjectsFrame = isApiWithRequireNonNullSupport();
- boolean includeJvmModule = isApiWithRequireNonNullSupport() && isCfVmWithModulePrefix();
- testForD8(parameters.getBackend())
- .debug()
- .internalEnableMappingOutput()
- .addInnerClasses(getClass())
- .setMinApi(parameters)
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkRunResult)
- .inspectStackTrace(
- stackTrace ->
- checkExpectedStackTrace(
- stackTrace,
- // TODO(b/326196974): This should always retrace to include the objects frame.
- includeObjectsFrame,
- includeJvmModule));
- }
-
- @Test
- public void testD8ReleaseRetrace() throws Exception {
- boolean includeObjectsFrame = isApiWithRequireNonNullSupport();
- boolean includeJvmModule = isCfVmWithModulePrefix();
- testForD8(parameters.getBackend())
- .release()
- .internalEnableMappingOutput()
- .addInnerClasses(getClass())
- .setMinApi(parameters)
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkRunResult)
- .inspectStackTrace(
- stackTrace ->
- checkExpectedStackTrace(
- stackTrace,
- // TODO(b/326196974): This should always retrace to include the objects frame.
- includeObjectsFrame,
- includeJvmModule));
- }
-
- @Test
- public void testR8() throws Exception {
- parameters.assumeR8TestParameters();
- testForR8(parameters.getBackend())
- .addInnerClasses(getClass())
- .addKeepMainRule(Main.class)
- .addKeepAttributeSourceFile()
- .addKeepAttributeLineNumberTable()
- .setMinApi(parameters)
- .run(parameters.getRuntime(), Main.class)
- .apply(this::checkRunResult)
- .inspectStackTrace(
- stackTrace ->
- checkExpectedStackTrace(
- stackTrace,
- // TODO(b/326196974): This should always retrace to include the objects frame.
- parameters.isCfRuntime() || isApiWithRequireNonNullSupport(),
- isCfVmWithModulePrefix()));
- }
-
- private void checkRunResult(SingleTestRunResult<?> runResult) {
- runResult.assertFailureWithErrorThatThrows(NullPointerException.class);
- }
-
- private void checkExpectedStackTrace(
- StackTrace stackTrace, boolean includeObjectsFrame, boolean includeJvmModule) {
- StackTrace.Builder builder = StackTrace.builder();
- if (includeObjectsFrame) {
- ClassReference objects = Reference.classFromClass(Objects.class);
- String objectsFrameFormat = (includeJvmModule ? "java.base/" : "") + objects.getTypeName();
- builder.addWithoutFileNameAndLineNumber(objectsFrameFormat, "requireNonNull");
- }
- builder
- .addWithoutFileNameAndLineNumber(A.class, "run")
- .addWithoutFileNameAndLineNumber(Main.class, "main");
- assertThat(stackTrace, isSameExceptForFileNameAndLineNumber(builder.build()));
- }
-
- public static class A {
- public void run(Object o) {
- Objects.requireNonNull(o);
- }
- }
-
- public static class Main {
-
- public static void main(String[] args) {
- (System.nanoTime() > 0 ? new A() : null).run(System.nanoTime() > 0 ? null : new A());
- }
- }
-}