Modify Position to use sub types for synthetics
Change-Id: I787d2a28182e1f79eaf08d8e8924706d396ff8d3
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index d68ff6b..dcc55b1 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -994,7 +994,7 @@
continue;
}
CfPosition position = instruction.asPosition();
- assert position.getPosition().getOutermostCaller().method == originalMethod;
+ assert position.getPosition().getOutermostCaller().getMethod() == originalMethod;
}
return true;
}
diff --git a/src/main/java/com/android/tools/r8/cf/CfPrinter.java b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
index 98808c7..3bdfcbf 100644
--- a/src/main/java/com/android/tools/r8/cf/CfPrinter.java
+++ b/src/main/java/com/android/tools/r8/cf/CfPrinter.java
@@ -555,8 +555,8 @@
public void print(CfPosition instruction) {
Position position = instruction.getPosition();
indent();
- builder.append(".line ").append(position.line);
- if (position.file != null || position.callerPosition != null) {
+ builder.append(".line ").append(position.getLine());
+ if (position.hasCallerPosition() || position.hasFile()) {
appendComment(position.toString());
}
}
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
index 45077e2..327bb51 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfPosition.java
@@ -47,7 +47,7 @@
this,
(CfPosition) other,
spec ->
- spec.withInt(p -> p.position.line)
+ spec.withInt(p -> p.position.getLine())
.withCustomItem(p -> p.label, helper.labelAcceptor()));
}
@@ -61,7 +61,7 @@
NamingLens namingLens,
LensCodeRewriterUtils rewriter,
MethodVisitor visitor) {
- visitor.visitLineNumber(position.line, label.getLabel());
+ visitor.visitLineNumber(position.getLine(), label.getLabel());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/graph/CfCode.java b/src/main/java/com/android/tools/r8/graph/CfCode.java
index c043d4a..4589a49 100644
--- a/src/main/java/com/android/tools/r8/graph/CfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/CfCode.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.conversion.CfSourceCode;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
@@ -763,7 +764,7 @@
@Override
public Code getCodeAsInlining(DexMethod caller, DexMethod callee) {
- Position callerPosition = Position.synthetic(0, caller, null);
+ Position callerPosition = SyntheticPosition.builder().setLine(0).setMethod(caller).build();
List<CfInstruction> newInstructions = new ArrayList<>(instructions.size() + 2);
CfLabel firstLabel;
if (instructions.get(0).isLabel()) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexCode.java b/src/main/java/com/android/tools/r8/graph/DexCode.java
index 8409ee1..3dd956f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -15,6 +15,7 @@
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.conversion.DexSourceCode;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.LensCodeRewriterUtils;
@@ -180,7 +181,7 @@
}
private DexDebugInfo debugInfoAsInlining(DexMethod caller, DexMethod callee) {
- Position callerPosition = Position.synthetic(0, caller, null);
+ Position callerPosition = SyntheticPosition.builder().setLine(0).setMethod(caller).build();
if (debugInfo == null) {
// If the method has no debug info we generate a preamble position to denote the inlining.
// This is consistent with the building IR for inlining which will always ensure the method
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java b/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java
index 8eb786a..2547996 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java
@@ -63,8 +63,8 @@
builder.append(":").append(method.name);
Position caller = callerPosition;
while (caller != null) {
- builder.append(";").append(caller.line).append(":").append(caller.method.name);
- caller = caller.callerPosition;
+ builder.append(";").append(caller.getLine()).append(":").append(caller.getMethod().name);
+ caller = caller.getCallerPosition();
}
}
if (prologueEnd) {
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java b/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
index dfd4f1c..30fb21f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEvent.java
@@ -579,7 +579,7 @@
public boolean hasOuterPosition(DexMethod method) {
return (caller == null && callee == method)
- || (caller != null && caller.getOutermostCaller().method == method);
+ || (caller != null && caller.getOutermostCaller().getMethod() == method);
}
}
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
index 7a8a3f6..bdb2633 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEventBuilder.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
import com.android.tools.r8.utils.InternalOptions;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap.Entry;
@@ -183,17 +184,17 @@
assert !position.equals(emittedPosition);
if (startLine == NO_LINE_INFO) {
assert emittedPosition.isNone();
- if (position.synthetic && position.callerPosition == null) {
+ if (position.isSyntheticPosition() && !position.hasCallerPosition()) {
// Ignore synthetic positions prior to any actual position.
// We do need to preserve synthetic position establishing the stack frame for inlined
// methods.
return;
}
- startLine = position.line;
+ startLine = position.getLine();
emittedPosition =
- Position.builder()
- .setLine(position.line)
- .setMethod(position.getOutermostCaller().method)
+ SourcePosition.builder()
+ .setLine(position.getLine())
+ .setMethod(position.getOutermostCaller().getMethod())
.build();
}
assert emittedPc != pc;
@@ -235,21 +236,22 @@
assert previousPc >= 0;
int pcDelta = nextPc - previousPc;
assert !previousPosition.isNone() || nextPosition.isNone();
- assert nextPosition.isNone() || nextPosition.line >= 0;
- int lineDelta = nextPosition.isNone() ? 0 : nextPosition.line - previousPosition.line;
+ assert nextPosition.isNone() || nextPosition.getLine() >= 0;
+ int lineDelta = nextPosition.isNone() ? 0 : nextPosition.getLine() - previousPosition.getLine();
assert pcDelta >= 0;
- if (nextPosition.file != previousPosition.file) {
- events.add(factory.createSetFile(nextPosition.file));
+ if (nextPosition.getFile() != previousPosition.getFile()) {
+ events.add(factory.createSetFile(nextPosition.getFile()));
}
// The LineNumberOptimizer maps new positions based on the outer most caller with
// callerPosition == null.
- assert null != nextPosition.callerPosition
- || null != previousPosition.callerPosition
- || nextPosition.method == previousPosition.method
+ assert nextPosition.hasCallerPosition()
+ || previousPosition.hasCallerPosition()
+ || nextPosition.getMethod() == previousPosition.getMethod()
|| optimizingLineNumbers;
- if (nextPosition.callerPosition != previousPosition.callerPosition
- || nextPosition.method != previousPosition.method) {
- events.add(factory.createSetInlineFrame(nextPosition.method, nextPosition.callerPosition));
+ if (nextPosition.getCallerPosition() != previousPosition.getCallerPosition()
+ || nextPosition.getMethod() != previousPosition.getMethod()) {
+ events.add(
+ factory.createSetInlineFrame(nextPosition.getMethod(), nextPosition.getCallerPosition()));
}
if (lineDelta < Constants.DBG_LINE_BASE
|| lineDelta - Constants.DBG_LINE_BASE >= Constants.DBG_LINE_RANGE) {
diff --git a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
index 0aaa24e..f111c9e 100644
--- a/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
+++ b/src/main/java/com/android/tools/r8/graph/LazyCfCode.java
@@ -57,6 +57,7 @@
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.NumberGenerator;
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.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
@@ -1007,7 +1008,7 @@
if (debugParsingOptions.lineInfo) {
instructions.add(
new CfPosition(
- getLabel(start), Position.builder().setLine(line).setMethod(method).build()));
+ getLabel(start), SourcePosition.builder().setLine(line).setMethod(method).build()));
}
}
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
index e68cc71..66251ba 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/InstanceInitializerDescription.java
@@ -28,6 +28,7 @@
import com.android.tools.r8.ir.analysis.value.SingleConstValue;
import com.android.tools.r8.ir.analysis.value.SingleDexItemBasedStringValue;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.utils.IntBox;
@@ -110,8 +111,14 @@
ImmutableList.Builder<CfInstruction> instructionBuilder = ImmutableList.builder();
// Set position.
- Position callerPosition = Position.synthetic(0, syntheticMethodReference, null);
- Position calleePosition = Position.synthetic(0, originalMethodReference, callerPosition);
+ Position callerPosition =
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
+ Position calleePosition =
+ SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(originalMethodReference)
+ .setCallerPosition(callerPosition)
+ .build();
CfPosition position = new CfPosition(new CfLabel(), calleePosition);
instructionBuilder.add(position);
instructionBuilder.add(position.getLabel());
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
index 8372926..085276f 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/code/ClassInitializerMerger.java
@@ -32,6 +32,7 @@
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.origin.Origin;
@@ -132,7 +133,8 @@
public CfCode build(DexMethod syntheticMethodReference) {
// Building the instructions will adjust maxStack and maxLocals. Build it here before invoking
// the CfCode constructor to ensure that the value passed in is the updated values.
- Position callerPosition = Position.synthetic(0, syntheticMethodReference, null);
+ Position callerPosition =
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
List<CfInstruction> instructions = buildInstructions(callerPosition);
return new CfCode(
syntheticMethodReference.getHolderType(),
@@ -201,7 +203,8 @@
public IRCode buildIR(ProgramMethod method, AppView<?> appView, Origin origin) {
assert !classInitializers.isEmpty();
- Position callerPosition = Position.synthetic(0, syntheticMethodReference, null);
+ Position callerPosition =
+ SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
IRMetadata metadata = new IRMetadata();
NumberGenerator blockNumberGenerator = new NumberGenerator();
NumberGenerator valueNumberGenerator = new NumberGenerator();
diff --git a/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java b/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
index ad16c77..85467b7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CanonicalPositions.java
@@ -5,6 +5,8 @@
package com.android.tools.r8.ir.code;
import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
@@ -36,7 +38,7 @@
methodIsSynthesized
? callerPosition
: getCanonical(
- Position.builder()
+ SourcePosition.builder()
.setLine(0)
.setMethod(method)
.setCallerPosition(callerPosition)
@@ -44,7 +46,8 @@
} else {
this.callerPosition = null;
isCompilerSynthesizedInlinee = false;
- preamblePosition = getCanonical(Position.synthetic(0, method, null));
+ preamblePosition =
+ getCanonical(SyntheticPosition.builder().setLine(0).setMethod(method).build());
}
}
@@ -81,7 +84,11 @@
Position callerOfCaller = canonicalizeCallerPosition(caller.callerPosition);
return getCanonical(
caller.isNone()
- ? Position.noneWithMethod(caller.method, callerOfCaller)
+ ? SourcePosition.builder()
+ .setMethod(caller.method)
+ .setCallerPosition(callerOfCaller)
+ .disableLineCheck()
+ .build()
: caller.builderWithCopy().setCallerPosition(callerOfCaller).build());
}
@@ -106,7 +113,11 @@
syntheticPosition =
(min == Integer.MAX_VALUE)
? getPreamblePosition()
- : Position.synthetic(min < max ? min - 1 : min, originalMethod, callerPosition);
+ : SyntheticPosition.builder()
+ .setLine(min < max ? min - 1 : min)
+ .setMethod(originalMethod)
+ .setCallerPosition(callerPosition)
+ .build();
} else {
// If in release mode we explicitly associate a synthetic none position with monitor exit.
// This is safe as the runtime must never throw at this position because the monitor cannot
diff --git a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
index c347f87..d4d76da 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DebugPosition.java
@@ -42,7 +42,7 @@
@Override
public void buildDex(DexBuilder builder) {
- assert getPosition().isSome() && !getPosition().synthetic;
+ assert getPosition().isSome() && !getPosition().isSyntheticPosition();
builder.addDebugPosition(this);
}
@@ -84,7 +84,7 @@
@Override
public void buildCf(CfBuilder builder) {
- assert getPosition().isSome() && !getPosition().synthetic;
+ assert getPosition().isSome() && !getPosition().isSyntheticPosition();
// All redundant debug positions are removed. Remaining ones must force a pc advance.
builder.add(new CfNop());
}
diff --git a/src/main/java/com/android/tools/r8/ir/code/Position.java b/src/main/java/com/android/tools/r8/ir/code/Position.java
index cb2ff68..25cbfdf 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Position.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Position.java
@@ -7,114 +7,110 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.ProgramMethod;
+import com.android.tools.r8.utils.structural.Equatable;
+import com.android.tools.r8.utils.structural.HashCodeVisitor;
import com.android.tools.r8.utils.structural.StructuralItem;
import com.android.tools.r8.utils.structural.StructuralMapping;
import com.android.tools.r8.utils.structural.StructuralSpecification;
-import com.google.common.annotations.VisibleForTesting;
-import java.util.Objects;
-public class Position implements StructuralItem<Position> {
+public abstract class Position implements StructuralItem<Position> {
- // A no-position marker. Not having a position means the position is implicitly defined by the
- // context, e.g., the marker does not materialize anything concrete.
- private static final Position NO_POSITION = new Position(-1, null, null, null, false, false);
+ // Compare ID(s) for positions.
+ private static final int SOURCE_POSITION_COMPARE_ID = 1;
+ private static final int SYNTHETIC_POSITION_COMPARE_ID = 2;
- // A synthetic marker position that should never materialize.
- // This is used specifically to mark exceptional exit blocks from synchronized methods in release.
- private static final Position NO_POSITION_SYNTHETIC =
- new Position(-1, null, null, null, true, false);
-
- // Fake position to use for representing an actual position in testing code.
- private static final Position TESTING_POSITION = new Position(0, null, null, null, true, false);
-
- public final int line;
- public final DexString file;
- public final boolean synthetic;
+ protected final int line;
+ protected final DexMethod method;
// If there's no inlining, callerPosition is null.
//
// For an inlined instruction its Position contains the inlinee's line and method and
// callerPosition is the position of the invoke instruction in the caller.
+ protected final Position callerPosition;
- public final DexMethod method;
- public final Position callerPosition;
- public final boolean removeInnerFrameIfThrowingNpe;
-
- private static void specify(StructuralSpecification<Position, ?> spec) {
- spec.withInt(p -> p.line)
- .withNullableItem(p -> p.file)
- .withBool(p -> p.synthetic)
- .withNullableItem(p -> p.method)
- .withNullableItem(p -> p.callerPosition);
- }
+ private final boolean removeInnerFramesIfThrowingNpe;
private Position(
- int line,
- DexString file,
- DexMethod method,
- Position callerPosition,
- boolean synthetic,
- boolean removeInnerFrameIfThrowingNpe) {
+ int line, DexMethod method, Position callerPosition, boolean removeInnerFramesIfThrowingNpe) {
this.line = line;
- this.file = file;
- this.synthetic = synthetic;
this.method = method;
this.callerPosition = callerPosition;
- this.removeInnerFrameIfThrowingNpe = removeInnerFrameIfThrowingNpe;
- assert callerPosition == null || callerPosition.method != null;
+ this.removeInnerFramesIfThrowingNpe = removeInnerFramesIfThrowingNpe;
}
- public static Position synthetic(int line, DexMethod method, Position callerPosition) {
- assert line >= 0;
- assert method != null;
- return new Position(line, null, method, callerPosition, true, false);
+ public boolean isSyntheticPosition() {
+ return false;
}
- public static Position none() {
- return NO_POSITION;
+ public boolean isAdditionalMappingInfoPosition() {
+ return false;
}
- public static Position syntheticNone() {
- return NO_POSITION_SYNTHETIC;
- }
-
- @VisibleForTesting
- public static Position testingPosition() {
- return TESTING_POSITION;
- }
-
- // This factory method is used by the Inliner to create Positions when the caller has no valid
- // positions. Since the callee still may have valid positions we need a non-null Position to set
- // it as the caller of the inlined Positions.
- public static Position noneWithMethod(DexMethod method, Position callerPosition) {
- assert method != null;
- return new Position(-1, null, method, callerPosition, false, false);
- }
-
- public static Position getPositionForInlining(
- AppView<?> appView, InvokeMethod invoke, ProgramMethod context) {
- Position position = invoke.getPosition();
- if (position.method == null) {
- assert position.isNone();
- position = Position.noneWithMethod(context.getReference(), null);
- }
- assert position.getOutermostCaller().method
- == appView.graphLens().getOriginalMethodSignature(context.getReference());
- return position;
+ public boolean isRemoveInnerFramesIfThrowingNpe() {
+ return removeInnerFramesIfThrowingNpe;
}
public boolean hasCallerPosition() {
return callerPosition != null;
}
+ public Position getCallerPosition() {
+ return callerPosition;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public DexMethod getMethod() {
+ return method;
+ }
+
+ public static Position none() {
+ return SourcePosition.NO_POSITION;
+ }
+
+ public boolean hasFile() {
+ return false;
+ }
+
+ public DexString getFile() {
+ return null;
+ }
+
@Override
public Position self() {
return this;
}
+ // Unique id to determine the ordering of positions
+ public abstract int getCompareToId();
+
@Override
- public StructuralMapping<Position> getStructuralMapping() {
- return Position::specify;
+ public abstract StructuralMapping<Position> getStructuralMapping();
+
+ private static void specifyBasePosition(StructuralSpecification<Position, ?> spec) {
+ spec.withInt(Position::getCompareToId)
+ .withInt(Position::getLine)
+ .withNullableItem(Position::getMethod)
+ .withNullableItem(Position::getCallerPosition)
+ .withBool(Position::isRemoveInnerFramesIfThrowingNpe);
+ }
+
+ public static Position syntheticNone() {
+ return SyntheticPosition.NO_POSITION_SYNTHETIC;
+ }
+
+ public static Position getPositionForInlining(
+ AppView<?> appView, InvokeMethod invoke, ProgramMethod context) {
+ Position position = invoke.getPosition();
+ if (position.method == null) {
+ assert position.isNone();
+ position = SourcePosition.builder().setMethod(context.getReference()).build();
+ }
+ assert position.getOutermostCaller().method
+ == appView.graphLens().getOriginalMethodSignature(context.getReference());
+ return position;
}
public boolean isNone() {
@@ -122,7 +118,7 @@
}
public boolean isSyntheticNone() {
- return this == NO_POSITION_SYNTHETIC;
+ return this == syntheticNone();
}
public boolean isSome() {
@@ -139,10 +135,6 @@
return lastPosition;
}
- public Position getCallerPosition() {
- return callerPosition;
- }
-
public Position withOutermostCallerPosition(Position newOutermostCallerPosition) {
return builderWithCopy()
.setCallerPosition(
@@ -153,14 +145,13 @@
}
@Override
- public boolean equals(Object other) {
- return other instanceof Position && compareTo((Position) other) == 0;
+ public final boolean equals(Object other) {
+ return Equatable.equalsImpl(this, other);
}
@Override
- public int hashCode() {
- return Objects.hash(
- line, file, synthetic, method, callerPosition, removeInnerFrameIfThrowingNpe);
+ public final int hashCode() {
+ return HashCodeVisitor.run(this);
}
private String toString(boolean forceMethod) {
@@ -168,8 +159,8 @@
return "--";
}
StringBuilder builder = new StringBuilder();
- if (file != null) {
- builder.append(file).append(":");
+ if (hasFile()) {
+ builder.append(getFile()).append(":");
}
builder.append("#").append(line);
if (method != null && (forceMethod || callerPosition != null)) {
@@ -190,64 +181,196 @@
return toString(false);
}
- public static Builder builder() {
- return new Builder();
- }
+ public abstract PositionBuilder<?, ?> builderWithCopy();
- public Builder builderWithCopy() {
- return new Builder()
- .setLine(line)
- .setFile(file)
- .setMethod(method)
- .setCallerPosition(callerPosition)
- .setSynthetic(synthetic)
- .setRemoveInnerFramesIfThrowingNpe(removeInnerFrameIfThrowingNpe);
- }
+ public abstract static class PositionBuilder<
+ P extends Position, B extends PositionBuilder<P, B>> {
- public static class Builder {
+ protected int line = -1;
+ protected DexMethod method;
+ protected Position callerPosition;
+ protected boolean removeInnerFramesIfThrowingNpe;
- public int line;
- public DexString file;
- public boolean synthetic;
- public DexMethod method;
- public Position callerPosition;
- public boolean removeInnerFrameIfThrowingNpe;
+ protected boolean noCheckOfPosition;
+ protected boolean noCheckOfMethod;
- public Builder setLine(int line) {
+ abstract B self();
+
+ public B setLine(int line) {
this.line = line;
- return this;
+ return self();
}
- public Builder setFile(DexString file) {
- this.file = file;
- return this;
- }
-
- public Builder setSynthetic(boolean synthetic) {
- this.synthetic = synthetic;
- return this;
- }
-
- public Builder setMethod(DexMethod method) {
+ public B setMethod(DexMethod method) {
this.method = method;
- return this;
+ return self();
}
- public Builder setCallerPosition(Position callerPosition) {
+ public B setCallerPosition(Position callerPosition) {
this.callerPosition = callerPosition;
- return this;
+ return self();
}
- public Builder setRemoveInnerFramesIfThrowingNpe(boolean removeInnerFramesIfThrowingNpe) {
- this.removeInnerFrameIfThrowingNpe = removeInnerFramesIfThrowingNpe;
- return this;
+ public B setRemoveInnerFramesIfThrowingNpe(boolean removeInnerFramesIfThrowingNpe) {
+ this.removeInnerFramesIfThrowingNpe = removeInnerFramesIfThrowingNpe;
+ return self();
}
- public Position build() {
- assert line >= 0;
- assert method != null;
- return new Position(
- line, file, method, callerPosition, synthetic, removeInnerFrameIfThrowingNpe);
+ public B disableLineCheck() {
+ noCheckOfPosition = true;
+ return self();
+ }
+
+ public B disableMethodCheck() {
+ noCheckOfMethod = true;
+ return self();
+ }
+
+ public abstract P build();
+ }
+
+ public static class SourcePosition extends Position {
+
+ // A no-position marker. Not having a position means the position is implicitly defined by the
+ // context, e.g., the marker does not materialize anything concrete.
+ private static final SourcePosition NO_POSITION =
+ new SourcePosition(-1, null, null, false, null);
+
+ public final DexString file;
+
+ private static void specify(StructuralSpecification<Position, ?> spec) {
+ spec.withSpec(Position::specifyBasePosition).withNullableItem(Position::getFile);
+ }
+
+ private SourcePosition(
+ int line,
+ DexMethod method,
+ Position callerPosition,
+ boolean removeInnerFramesIfThrowingNpe,
+ DexString file) {
+ super(line, method, callerPosition, removeInnerFramesIfThrowingNpe);
+ this.file = file;
+ assert callerPosition == null || callerPosition.method != null;
+ }
+
+ @Override
+ public boolean hasFile() {
+ return file != null;
+ }
+
+ @Override
+ public DexString getFile() {
+ return file;
+ }
+
+ @Override
+ public int getCompareToId() {
+ return SOURCE_POSITION_COMPARE_ID;
+ }
+
+ @Override
+ public PositionBuilder<?, ?> builderWithCopy() {
+ return builder()
+ .setLine(line)
+ .setFile(file)
+ .setMethod(method)
+ .setCallerPosition(callerPosition);
+ }
+
+ @Override
+ public StructuralMapping<Position> getStructuralMapping() {
+ return SourcePosition::specify;
+ }
+
+ public static SourcePositionBuilder builder() {
+ return new SourcePositionBuilder();
+ }
+
+ public static class SourcePositionBuilder
+ extends PositionBuilder<SourcePosition, SourcePositionBuilder> {
+
+ private DexString file;
+
+ @Override
+ SourcePositionBuilder self() {
+ return this;
+ }
+
+ public SourcePositionBuilder setFile(DexString file) {
+ this.file = file;
+ return this;
+ }
+
+ @Override
+ public SourcePosition build() {
+ assert noCheckOfPosition || line >= 0;
+ assert noCheckOfMethod || method != null;
+ return new SourcePosition(
+ line, method, callerPosition, removeInnerFramesIfThrowingNpe, file);
+ }
+ }
+ }
+
+ public static class SyntheticPosition extends Position {
+
+ // A synthetic marker position that should never materialize.
+ // This is used specifically to mark exceptional exit blocks from synchronized methods in
+ // release.
+ private static final Position NO_POSITION_SYNTHETIC =
+ new SyntheticPosition(-1, null, null, false);
+
+ private static void specify(StructuralSpecification<Position, ?> spec) {
+ spec.withSpec(Position::specifyBasePosition);
+ }
+
+ private SyntheticPosition(
+ int line,
+ DexMethod method,
+ Position callerPosition,
+ boolean removeInnerFramesIfThrowingNpe) {
+ super(line, method, callerPosition, removeInnerFramesIfThrowingNpe);
+ }
+
+ @Override
+ public boolean isSyntheticPosition() {
+ return true;
+ }
+
+ @Override
+ public int getCompareToId() {
+ return SYNTHETIC_POSITION_COMPARE_ID;
+ }
+
+ @Override
+ public PositionBuilder<?, ?> builderWithCopy() {
+ return builder().setLine(line).setMethod(method).setCallerPosition(callerPosition);
+ }
+
+ @Override
+ public StructuralMapping<Position> getStructuralMapping() {
+ return SyntheticPosition::specify;
+ }
+
+ public static SyntheticPositionBuilder builder() {
+ return new SyntheticPositionBuilder();
+ }
+
+ public static class SyntheticPositionBuilder
+ extends PositionBuilder<SyntheticPosition, SyntheticPositionBuilder> {
+
+ private SyntheticPositionBuilder() {}
+
+ @Override
+ SyntheticPositionBuilder self() {
+ return this;
+ }
+
+ @Override
+ public SyntheticPosition build() {
+ assert noCheckOfPosition || line >= 0;
+ assert noCheckOfMethod || method != null;
+ return new SyntheticPosition(line, method, callerPosition, removeInnerFramesIfThrowingNpe);
+ }
}
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
index 0085b70..b358828 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfBuilder.java
@@ -519,7 +519,9 @@
&& position != currentPosition
// Ignore synthetic positions prior to any actual position, except when inlined
// (that is, callerPosition != null).
- && !(currentPosition.isNone() && position.synthetic && position.callerPosition == null)
+ && !(currentPosition.isNone()
+ && position.isSyntheticPosition()
+ && !position.hasCallerPosition())
&& (appView.options().debug || instruction.instructionTypeCanThrow());
if (!didLocalsChange && !didPositionChange) {
return;
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
index 5abeb6e..1a39011 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CfSourceCode.java
@@ -904,7 +904,7 @@
position
.builderWithCopy()
.setCallerPosition(
- canonicalPositions.canonicalizeCallerPosition(position.callerPosition))
+ canonicalPositions.canonicalizeCallerPosition(position.getCallerPosition()))
.build());
}
}
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index 4181373..f2c1d8d 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -43,6 +43,7 @@
import com.android.tools.r8.ir.code.CanonicalPositions;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -255,10 +256,10 @@
private Position getCanonicalPositionAppendCaller(DexDebugEntry entry) {
// If this instruction has already been inlined then this.method must be the outermost caller.
assert entry.callerPosition == null
- || entry.callerPosition.getOutermostCaller().method == originalMethod;
+ || entry.callerPosition.getOutermostCaller().getMethod() == originalMethod;
return canonicalPositions.getCanonical(
- Position.builder()
+ SourcePosition.builder()
.setLine(entry.line)
.setFile(entry.sourceFile)
.setMethod(entry.method)
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 40c7bb9..b6fcd8c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -829,7 +829,9 @@
} else {
current = position;
}
- } else if (position.isSome() && !position.synthetic && !position.equals(current)) {
+ } else if (position.isSome()
+ && !position.isSyntheticPosition()
+ && !position.equals(current)) {
DebugPosition positionChange = new DebugPosition();
positionChange.setPosition(position);
it.previous();
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index cdc2c6e..bcd27e6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -79,6 +79,7 @@
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.Switch;
import com.android.tools.r8.ir.code.Throw;
@@ -3673,7 +3674,8 @@
InstructionListIterator iterator = block.listIterator(code);
// Attach some synthetic position to all inserted code.
- Position position = Position.synthetic(1, method.getReference(), null);
+ Position position =
+ SyntheticPosition.builder().setLine(1).setMethod(method.getReference()).build();
iterator.setInsertionPosition(position);
// Split arguments into their own block.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
index 31801c6..a0d7ede 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/OutlinerImpl.java
@@ -47,6 +47,7 @@
import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Rem;
import com.android.tools.r8.ir.code.Sub;
import com.android.tools.r8.ir.code.Value;
@@ -1537,7 +1538,7 @@
OutlineSourceCode(Outline outline, DexMethod method) {
this.outline = outline;
- this.position = Position.synthetic(0, method, null);
+ this.position = SyntheticPosition.builder().setLine(0).setMethod(method).build();
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index ae06b60..c81383c 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.DexSourceCode;
import com.android.tools.r8.ir.conversion.IRBuilder;
@@ -64,7 +65,12 @@
this.paramRegisters[i] = nextRegister(ValueType.fromDexType(params[i]));
}
- position = Position.synthetic(0, originalMethod, callerPosition);
+ position =
+ SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(originalMethod)
+ .setCallerPosition(callerPosition)
+ .build();
}
protected final void add(Consumer<IRBuilder> constructor) {
diff --git a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
index 391f2c7..ea756b5 100644
--- a/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
+++ b/src/main/java/com/android/tools/r8/naming/IdentifierNameStringMarker.java
@@ -375,9 +375,9 @@
+ " Thus, not all identifier strings flowing to that " + kind
+ " are renamed, which can cause resolution failures at runtime.";
StringDiagnostic diagnostic =
- instruction.getPosition().line >= 1
+ instruction.getPosition().getLine() >= 1
? new StringDiagnostic(
- message, origin, new TextPosition(0L, instruction.getPosition().line, 1))
+ message, origin, new TextPosition(0L, instruction.getPosition().getLine(), 1))
: new StringDiagnostic(message, origin);
appView.options().reporter.warning(diagnostic);
}
diff --git a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
index 2a4db34..6dd9775 100644
--- a/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
+++ b/src/main/java/com/android/tools/r8/utils/LineNumberOptimizer.java
@@ -39,6 +39,7 @@
import com.android.tools.r8.graph.DexValue.DexValueString;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
import com.android.tools.r8.kotlin.KotlinSourceDebugExtensionParser;
import com.android.tools.r8.kotlin.KotlinSourceDebugExtensionParser.Result;
import com.android.tools.r8.naming.ClassNameMapper;
@@ -103,12 +104,12 @@
@Override
public Pair<Position, Position> createRemappedPosition(Position position) {
- assert position.method != null;
- if (previousMethod == position.method) {
+ assert position.getMethod() != null;
+ if (previousMethod == position.getMethod()) {
assert previousSourceLine >= 0;
- if (position.line > previousSourceLine
- && position.line - previousSourceLine <= maxLineDelta) {
- nextOptimizedLineNumber += (position.line - previousSourceLine) - 1;
+ if (position.getLine() > previousSourceLine
+ && position.getLine() - previousSourceLine <= maxLineDelta) {
+ nextOptimizedLineNumber += (position.getLine() - previousSourceLine) - 1;
}
}
@@ -118,8 +119,8 @@
.setLine(nextOptimizedLineNumber++)
.setCallerPosition(null)
.build();
- previousSourceLine = position.line;
- previousMethod = position.method;
+ previousSourceLine = position.getLine();
+ previousMethod = position.getMethod();
return new Pair<>(position, newPosition);
}
}
@@ -149,8 +150,8 @@
@Override
public Pair<Position, Position> createRemappedPosition(Position position) {
assert currentMethod != null;
- int line = position.line;
- Result parsedData = getAndParseSourceDebugExtension(position.method.holder);
+ int line = position.getLine();
+ Result parsedData = getAndParseSourceDebugExtension(position.getMethod().holder);
if (parsedData == null) {
return baseRemapper.createRemappedPosition(position);
}
@@ -183,7 +184,7 @@
factory.createString(methodName),
factory.createString(returnTypeDescriptor),
argumentDexStringDescriptors);
- if (!inlinee.equals(position.method)) {
+ if (!inlinee.equals(position.getMethod())) {
// We have an inline from a different method than the current position.
Entry<Integer, KotlinSourceDebugExtensionParser.Position> calleePosition =
parsedData.lookupCalleePosition(line);
@@ -196,7 +197,7 @@
.build();
}
return baseRemapper.createRemappedPosition(
- Position.builder()
+ SourcePosition.builder()
.setLine(originalInlineeLine)
.setMethod(inlinee)
.setCallerPosition(position)
@@ -256,9 +257,8 @@
private void emitPositionEvents(int currentPc, Position currentPosition) {
if (previousPosition == null) {
- startLine = currentPosition.line;
- previousPosition =
- Position.builder().setLine(startLine).setFile(null).setMethod(method).build();
+ startLine = currentPosition.getLine();
+ previousPosition = SourcePosition.builder().setLine(startLine).setMethod(method).build();
}
DexDebugEventBuilder.emitAdvancementEvents(
previousPc,
@@ -509,10 +509,10 @@
lastMappedRange =
classNamingBuilder.addMappedRange(
obfuscatedRange,
- getOriginalMethodSignature.apply(caller.method),
- new Range(Math.max(caller.line, 0)), // Prevent against "no-position".
+ getOriginalMethodSignature.apply(caller.getMethod()),
+ new Range(Math.max(caller.getLine(), 0)), // Prevent against "no-position".
obfuscatedName);
- if (caller.removeInnerFrameIfThrowingNpe) {
+ if (caller.isRemoveInnerFramesIfThrowingNpe()) {
lastMappedRange.addMappingInformation(
RewriteFrameMappingInformation.builder()
.addCondition(
@@ -523,7 +523,7 @@
.build(),
Unreachable::raise);
}
- caller = caller.callerPosition;
+ caller = caller.getCallerPosition();
}
for (MappingInformation info : methodMappingInfo) {
lastMappedRange.addMappingInformation(info, Unreachable::raise);
@@ -597,7 +597,7 @@
if (!(instruction instanceof CfPosition)) {
continue;
}
- return ((CfPosition) instruction).getPosition().line;
+ return ((CfPosition) instruction).getPosition().getLine();
}
}
return 0;
@@ -748,7 +748,7 @@
super.visit(defaultEvent);
assert getCurrentLine() >= 0;
Position position =
- Position.builder()
+ SourcePosition.builder()
.setLine(getCurrentLine())
.setFile(getCurrentFile())
.setMethod(getCurrentMethod())
@@ -856,7 +856,7 @@
}
lastPosition.setFirst(getCurrentPc());
lastPosition.setSecond(
- Position.builder()
+ SourcePosition.builder()
.setLine(getCurrentLine())
.setFile(getCurrentFile())
.setMethod(getCurrentMethod())
@@ -932,7 +932,10 @@
Position newPosition = remappedPosition.getSecond();
mappedPositions.add(
new MappedPosition(
- oldPosition.method, oldPosition.line, oldPosition.callerPosition, newPosition.line));
+ oldPosition.getMethod(),
+ oldPosition.getLine(),
+ oldPosition.getCallerPosition(),
+ newPosition.getLine()));
return newPosition;
}
@@ -947,7 +950,10 @@
for (int currentPc = startPc; currentPc < endPc; currentPc++) {
mappedPositions.add(
new MappedPosition(
- oldPosition.method, oldPosition.line, oldPosition.callerPosition, currentPc));
+ oldPosition.getMethod(),
+ oldPosition.getLine(),
+ oldPosition.getCallerPosition(),
+ currentPc));
}
}
}
diff --git a/src/test/java/com/android/tools/r8/graph/DexDebugEventsTest.java b/src/test/java/com/android/tools/r8/graph/DexDebugEventsTest.java
index 4f71913..9b85698 100644
--- a/src/test/java/com/android/tools/r8/graph/DexDebugEventsTest.java
+++ b/src/test/java/com/android/tools/r8/graph/DexDebugEventsTest.java
@@ -8,7 +8,7 @@
import com.android.tools.r8.graph.DexDebugEvent.AdvancePC;
import com.android.tools.r8.graph.DexDebugEvent.Default;
-import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
@@ -133,9 +133,9 @@
List<DexDebugEvent> events = new ArrayList<>();
DexDebugEventBuilder.emitAdvancementEvents(
pc,
- Position.builder().setLine(line).setMethod(method).build(),
+ SourcePosition.builder().setLine(line).setMethod(method).build(),
nextPc,
- Position.builder().setLine(nextLine).setMethod(method).build(),
+ SourcePosition.builder().setLine(nextLine).setMethod(method).build(),
events,
factory,
false);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
index 2485f20..2d40272 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/ConstantRemovalTest.java
@@ -19,6 +19,7 @@
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
@@ -75,7 +76,7 @@
block.setNumber(basicBlockNumberGenerator.next());
IRMetadata metadata = IRMetadata.unknown();
- Position position = Position.testingPosition();
+ Position position = SyntheticPosition.builder().setLine(0).build();
Value v3 = new Value(3, TypeElement.getLong(), null);
v3.setNeedsRegister(true);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 9fc16f8..762f5e9 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -24,6 +24,7 @@
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.NumberGenerator;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.Return;
import com.android.tools.r8.ir.code.Throw;
import com.android.tools.r8.ir.code.Value;
@@ -63,7 +64,7 @@
// block2:
// return
final NumberGenerator basicBlockNumberGenerator = new NumberGenerator();
- Position position = Position.testingPosition();
+ Position position = SyntheticPosition.builder().setLine(0).build();
BasicBlock block2 = new BasicBlock();
BasicBlock block0 =
BasicBlock.createGotoBlock(basicBlockNumberGenerator.next(), position, metadata, block2);
@@ -127,7 +128,7 @@
// block3:
// goto block3
final NumberGenerator basicBlockNumberGenerator = new NumberGenerator();
- Position position = Position.testingPosition();
+ Position position = SyntheticPosition.builder().setLine(0).build();
BasicBlock block0 = new BasicBlock();
block0.setNumber(basicBlockNumberGenerator.next());
BasicBlock block2 = new BasicBlock();
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 80863b5..664e68e 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -57,6 +57,7 @@
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Phi.RegisterReadType;
import com.android.tools.r8.ir.code.Position;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.ValueTypeConstraint;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.SourceCode;
@@ -902,7 +903,12 @@
private final Position position;
public ReturnVoidCode(DexMethod method, Position callerPosition) {
- this.position = Position.synthetic(0, method, callerPosition);
+ this.position =
+ SyntheticPosition.builder()
+ .setLine(0)
+ .setMethod(method)
+ .setCallerPosition(callerPosition)
+ .build();
}
@Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 7c882b4..40fcc0f 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -258,7 +258,7 @@
new Object2IntOpenHashMap<>(code.getInstructions().size());
for (CfInstruction insn : code.getInstructions()) {
if (insn instanceof CfPosition) {
- currentLine = ((CfPosition) insn).getPosition().line;
+ currentLine = ((CfPosition) insn).getPosition().getLine();
}
if (currentLine != -1) {
lineNumberTable.put(new CfInstructionSubject(insn, this), currentLine);