Clean-up DexEntryDebugState to account for all position info

Change-Id: I3ad62f33038903f68e6535494f0439f459cd710a
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 81caca5..8ca811b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexCode.java
+++ b/src/main/java/com/android/tools/r8/graph/DexCode.java
@@ -560,7 +560,7 @@
             .append("(warning: has unhandled debug events @ pc:")
             .append(debugInfo.address)
             .append(", line:")
-            .append(debugInfo.line);
+            .append(debugInfo.getPosition().getLine());
       } else {
         builder.append("(has debug events past last pc)\n");
       }
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 f89353c..6679383 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEntry.java
@@ -4,60 +4,38 @@
 package com.android.tools.r8.graph;
 
 import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition.OutlineCallerPositionBuilder;
-import com.android.tools.r8.ir.code.Position.OutlinePosition;
-import com.android.tools.r8.ir.code.Position.PositionBuilder;
-import com.android.tools.r8.ir.code.Position.SourcePosition;
-import com.android.tools.r8.utils.Int2StructuralItemArrayMap;
 import com.android.tools.r8.utils.StringUtils;
 import com.google.common.collect.ImmutableMap;
 import java.util.Map;
 import java.util.SortedSet;
 import java.util.TreeSet;
-import java.util.function.Function;
 
 public class DexDebugEntry {
 
   public final boolean lineEntry;
   public final int address;
-  public final int line;
   public final DexString sourceFile;
   public final boolean prologueEnd;
   public final boolean epilogueBegin;
   public final Map<Integer, DebugLocalInfo> locals;
-  public final DexMethod method;
-  public final Position callerPosition;
-  public final boolean isOutline;
-  public final DexMethod outlineCallee;
-  public final Int2StructuralItemArrayMap<Position> outlineCallerPositions;
+  private final Position position;
 
   public DexDebugEntry(
       boolean lineEntry,
       int address,
-      int line,
       DexString sourceFile,
       boolean prologueEnd,
       boolean epilogueBegin,
       ImmutableMap<Integer, DebugLocalInfo> locals,
-      DexMethod method,
-      Position callerPosition,
-      boolean isOutline,
-      DexMethod outlineCallee,
-      Int2StructuralItemArrayMap<Position> outlineCallerPositions) {
+      Position position) {
     this.lineEntry = lineEntry;
     this.address = address;
-    this.line = line;
     this.sourceFile = sourceFile;
     this.prologueEnd = prologueEnd;
     this.epilogueBegin = epilogueBegin;
     this.locals = locals;
-    this.method = method;
-    assert method != null;
-    this.callerPosition = callerPosition;
-    this.isOutline = isOutline;
-    this.outlineCallee = outlineCallee;
-    this.outlineCallerPositions = outlineCallerPositions;
+    this.position = position;
+    assert position != null;
   }
 
   @Override
@@ -74,24 +52,7 @@
     if (sourceFile != null) {
       builder.append(", file ").append(sourceFile);
     }
-    builder.append(", line ").append(line);
-    if (callerPosition != null) {
-      builder.append(":").append(method.name);
-      Position caller = callerPosition;
-      while (caller != null) {
-        builder.append(";").append(caller.getLine()).append(":").append(caller.getMethod().name);
-        caller = caller.getCallerPosition();
-      }
-    }
-    if (isOutline) {
-      builder.append(", isOutline = true");
-    }
-    if (outlineCallee != null) {
-      builder.append(", outlineCallee = ").append(outlineCallee);
-    }
-    if (outlineCallerPositions != null) {
-      builder.append(", outlineCallerPositions = ").append(outlineCallerPositions);
-    }
+    builder.append(", ").append(position);
     if (prologueEnd) {
       builder.append(", prologue_end = true");
     }
@@ -115,22 +76,11 @@
     return builder.toString();
   }
 
-  public Position toPosition(Function<Position, Position> canonicalizeCallerPosition) {
-    PositionBuilder<?, ?> positionBuilder;
-    if (outlineCallee != null) {
-      OutlineCallerPositionBuilder outlineCallerPositionBuilder =
-          OutlineCallerPosition.builder().setOutlineCallee(outlineCallee).setIsOutline(isOutline);
-      outlineCallerPositions.forEach(outlineCallerPositionBuilder::addOutlinePosition);
-      positionBuilder = outlineCallerPositionBuilder;
-    } else if (isOutline) {
-      positionBuilder = OutlinePosition.builder();
-    } else {
-      positionBuilder = SourcePosition.builder().setFile(sourceFile);
-    }
-    return positionBuilder
-        .setLine(line)
-        .setMethod(method)
-        .setCallerPosition(canonicalizeCallerPosition.apply(callerPosition))
-        .build();
+  public Position getPosition() {
+    return position;
+  }
+
+  public int getLine() {
+    return position.getLine();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java b/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
index 5a4fd84..e323ab8 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugEntryBuilder.java
@@ -46,7 +46,6 @@
   private boolean epilogueBegin = false;
   private final Map<Integer, LocalEntry> locals = new HashMap<>();
   private final Int2ReferenceMap<DebugLocalInfo> arguments = new Int2ReferenceArrayMap<>();
-  private final DexMethod method;
 
   // Delayed construction of an entry. Is finalized once locals information has been collected.
   private DexDebugEntry pending = null;
@@ -60,13 +59,11 @@
 
   public DexDebugEntryBuilder(int startLine, DexMethod method) {
     assert method != null;
-    this.method = method;
     positionState = new DexDebugPositionState(startLine, method);
   }
 
   public DexDebugEntryBuilder(DexEncodedMethod method, DexItemFactory factory) {
     assert method != null && method.getReference() != null;
-    this.method = method.getReference();
     DexCode code = method.getCode().asDexCode();
     EventBasedDebugInfo info = code.getDebugInfo().asEventBasedInfo();
     // Only event based debug info supports conversion to entries.
@@ -164,31 +161,21 @@
           new DexDebugEntry(
               pending.lineEntry,
               pending.address,
-              pending.line,
               pending.sourceFile,
               pending.prologueEnd,
               pending.epilogueBegin,
               getLocals(),
-              pending.method,
-              pending.callerPosition,
-              pending.isOutline,
-              pending.outlineCallee,
-              pending.outlineCallerPositions));
+              pending.getPosition()));
     }
     pending =
         new DexDebugEntry(
             lineEntry,
             positionState.getCurrentPc(),
-            positionState.getCurrentLine(),
-            positionState.getCurrentFile(),
+            null,
             prologueEnd,
             epilogueBegin,
             null,
-            positionState.getCurrentMethod(),
-            positionState.getCurrentCallerPosition(),
-            positionState.isOutline(),
-            positionState.getOutlineCallee(),
-            positionState.getOutlineCallerPositions());
+            positionState.getPosition());
     prologueEnd = false;
     epilogueBegin = false;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java b/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
index 10a06d5..96eb206 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDebugPositionState.java
@@ -15,7 +15,8 @@
 import com.android.tools.r8.graph.DexDebugEvent.SetPrologueEnd;
 import com.android.tools.r8.graph.DexDebugEvent.StartLocal;
 import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.utils.Int2StructuralItemArrayMap;
+import com.android.tools.r8.ir.code.Position.SourcePosition;
+import com.android.tools.r8.ir.code.Position.SyntheticPosition;
 
 /**
  * State machine to process and accumulate position-related DexDebugEvents. Clients should retrieve
@@ -25,12 +26,8 @@
 
   private int currentPc = 0;
   private int currentLine;
-  private DexString currentFile = null;
-  private DexMethod currentMethod;
-  private Position currentCallerPosition = null;
-  private boolean isOutline;
-  private DexMethod outlineCallee;
-  private Int2StructuralItemArrayMap<Position> outlineCallerPositions;
+  protected DexMethod currentMethod;
+  protected Position currentPosition;
 
   public DexDebugPositionState(int startLine, DexMethod method) {
     currentLine = startLine;
@@ -53,10 +50,7 @@
     assert setPositionFrame.getPosition() != null;
     Position position = setPositionFrame.getPosition();
     currentMethod = position.getMethod();
-    currentCallerPosition = position.getCallerPosition();
-    outlineCallee = position.getOutlineCallee();
-    outlineCallerPositions = position.getOutlinePositions();
-    isOutline = position.isOutline();
+    currentPosition = position;
   }
 
   @Override
@@ -68,7 +62,7 @@
 
   @Override
   public void visit(SetFile setFile) {
-    currentFile = setFile.fileName;
+    // Empty.
   }
 
   @Override
@@ -104,33 +98,14 @@
     return currentLine;
   }
 
-  public DexString getCurrentFile() {
-    return currentFile;
-  }
-
-  public DexMethod getCurrentMethod() {
-    return currentMethod;
-  }
-
-  public Position getCurrentCallerPosition() {
-    return currentCallerPosition;
-  }
-
-  public boolean isOutline() {
-    return isOutline;
-  }
-
-  public DexMethod getOutlineCallee() {
-    return outlineCallee;
-  }
-
-  public Int2StructuralItemArrayMap<Position> getOutlineCallerPositions() {
-    return outlineCallerPositions;
-  }
-
-  public void resetOutlineInformation() {
-    isOutline = false;
-    outlineCallee = null;
-    outlineCallerPositions = null;
+  public Position getPosition() {
+    if (currentPosition == null) {
+      return (getCurrentLine() > 0 ? SourcePosition.builder() : SyntheticPosition.builder())
+          .setLine(getCurrentLine())
+          .setMethod(currentMethod)
+          .build();
+    } else {
+      return currentPosition.builderWithCopy().setLine(getCurrentLine()).build();
+    }
   }
 }
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 3662c28..5e88574 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
@@ -217,6 +217,15 @@
         caller = caller.callerPosition;
       }
     }
+    if (isOutline()) {
+      builder.append(", isOutline = true");
+    }
+    if (getOutlineCallee() != null) {
+      builder.append(", outlineCallee = ").append(getOutlineCallee());
+    }
+    if (getOutlinePositions() != null) {
+      builder.append(", outlineCallerPositions = ").append(getOutlinePositions());
+    }
     return builder.toString();
   }
 
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 3fbcdc8..ea0f655 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
@@ -259,10 +259,15 @@
 
   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().getMethod() == originalMethod;
+    Position position = entry.getPosition();
+    assert !position.hasCallerPosition()
+        || position.getOutermostCaller().getMethod() == originalMethod;
     return canonicalPositions.getCanonical(
-        entry.toPosition(canonicalPositions::canonicalizeCallerPosition));
+        position
+            .builderWithCopy()
+            .setCallerPosition(
+                canonicalPositions.canonicalizeCallerPosition(position.getCallerPosition()))
+            .build());
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
index 6e540b8..a660a37 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToNoPcMappedRangeMapper.java
@@ -14,7 +14,6 @@
 import com.android.tools.r8.graph.DexDebugEvent.RestartLocal;
 import com.android.tools.r8.graph.DexDebugEvent.SetEpilogueBegin;
 import com.android.tools.r8.graph.DexDebugEvent.SetFile;
-import com.android.tools.r8.graph.DexDebugEvent.SetPositionFrame;
 import com.android.tools.r8.graph.DexDebugEvent.SetPrologueEnd;
 import com.android.tools.r8.graph.DexDebugEvent.StartLocal;
 import com.android.tools.r8.graph.DexDebugEventBuilder;
@@ -26,12 +25,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition.OutlineCallerPositionBuilder;
-import com.android.tools.r8.ir.code.Position.OutlinePosition;
-import com.android.tools.r8.ir.code.Position.PositionBuilder;
 import com.android.tools.r8.ir.code.Position.SourcePosition;
-import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.InternalOptions.LineNumberOptimization;
 import java.util.ArrayList;
 import java.util.List;
@@ -87,6 +81,122 @@
     }
   }
 
+  private static class DexDebugPositionStateVisitor extends DexDebugPositionState {
+
+    private final PositionEventEmitter positionEventEmitter;
+    private final List<MappedPosition> mappedPositions;
+    private final PositionRemapper positionRemapper;
+    private final List<DexDebugEvent> processedEvents;
+    private final DexItemFactory factory;
+
+    private final DexMethod startMethod;
+
+    // Keep track of what PC has been emitted.
+    private int emittedPc = 0;
+
+    private boolean inlinedOriginalPosition;
+
+    public DexDebugPositionStateVisitor(
+        PositionEventEmitter positionEventEmitter,
+        List<MappedPosition> mappedPositions,
+        PositionRemapper positionRemapper,
+        List<DexDebugEvent> processedEvents,
+        DexItemFactory factory,
+        int startLine,
+        DexMethod method) {
+      super(startLine, method);
+      this.positionEventEmitter = positionEventEmitter;
+      this.mappedPositions = mappedPositions;
+      this.positionRemapper = positionRemapper;
+      this.processedEvents = processedEvents;
+      this.factory = factory;
+      this.startMethod = method;
+    }
+
+    // Force the current PC to emitted.
+    private void flushPc() {
+      if (emittedPc != getCurrentPc()) {
+        positionEventEmitter.emitAdvancePc(getCurrentPc());
+        emittedPc = getCurrentPc();
+      }
+    }
+
+    // A default event denotes a line table entry and must always be emitted. Remap its line.
+    @Override
+    public void visit(Default defaultEvent) {
+      if (hasPreamblePosition(defaultEvent)) {
+        emitPreamblePosition();
+      }
+      super.visit(defaultEvent);
+      assert getCurrentLine() >= 0;
+      Position position = getPosition();
+      Position mappedPosition =
+          PositionUtils.remapAndAdd(position, positionRemapper, mappedPositions);
+      positionEventEmitter.emitPositionEvents(getCurrentPc(), mappedPosition);
+      if (mappedPosition != position) {
+        inlinedOriginalPosition = true;
+      }
+      emittedPc = getCurrentPc();
+    }
+
+    private boolean hasPreamblePosition(Default defaultEvent) {
+      return getCurrentPc() == 0
+          && defaultEvent.getPCDelta() > 0
+          && currentPosition != null
+          && currentPosition.getLine() != getCurrentLine();
+    }
+
+    // Non-materializing events use super, ie, AdvancePC, AdvanceLine and SetInlineFrame.
+
+    // Materializing events are just amended to the stream.
+
+    @Override
+    public void visit(SetFile setFile) {
+      processedEvents.add(setFile);
+    }
+
+    @Override
+    public void visit(SetPrologueEnd setPrologueEnd) {
+      processedEvents.add(setPrologueEnd);
+    }
+
+    @Override
+    public void visit(SetEpilogueBegin setEpilogueBegin) {
+      processedEvents.add(setEpilogueBegin);
+    }
+
+    // Local changes must force flush the PC ensuing they pertain to the correct point.
+
+    @Override
+    public void visit(StartLocal startLocal) {
+      flushPc();
+      processedEvents.add(startLocal);
+    }
+
+    @Override
+    public void visit(EndLocal endLocal) {
+      flushPc();
+      processedEvents.add(endLocal);
+    }
+
+    @Override
+    public void visit(RestartLocal restartLocal) {
+      flushPc();
+      processedEvents.add(restartLocal);
+    }
+
+    public void emitPreamblePosition() {
+      if (currentPosition == null || positionEventEmitter.didEmitLineEvents()) {
+        return;
+      }
+      Position mappedPosition =
+          PositionUtils.remapAndAdd(currentPosition, positionRemapper, mappedPositions);
+      processedEvents.add(factory.createPositionFrame(mappedPosition));
+      currentPosition = null;
+      currentMethod = startMethod;
+    }
+  }
+
   private final AppView<?> appView;
   private final boolean isIdentityMapping;
 
@@ -112,95 +222,24 @@
             appView.graphLens().getOriginalMethodSignature(method.getReference()),
             processedEvents);
 
-    Box<Boolean> inlinedOriginalPosition = new Box<>(false);
-
-    // Debug event visitor to map line numbers.
-    DexDebugPositionState visitor =
-        new DexDebugPositionState(
+    DexDebugPositionStateVisitor visitor =
+        new DexDebugPositionStateVisitor(
+            positionEventEmitter,
+            mappedPositions,
+            positionRemapper,
+            processedEvents,
+            appView.dexItemFactory(),
             debugInfo.startLine,
-            appView.graphLens().getOriginalMethodSignature(method.getReference())) {
-
-          // Keep track of what PC has been emitted.
-          private int emittedPc = 0;
-
-          // Force the current PC to emitted.
-          private void flushPc() {
-            if (emittedPc != getCurrentPc()) {
-              positionEventEmitter.emitAdvancePc(getCurrentPc());
-              emittedPc = getCurrentPc();
-            }
-          }
-
-          // A default event denotes a line table entry and must always be emitted. Remap its line.
-          @Override
-          public void visit(Default defaultEvent) {
-            super.visit(defaultEvent);
-            assert getCurrentLine() >= 0;
-            Position position = getPositionFromPositionState(this);
-            Position currentPosition =
-                PositionUtils.remapAndAdd(position, positionRemapper, mappedPositions);
-            positionEventEmitter.emitPositionEvents(getCurrentPc(), currentPosition);
-            if (currentPosition != position) {
-              inlinedOriginalPosition.set(true);
-            }
-            emittedPc = getCurrentPc();
-            resetOutlineInformation();
-          }
-
-          // Non-materializing events use super, ie, AdvancePC, AdvanceLine and SetInlineFrame.
-
-          // Materializing events are just amended to the stream.
-
-          @Override
-          public void visit(SetFile setFile) {
-            processedEvents.add(setFile);
-          }
-
-          @Override
-          public void visit(SetPrologueEnd setPrologueEnd) {
-            processedEvents.add(setPrologueEnd);
-          }
-
-          @Override
-          public void visit(SetEpilogueBegin setEpilogueBegin) {
-            processedEvents.add(setEpilogueBegin);
-          }
-
-          // Local changes must force flush the PC ensuing they pertain to the correct point.
-
-          @Override
-          public void visit(StartLocal startLocal) {
-            flushPc();
-            processedEvents.add(startLocal);
-          }
-
-          @Override
-          public void visit(EndLocal endLocal) {
-            flushPc();
-            processedEvents.add(endLocal);
-          }
-
-          @Override
-          public void visit(RestartLocal restartLocal) {
-            flushPc();
-            processedEvents.add(restartLocal);
-          }
-        };
+            appView.graphLens().getOriginalMethodSignature(method.getReference()));
 
     DexDebugEvent[] events = debugInfo.events;
-    if (events.length > 0) {
-      SetPositionFrame preambleFrame = getAsPreambleFrame(events[0]);
-      if (preambleFrame != null) {
-        // The preamble is specially identified here as it is active at method entry and thus not
-        // part of the instruction stream events.
-        Position position = preambleFrame.getPosition();
-        Position newPosition =
-            PositionUtils.remapAndAdd(position, positionRemapper, mappedPositions);
-        processedEvents.add(appView.dexItemFactory().createPositionFrame(newPosition));
-      }
-      for (int i = (preambleFrame == null) ? 0 : 1; i < events.length; i++) {
-        events[i].accept(visitor);
-      }
+    for (DexDebugEvent event : events) {
+      event.accept(visitor);
+    }
+
+    // We still need to emit a preamble if we did not materialize any other instructions.
+    if (mappedPositions.isEmpty()) {
+      visitor.emitPreamblePosition();
     }
 
     EventBasedDebugInfo optimizedDebugInfo =
@@ -210,23 +249,13 @@
             processedEvents.toArray(DexDebugEvent.EMPTY_ARRAY));
 
     assert !isIdentityMapping
-        || inlinedOriginalPosition.get()
+        || visitor.inlinedOriginalPosition
         || verifyIdentityMapping(debugInfo, optimizedDebugInfo);
 
     dexCode.setDebugInfo(optimizedDebugInfo);
     return mappedPositions;
   }
 
-  private SetPositionFrame getAsPreambleFrame(DexDebugEvent event) {
-    SetPositionFrame positionFrame = event.asSetPositionFrame();
-    if (positionFrame != null
-        && positionFrame.getPosition().isSyntheticPosition()
-        && positionFrame.getPosition().getLine() == 0) {
-      return positionFrame;
-    }
-    return null;
-  }
-
   // This conversion *always* creates an event based debug info encoding as any non-info will
   // be created as an implicit PC encoding.
   private static EventBasedDebugInfo getEventBasedDebugInfo(
@@ -243,27 +272,6 @@
     return debugInfo;
   }
 
-  private static Position getPositionFromPositionState(DexDebugPositionState state) {
-    PositionBuilder<?, ?> positionBuilder;
-    if (state.getOutlineCallee() != null) {
-      OutlineCallerPositionBuilder outlineCallerPositionBuilder =
-          OutlineCallerPosition.builder()
-              .setOutlineCallee(state.getOutlineCallee())
-              .setIsOutline(state.isOutline());
-      state.getOutlineCallerPositions().forEach(outlineCallerPositionBuilder::addOutlinePosition);
-      positionBuilder = outlineCallerPositionBuilder;
-    } else if (state.isOutline()) {
-      positionBuilder = OutlinePosition.builder();
-    } else {
-      positionBuilder = SourcePosition.builder().setFile(state.getCurrentFile());
-    }
-    return positionBuilder
-        .setLine(state.getCurrentLine())
-        .setMethod(state.getCurrentMethod())
-        .setCallerPosition(state.getCurrentCallerPosition())
-        .build();
-  }
-
   private static boolean verifyIdentityMapping(
       EventBasedDebugInfo originalDebugInfo, EventBasedDebugInfo optimizedDebugInfo) {
     assert optimizedDebugInfo.startLine == originalDebugInfo.startLine;
diff --git a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
index 890cb80..eff8ac4 100644
--- a/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
+++ b/src/main/java/com/android/tools/r8/utils/positions/DexPositionToPcMappedRangeMapper.java
@@ -16,11 +16,6 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.ir.code.Position;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition;
-import com.android.tools.r8.ir.code.Position.OutlineCallerPosition.OutlineCallerPositionBuilder;
-import com.android.tools.r8.ir.code.Position.OutlinePosition;
-import com.android.tools.r8.ir.code.Position.PositionBuilder;
-import com.android.tools.r8.ir.code.Position.SourcePosition;
 import com.android.tools.r8.utils.IntBox;
 import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.positions.PositionToMappedRangeMapper.PcBasedDebugInfoRecorder;
@@ -58,7 +53,7 @@
             if (firstDefaultEventPc.get() < 0) {
               firstDefaultEventPc.set(getCurrentPc());
             }
-            Position currentPosition = getPositionFromPositionState(this);
+            Position currentPosition = getPosition();
             if (lastPosition.getSecond() != null) {
               remapAndAddForPc(
                   pcBasedDebugInfo,
@@ -70,7 +65,6 @@
             }
             lastPosition.setFirst(getCurrentPc());
             lastPosition.setSecond(currentPosition);
-            resetOutlineInformation();
           }
         };
 
@@ -135,27 +129,6 @@
     return debugInfo;
   }
 
-  private static Position getPositionFromPositionState(DexDebugPositionState state) {
-    PositionBuilder<?, ?> positionBuilder;
-    if (state.getOutlineCallee() != null) {
-      OutlineCallerPositionBuilder outlineCallerPositionBuilder =
-          OutlineCallerPosition.builder()
-              .setOutlineCallee(state.getOutlineCallee())
-              .setIsOutline(state.isOutline());
-      state.getOutlineCallerPositions().forEach(outlineCallerPositionBuilder::addOutlinePosition);
-      positionBuilder = outlineCallerPositionBuilder;
-    } else if (state.isOutline()) {
-      positionBuilder = OutlinePosition.builder();
-    } else {
-      positionBuilder = SourcePosition.builder().setFile(state.getCurrentFile());
-    }
-    return positionBuilder
-        .setLine(state.getCurrentLine())
-        .setMethod(state.getCurrentMethod())
-        .setCallerPosition(state.getCurrentCallerPosition())
-        .build();
-  }
-
   private static boolean verifyIdentityMapping(
       EventBasedDebugInfo originalDebugInfo, EventBasedDebugInfo optimizedDebugInfo) {
     assert optimizedDebugInfo.startLine == originalDebugInfo.startLine;
diff --git a/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java b/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
index 1f41abc..1d4a205 100644
--- a/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
+++ b/src/test/java/com/android/tools/r8/debug/SmaliDebugTest.java
@@ -122,7 +122,7 @@
     int target = cond.getTargets()[0] + cond.getOffset();
     int linePC = -1;
     for (DexDebugEntry entry : info.getEntries()) {
-      if (entry.line == 4) {
+      if (entry.getPosition().getLine() == 4) {
         linePC = entry.address;
         break;
       }
diff --git a/src/test/java/com/android/tools/r8/debuginfo/DebugInfoInspector.java b/src/test/java/com/android/tools/r8/debuginfo/DebugInfoInspector.java
index 605865f..00409e1 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/DebugInfoInspector.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/DebugInfoInspector.java
@@ -125,7 +125,7 @@
     for (int i = 0; i < entries.size(); i++) {
       DexDebugEntry entry = entries.get(i);
       // Matches each entry at 'line' that is not a zero-line increment.
-      if (entry.line == line && (i == 0 || entries.get(i - 1).line != line)) {
+      if (entry.getLine() == line && (i == 0 || entries.get(i - 1).getLine() != line)) {
         found++;
         check.accept(entry);
       }
@@ -139,7 +139,11 @@
     for (DebugLocalInfo local : entry.locals.values()) {
       if (local.name.toString().equals(name)) {
         if (found != null) {
-          fail("Line " + entry.line + ". Local defined multiple times for name: " + name);
+          fail(
+              "Line "
+                  + entry.getPosition().getLine()
+                  + ". Local defined multiple times for name: "
+                  + name);
         }
         assertEquals(type, local.type.toString());
         if (typeParameters.length > 0) {
@@ -155,7 +159,7 @@
         found = local;
       }
     }
-    assertNotNull("Line " + entry.line + ". Failed to find local with name: " + name, found);
+    assertNotNull("Line " + entry.getLine() + ". Failed to find local with name: " + name, found);
     return found;
   }
 
@@ -176,9 +180,14 @@
         remaining.remove(local);
       }
     }
-    assertEquals("Line " + entry.line + ". Found unexpected locals: " +
-            String.join(",", remaining.stream().map(Object::toString).collect(Collectors.toList())),
-        expected, expected + remaining.size());
+    assertEquals(
+        "Line "
+            + entry.getLine()
+            + ". Found unexpected locals: "
+            + String.join(
+                ",", remaining.stream().map(Object::toString).collect(Collectors.toList())),
+        expected,
+        expected + remaining.size());
   }
 
   public DexEncodedMethod getMethod() {
diff --git a/src/test/java/com/android/tools/r8/debuginfo/EnsureNoDebugInfoEmittedForPcOnlyTestRunner.java b/src/test/java/com/android/tools/r8/debuginfo/EnsureNoDebugInfoEmittedForPcOnlyTestRunner.java
index c6f0994..9d8cf281 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/EnsureNoDebugInfoEmittedForPcOnlyTestRunner.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/EnsureNoDebugInfoEmittedForPcOnlyTestRunner.java
@@ -146,7 +146,8 @@
     MethodSubject main = clazz.uniqueMethodWithOriginalName("main");
     List<DexDebugEntry> entries =
         new DexDebugEntryBuilder(main.getMethod(), inspector.getFactory()).build();
-    Set<Integer> lines = entries.stream().map(e -> e.line).collect(Collectors.toSet());
+    Set<Integer> lines =
+        entries.stream().map(e -> e.getPosition().getLine()).collect(Collectors.toSet());
     assertFalse(lines.isEmpty());
   }
 
diff --git a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
index 6af4440..944b163 100644
--- a/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
+++ b/src/test/java/com/android/tools/r8/debuginfo/InliningWithoutPositionsTestRunner.java
@@ -97,7 +97,8 @@
               assertEquals(TEST_CLASS, line.className);
               assertEquals("main", line.methodName);
               // Expected line number could be PC based or increments.
-              // The test need not check what it is, just that all methods have been fully inlined.
+              // The test need not check what it is, just that all methods have been fully
+              // inlined.
               assertEquals(2, rawStackTrace.size());
             })
         .inspectStackTrace(