[Retrace] Clean up stack trace proxy retracing

This will prepare the stack proxy retracing for passing contexts

Change-Id: I68cfabaaa2fc02ce29d25fa4f62307d3eca874d0
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
index 35380e4..9c37aa5 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceClassElement.java
@@ -12,7 +12,7 @@
 
   RetracedClassReference getRetracedClass();
 
-  RetraceSourceFileResult getSourceFile();
+  RetracedSourceFile getSourceFile();
 
   RetraceFieldResult lookupField(String fieldName);
 
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
index 5982550..d51e175 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFieldElement.java
@@ -14,5 +14,5 @@
 
   RetraceClassElement getClassElement();
 
-  RetraceSourceFileResult getSourceFile();
+  RetracedSourceFile getSourceFile();
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
index 3295c44..b114240 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceFrameElement.java
@@ -20,7 +20,7 @@
 
   void visitNonCompilerSynthesizedFrames(BiConsumer<RetracedMethodReference, Integer> consumer);
 
-  RetraceSourceFileResult getSourceFile(RetracedClassMemberReference frame);
+  RetracedSourceFile getSourceFile(RetracedClassMemberReference frame);
 
   List<? extends RetracedMethodReference> getOuterFrames();
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java b/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
index 887bff5..132a200 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetraceMethodElement.java
@@ -14,5 +14,5 @@
 
   RetraceClassElement getClassElement();
 
-  RetraceSourceFileResult getSourceFile();
+  RetracedSourceFile getSourceFile();
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java b/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
similarity index 66%
rename from src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java
rename to src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
index 9941d9c..c0e0a7d 100644
--- a/src/main/java/com/android/tools/r8/retrace/RetraceSourceFileResult.java
+++ b/src/main/java/com/android/tools/r8/retrace/RetracedSourceFile.java
@@ -6,11 +6,10 @@
 
 import com.android.tools.r8.Keep;
 
-// TODO: This does not seem to be a "result" per say, should this rather be a RetracedSourceFile?
 @Keep
-public interface RetraceSourceFileResult {
+public interface RetracedSourceFile {
 
   boolean hasRetraceResult();
 
-  String getFilename();
+  String getSourceFile();
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
index 7cffce0..25150d2 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxy.java
@@ -14,7 +14,7 @@
 
   public abstract boolean hasMethodName();
 
-  public abstract boolean hasFileName();
+  public abstract boolean hasSourceFile();
 
   public abstract boolean hasLineNumber();
 
@@ -28,7 +28,7 @@
 
   public abstract String getMethodName();
 
-  public abstract String getFileName();
+  public abstract String getSourceFile();
 
   public abstract int getLineNumber();
 
diff --git a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
index 18be7e7..2795942 100644
--- a/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
+++ b/src/main/java/com/android/tools/r8/retrace/StackTraceElementProxyRetracer.java
@@ -11,7 +11,7 @@
 @Keep
 public interface StackTraceElementProxyRetracer<T, ST extends StackTraceElementProxy<T, ST>> {
 
-  Stream<RetraceStackTraceProxy<T, ST>> retrace(ST element);
+  Stream<? extends RetraceStackTraceProxy<T, ST>> retrace(ST element);
 
   static <T, ST extends StackTraceElementProxy<T, ST>>
       StackTraceElementProxyRetracer<T, ST> createDefault(Retracer retracer) {
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
index 55ed4db..9117006 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceClassResultImpl.java
@@ -16,8 +16,8 @@
 import com.android.tools.r8.retrace.RetraceClassElement;
 import com.android.tools.r8.retrace.RetraceClassResult;
 import com.android.tools.r8.retrace.RetraceFrameResult;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
 import com.android.tools.r8.retrace.RetraceUnknownJsonMappingInformationResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.Pair;
@@ -240,15 +240,15 @@
     }
 
     @Override
-    public RetraceSourceFileResult getSourceFile() {
+    public RetracedSourceFile getSourceFile() {
       if (classResult.mapper != null) {
         for (MappingInformation info : classResult.mapper.getAdditionalMappingInfo()) {
           if (info.isFileNameInformation()) {
-            return new RetraceSourceFileResultImpl(info.asFileNameInformation().getFileName());
+            return new RetracedSourceFileImpl(info.asFileNameInformation().getFileName());
           }
         }
       }
-      return new RetraceSourceFileResultImpl(null);
+      return new RetracedSourceFileImpl(null);
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
index 6f5e557..38667c4 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFieldResultImpl.java
@@ -10,7 +10,7 @@
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.retrace.RetraceFieldElement;
 import com.android.tools.r8.retrace.RetraceFieldResult;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -133,7 +133,7 @@
     }
 
     @Override
-    public RetraceSourceFileResult getSourceFile() {
+    public RetracedSourceFile getSourceFile() {
       return classElement.getSourceFile();
     }
   }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
index edde5ab..5d0f836 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceFrameResultImpl.java
@@ -11,9 +11,9 @@
 import com.android.tools.r8.references.MethodReference;
 import com.android.tools.r8.retrace.RetraceFrameElement;
 import com.android.tools.r8.retrace.RetraceFrameResult;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
 import com.android.tools.r8.retrace.RetracedClassMemberReference;
 import com.android.tools.r8.retrace.RetracedMethodReference;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl;
 import com.android.tools.r8.utils.ListUtils;
@@ -224,7 +224,7 @@
     }
 
     @Override
-    public RetraceSourceFileResult getSourceFile(RetracedClassMemberReference frame) {
+    public RetracedSourceFile getSourceFile(RetracedClassMemberReference frame) {
       return RetraceUtils.getSourceFileOrLookup(
           frame.getHolderClass(), classElement, retraceFrameResult.retracer);
     }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
index 37b8ffa..c6ac407 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceMethodResultImpl.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.retrace.RetraceMethodElement;
 import com.android.tools.r8.retrace.RetraceMethodResult;
 import com.android.tools.r8.retrace.RetracedMethodReference;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.retrace.internal.RetraceClassResultImpl.RetraceClassElementImpl;
 import com.android.tools.r8.utils.Pair;
@@ -166,7 +167,7 @@
     }
 
     @Override
-    public com.android.tools.r8.retrace.RetraceSourceFileResult getSourceFile() {
+    public RetracedSourceFile getSourceFile() {
       return RetraceUtils.getSourceFileOrLookup(
           methodReference.getHolderClass(), classElement, retraceMethodResult.retracer);
     }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceUtils.java b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUtils.java
index d1a6b10..920393b 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceUtils.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetraceUtils.java
@@ -14,10 +14,10 @@
 import com.android.tools.r8.references.TypeReference;
 import com.android.tools.r8.retrace.RetraceClassElement;
 import com.android.tools.r8.retrace.RetraceClassResult;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
 import com.android.tools.r8.retrace.RetracedClassReference;
 import com.android.tools.r8.retrace.RetracedMethodReference;
 import com.android.tools.r8.retrace.RetracedMethodReference.KnownRetracedMethodReference;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.DescriptorUtils;
@@ -75,18 +75,18 @@
     return clazz.substring(lastIndexOfPeriod + 1, endIndex);
   }
 
-  public static RetraceSourceFileResult getSourceFileOrLookup(
+  public static RetracedSourceFile getSourceFileOrLookup(
       RetracedClassReference holder, RetraceClassElement context, Retracer retracer) {
     if (holder.equals(context.getRetracedClass())) {
       return context.getSourceFile();
     }
     RetraceClassResult contextClassResult = retracer.retraceClass(holder.getClassReference());
-    Box<RetraceSourceFileResult> retraceSourceFile = new Box<>();
+    Box<RetracedSourceFile> retraceSourceFile = new Box<>();
     contextClassResult.forEach(element -> retraceSourceFile.set(element.getSourceFile()));
     return retraceSourceFile.get();
   }
 
-  public static String inferFileName(
+  public static String inferSourceFile(
       String retracedClassName, String sourceFile, boolean hasRetraceResult) {
     if (!hasRetraceResult || KEEP_SOURCEFILE_NAMES.contains(sourceFile)) {
       return sourceFile;
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/RetraceSourceFileResultImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/RetracedSourceFileImpl.java
similarity index 67%
rename from src/main/java/com/android/tools/r8/retrace/internal/RetraceSourceFileResultImpl.java
rename to src/main/java/com/android/tools/r8/retrace/internal/RetracedSourceFileImpl.java
index d3753e3..ef19bb3 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/RetraceSourceFileResultImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/RetracedSourceFileImpl.java
@@ -4,13 +4,13 @@
 
 package com.android.tools.r8.retrace.internal;
 
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 
-public class RetraceSourceFileResultImpl implements RetraceSourceFileResult {
+public class RetracedSourceFileImpl implements RetracedSourceFile {
 
   private final String filename;
 
-  RetraceSourceFileResultImpl(String filename) {
+  RetracedSourceFileImpl(String filename) {
     this.filename = filename;
   }
 
@@ -20,7 +20,7 @@
   }
 
   @Override
-  public String getFilename() {
+  public String getSourceFile() {
     return filename;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
index 06143aa..0f29acd 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementProxyRetracerImpl.java
@@ -9,23 +9,21 @@
 import com.android.tools.r8.retrace.RetraceClassResult;
 import com.android.tools.r8.retrace.RetraceFieldResult;
 import com.android.tools.r8.retrace.RetraceFrameResult;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
 import com.android.tools.r8.retrace.RetraceStackTraceProxy;
 import com.android.tools.r8.retrace.RetraceTypeResult;
+import com.android.tools.r8.retrace.RetraceTypeResult.Element;
 import com.android.tools.r8.retrace.RetracedClassReference;
 import com.android.tools.r8.retrace.RetracedFieldReference;
 import com.android.tools.r8.retrace.RetracedMethodReference;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.RetracedTypeReference;
 import com.android.tools.r8.retrace.Retracer;
 import com.android.tools.r8.retrace.StackTraceElementProxy;
 import com.android.tools.r8.retrace.StackTraceElementProxyRetracer;
-import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.ListUtils;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Supplier;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -39,178 +37,169 @@
   }
 
   @Override
-  public Stream<RetraceStackTraceProxy<T, ST>> retrace(ST element) {
-    if (!element.hasClassName()) {
-      RetraceStackTraceProxyImpl.Builder<T, ST> builder =
-          RetraceStackTraceProxyImpl.builder(element);
-      return Stream.of(builder.build());
+  public Stream<? extends RetraceStackTraceProxy<T, ST>> retrace(ST element) {
+    Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults =
+        Stream.of(RetraceStackTraceProxyImpl.create(element));
+    if (!element.hasClassName()
+        && !element.hasFieldOrReturnType()
+        && !element.hasMethodArguments()) {
+      return currentResults;
     }
-    RetraceClassResult classResult = retracer.retraceClass(element.getClassReference());
-    if (element.hasMethodName()) {
-      return retraceMethod(element, classResult);
-    } else if (element.hasFieldName()) {
-      return retraceField(element, classResult);
-    } else {
-      return retraceClassOrType(element, classResult);
+    currentResults = retraceFieldOrReturnType(currentResults, element);
+    currentResults = retracedMethodArguments(currentResults, element);
+    if (element.hasClassName()) {
+      RetraceClassResult classResult = retracer.retraceClass(element.getClassReference());
+      if (element.hasMethodName()) {
+        currentResults = retraceMethod(currentResults, element, classResult);
+      } else if (element.hasFieldName()) {
+        currentResults = retraceField(currentResults, element, classResult);
+      } else {
+        currentResults = retraceClassOrType(currentResults, element, classResult);
+      }
     }
+    return currentResults;
   }
 
-  private Stream<RetraceStackTraceProxy<T, ST>> retraceClassOrType(
-      ST element, RetraceClassResult classResult) {
-    return classResult.stream()
-        .flatMap(
-            classElement ->
-                retraceFieldOrReturnType(element)
-                    .flatMap(
-                        fieldOrReturnTypeConsumer ->
-                            retracedMethodArguments(element)
-                                .map(
-                                    argumentsConsumer -> {
-                                      RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
-                                          RetraceStackTraceProxyImpl.builder(element)
-                                              .setRetracedClass(classElement.getRetracedClass())
-                                              .setAmbiguous(classResult.isAmbiguous())
-                                              .setTopFrame(true);
-                                      argumentsConsumer.accept(proxy);
-                                      fieldOrReturnTypeConsumer.accept(proxy);
-                                      if (element.hasFileName()) {
-                                        proxy.setSourceFile(
-                                            getSourceFile(
-                                                classElement::getSourceFile,
-                                                classElement.getRetracedClass(),
-                                                element.getFileName(),
-                                                classResult.hasRetraceResult()));
-                                      }
-                                      return proxy.build();
-                                    })));
+  private Stream<RetraceStackTraceProxyImpl<T, ST>> retraceClassOrType(
+      Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults,
+      ST element,
+      RetraceClassResult classResult) {
+    return currentResults.flatMap(
+        proxy ->
+            classResult.stream()
+                .map(
+                    classElement -> {
+                      RetraceStackTraceProxyImpl.Builder<T, ST> proxyBuilder =
+                          proxy
+                              .builder()
+                              .setRetracedClass(classElement.getRetracedClass())
+                              .joinAmbiguous(classResult.isAmbiguous())
+                              .setTopFrame(true);
+                      if (element.hasSourceFile()) {
+                        RetracedSourceFile sourceFileResult = classElement.getSourceFile();
+                        proxyBuilder.setSourceFile(
+                            sourceFileResult.hasRetraceResult()
+                                ? sourceFileResult.getSourceFile()
+                                : RetraceUtils.inferSourceFile(
+                                    classElement.getRetracedClass().getTypeName(),
+                                    element.getSourceFile(),
+                                    classResult.hasRetraceResult()));
+                      }
+                      return proxyBuilder.build();
+                    }));
   }
 
-  private Stream<RetraceStackTraceProxy<T, ST>> retraceMethod(
-      ST element, RetraceClassResult classResult) {
-    return retraceFieldOrReturnType(element)
-        .flatMap(
-            fieldOrReturnTypeConsumer ->
-                retracedMethodArguments(element)
-                    .flatMap(
-                        argumentsConsumer -> {
-                          RetraceFrameResult frameResult =
-                              element.hasLineNumber()
-                                  ? classResult.lookupFrame(
-                                      element.getMethodName(), element.getLineNumber())
-                                  : classResult.lookupFrame(element.getMethodName());
-                          return frameResult.stream()
-                              .flatMap(
-                                  frameElement -> {
-                                    List<RetraceStackTraceProxy<T, ST>> retracedProxies =
-                                        new ArrayList<>();
-                                    frameElement.visitNonCompilerSynthesizedFrames(
-                                        (frame, index) -> {
-                                          boolean isTopFrame = retracedProxies.isEmpty();
-                                          RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
-                                              RetraceStackTraceProxyImpl.builder(element)
-                                                  .setRetracedClass(frame.getHolderClass())
-                                                  .setRetracedMethod(frame)
-                                                  .setAmbiguous(
-                                                      frameResult.isAmbiguous() && isTopFrame)
-                                                  .setTopFrame(isTopFrame);
-                                          if (element.hasLineNumber()) {
-                                            proxy.setLineNumber(
-                                                frame.getOriginalPositionOrDefault(
-                                                    element.getLineNumber()));
-                                          }
-                                          if (element.hasFileName()) {
-                                            proxy.setSourceFile(
-                                                getSourceFile(
-                                                    () -> frameElement.getSourceFile(frame),
-                                                    frame.getHolderClass(),
-                                                    element.getFileName(),
-                                                    classResult.hasRetraceResult()));
-                                          }
-                                          fieldOrReturnTypeConsumer.accept(proxy);
-                                          argumentsConsumer.accept(proxy);
-                                          retracedProxies.add(proxy.build());
-                                        });
-                                    return retracedProxies.stream();
-                                  });
-                        }));
+  private Stream<RetraceStackTraceProxyImpl<T, ST>> retraceMethod(
+      Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults,
+      ST element,
+      RetraceClassResult classResult) {
+    return currentResults.flatMap(
+        proxy -> {
+          RetraceFrameResult frameResult =
+              element.hasLineNumber()
+                  ? classResult.lookupFrame(element.getMethodName(), element.getLineNumber())
+                  : classResult.lookupFrame(element.getMethodName());
+          return frameResult.stream()
+              .flatMap(
+                  frameElement -> {
+                    List<RetraceStackTraceProxyImpl<T, ST>> retracedProxies = new ArrayList<>();
+                    frameElement.visitNonCompilerSynthesizedFrames(
+                        (frame, position) -> {
+                          boolean isTopFrame = position == 0;
+                          RetraceStackTraceProxyImpl.Builder<T, ST> proxyBuilder =
+                              proxy
+                                  .builder()
+                                  .setRetracedClass(frame.getHolderClass())
+                                  .setRetracedMethod(frame)
+                                  .joinAmbiguous(frameResult.isAmbiguous() && isTopFrame)
+                                  .setTopFrame(isTopFrame);
+                          if (element.hasLineNumber()) {
+                            proxyBuilder.setLineNumber(
+                                frame.getOriginalPositionOrDefault(element.getLineNumber()));
+                          }
+                          if (element.hasSourceFile()) {
+                            RetracedSourceFile sourceFileResult = frameElement.getSourceFile(frame);
+                            proxyBuilder.setSourceFile(
+                                sourceFileResult.hasRetraceResult()
+                                    ? sourceFileResult.getSourceFile()
+                                    : RetraceUtils.inferSourceFile(
+                                        frame.getHolderClass().getTypeName(),
+                                        element.getSourceFile(),
+                                        classResult.hasRetraceResult()));
+                          }
+                          retracedProxies.add(proxyBuilder.build());
+                        });
+                    return retracedProxies.stream();
+                  });
+        });
   }
 
-  private Stream<RetraceStackTraceProxy<T, ST>> retraceField(
-      ST element, RetraceClassResult classResult) {
-    return retraceFieldOrReturnType(element)
-        .flatMap(
-            fieldOrReturnTypeConsumer ->
-                retracedMethodArguments(element)
-                    .flatMap(
-                        argumentsConsumer -> {
-                          RetraceFieldResult retraceFieldResult =
-                              classResult.lookupField(element.getFieldName());
-                          return retraceFieldResult.stream()
-                              .map(
-                                  fieldElement -> {
-                                    RetraceStackTraceProxyImpl.Builder<T, ST> proxy =
-                                        RetraceStackTraceProxyImpl.builder(element)
-                                            .setRetracedClass(
-                                                fieldElement.getField().getHolderClass())
-                                            .setRetracedField(fieldElement.getField())
-                                            .setAmbiguous(retraceFieldResult.isAmbiguous())
-                                            .setTopFrame(true);
-                                    if (element.hasFileName()) {
-                                      proxy.setSourceFile(
-                                          getSourceFile(
-                                              // May not be fieldElement::getSourceFile since this
-                                              // throws off the jdk11 compiler,
-                                              () -> fieldElement.getSourceFile(),
-                                              fieldElement.getField().getHolderClass(),
-                                              element.getFileName(),
-                                              classResult.hasRetraceResult()));
-                                    }
-                                    fieldOrReturnTypeConsumer.accept(proxy);
-                                    argumentsConsumer.accept(proxy);
-                                    return proxy.build();
-                                  });
-                        }));
+  private Stream<RetraceStackTraceProxyImpl<T, ST>> retraceField(
+      Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults,
+      ST element,
+      RetraceClassResult classResult) {
+    return currentResults.flatMap(
+        proxy -> {
+          RetraceFieldResult retraceFieldResult = classResult.lookupField(element.getFieldName());
+          return retraceFieldResult.stream()
+              .map(
+                  fieldElement -> {
+                    RetraceStackTraceProxyImpl.Builder<T, ST> proxyBuilder =
+                        proxy
+                            .builder()
+                            .setRetracedClass(fieldElement.getField().getHolderClass())
+                            .setRetracedField(fieldElement.getField())
+                            .joinAmbiguous(retraceFieldResult.isAmbiguous())
+                            .setTopFrame(true);
+                    if (element.hasSourceFile()) {
+                      RetracedSourceFile sourceFileResult = fieldElement.getSourceFile();
+                      proxyBuilder.setSourceFile(
+                          sourceFileResult.hasRetraceResult()
+                              ? sourceFileResult.getSourceFile()
+                              : RetraceUtils.inferSourceFile(
+                                  fieldElement.getField().getHolderClass().getTypeName(),
+                                  element.getSourceFile(),
+                                  classResult.hasRetraceResult()));
+                    }
+                    return proxyBuilder.build();
+                  });
+        });
   }
 
-  private String getSourceFile(
-      Supplier<RetraceSourceFileResult> sourceFile,
-      RetracedClassReference classReference,
-      String fileName,
-      boolean hasRetraceResult) {
-    RetraceSourceFileResult sourceFileResult = sourceFile.get();
-    return sourceFileResult.hasRetraceResult()
-        ? sourceFileResult.getFilename()
-        : RetraceUtils.inferFileName(classReference.getTypeName(), fileName, hasRetraceResult);
-  }
-
-  private Stream<Consumer<RetraceStackTraceProxyImpl.Builder<T, ST>>> retraceFieldOrReturnType(
-      ST element) {
+  private Stream<RetraceStackTraceProxyImpl<T, ST>> retraceFieldOrReturnType(
+      Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults, ST element) {
     if (!element.hasFieldOrReturnType()) {
-      return Stream.of(noEffect -> {});
+      return currentResults;
     }
     String elementOrReturnType = element.getFieldOrReturnType();
     if (elementOrReturnType.equals("void")) {
-      return Stream.of(
-          proxy -> proxy.setRetracedFieldOrReturnType(RetracedTypeReferenceImpl.createVoid()));
+      return currentResults.map(
+          proxy ->
+              proxy
+                  .builder()
+                  .setRetracedFieldOrReturnType(RetracedTypeReferenceImpl.createVoid())
+                  .build());
     } else {
       TypeReference typeReference = Reference.typeFromTypeName(elementOrReturnType);
       RetraceTypeResult retraceTypeResult = retracer.retraceType(typeReference);
-      return retraceTypeResult.stream()
-          .map(
-              type ->
-                  (proxy -> {
-                    proxy.setRetracedFieldOrReturnType(type.getType());
-                    if (retraceTypeResult.isAmbiguous()) {
-                      proxy.setAmbiguous(true);
-                    }
-                  }));
+      List<Element> retracedElements = retraceTypeResult.stream().collect(Collectors.toList());
+      return currentResults.flatMap(
+          proxy ->
+              retracedElements.stream()
+                  .map(
+                      retracedResult ->
+                          proxy
+                              .builder()
+                              .setRetracedFieldOrReturnType(retracedResult.getType())
+                              .joinAmbiguous(retraceTypeResult.isAmbiguous())
+                              .build()));
     }
   }
 
-  private Stream<Consumer<RetraceStackTraceProxyImpl.Builder<T, ST>>> retracedMethodArguments(
-      ST element) {
+  private Stream<RetraceStackTraceProxyImpl<T, ST>> retracedMethodArguments(
+      Stream<RetraceStackTraceProxyImpl<T, ST>> currentResults, ST element) {
     if (!element.hasMethodArguments()) {
-      return Stream.of(noEffect -> {});
+      return currentResults;
     }
     List<RetraceTypeResult> retracedResults =
         Arrays.stream(element.getMethodArguments().split(","))
@@ -218,36 +207,33 @@
             .collect(Collectors.toList());
     List<List<RetracedTypeReference>> initial = new ArrayList<>();
     initial.add(new ArrayList<>());
-    Box<Boolean> isAmbiguous = new Box<>(false);
-    List<List<RetracedTypeReference>> retracedArguments =
+    List<List<RetracedTypeReference>> allRetracedArguments =
         ListUtils.fold(
             retracedResults,
             initial,
             (acc, retracedTypeResult) -> {
-              if (retracedTypeResult.isAmbiguous()) {
-                isAmbiguous.set(true);
-              }
               List<List<RetracedTypeReference>> newResult = new ArrayList<>();
               retracedTypeResult.forEach(
-                  retracedElement -> {
-                    acc.forEach(
-                        oldResult -> {
-                          List<RetracedTypeReference> newList = new ArrayList<>(oldResult);
-                          newList.add(retracedElement.getType());
-                          newResult.add(newList);
-                        });
-                  });
+                  retracedElement ->
+                      acc.forEach(
+                          oldResult -> {
+                            List<RetracedTypeReference> newList = new ArrayList<>(oldResult);
+                            newList.add(retracedElement.getType());
+                            newResult.add(newList);
+                          }));
               return newResult;
             });
-    return retracedArguments.stream()
-        .map(
-            arguments ->
-                proxy -> {
-                  proxy.setRetracedMethodArguments(arguments);
-                  if (isAmbiguous.get()) {
-                    proxy.setAmbiguous(true);
-                  }
-                });
+    boolean isAmbiguous = allRetracedArguments.size() > 1;
+    return currentResults.flatMap(
+        proxy ->
+            allRetracedArguments.stream()
+                .map(
+                    retracedArguments ->
+                        proxy
+                            .builder()
+                            .setRetracedMethodArguments(retracedArguments)
+                            .joinAmbiguous(isAmbiguous)
+                            .build()));
   }
 
   public static class RetraceStackTraceProxyImpl<T, ST extends StackTraceElementProxy<T, ST>>
@@ -368,9 +354,24 @@
       return sourceFile;
     }
 
-    private static <T, ST extends StackTraceElementProxy<T, ST>> Builder<T, ST> builder(
-        ST originalElement) {
-      return new Builder<>(originalElement);
+    private static <T, ST extends StackTraceElementProxy<T, ST>>
+        RetraceStackTraceProxyImpl<T, ST> create(ST originalItem) {
+      return new RetraceStackTraceProxyImpl<T, ST>(
+          originalItem, null, null, null, null, null, null, -1, false, false);
+    }
+
+    private Builder<T, ST> builder() {
+      Builder<T, ST> builder = new Builder<>(originalItem);
+      builder.classContext = retracedClass;
+      builder.methodContext = retracedMethod;
+      builder.retracedField = retracedField;
+      builder.fieldOrReturnType = fieldOrReturnType;
+      builder.methodArguments = methodArguments;
+      builder.sourceFile = sourceFile;
+      builder.lineNumber = lineNumber;
+      builder.isAmbiguous = isAmbiguous;
+      builder.isTopFrame = isTopFrame;
+      return builder;
     }
 
     @Override
@@ -473,8 +474,8 @@
         return this;
       }
 
-      private Builder<T, ST> setAmbiguous(boolean ambiguous) {
-        this.isAmbiguous = ambiguous;
+      private Builder<T, ST> joinAmbiguous(boolean ambiguous) {
+        this.isAmbiguous = ambiguous || this.isAmbiguous;
         return this;
       }
 
@@ -483,7 +484,7 @@
         return this;
       }
 
-      private RetraceStackTraceProxy<T, ST> build() {
+      private RetraceStackTraceProxyImpl<T, ST> build() {
         RetracedClassReference retracedClass = classContext;
         if (methodContext != null) {
           retracedClass = methodContext.getHolderClass();
diff --git a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
index 5f512f4..0b22dae 100644
--- a/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
+++ b/src/main/java/com/android/tools/r8/retrace/internal/StackTraceElementStringProxy.java
@@ -69,7 +69,7 @@
   }
 
   @Override
-  public boolean hasFileName() {
+  public boolean hasSourceFile() {
     return sourceFile.hasIndex();
   }
 
@@ -104,8 +104,8 @@
   }
 
   @Override
-  public String getFileName() {
-    return hasFileName() ? getEntryInLine(sourceFile) : null;
+  public String getSourceFile() {
+    return hasSourceFile() ? getEntryInLine(sourceFile) : null;
   }
 
   @Override
@@ -225,7 +225,7 @@
               startIndex,
               endIndex,
               (retraced, original, verbose) ->
-                  retraced.hasSourceFile() ? retraced.getSourceFile() : original.getFileName());
+                  retraced.hasSourceFile() ? retraced.getSourceFile() : original.getSourceFile());
       orderedIndices.add(sourceFile);
       return this;
     }
diff --git a/src/test/java/com/android/tools/r8/retrace/SourceFileTest.java b/src/test/java/com/android/tools/r8/retrace/SourceFileTest.java
index 30dc206..5bc7a26 100644
--- a/src/test/java/com/android/tools/r8/retrace/SourceFileTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/SourceFileTest.java
@@ -63,7 +63,7 @@
                   .clazz(ClassWithCustomFileName.class)
                   .retraceUnique()
                   .getSourceFile()
-                  .getFilename());
+                  .getSourceFile());
         }));
   }
 
@@ -78,7 +78,7 @@
               inspector.clazz(ClassWithoutCustomFileName.class).retraceUnique();
           assertEquals(
               "SourceFileTest.java",
-              RetraceUtils.inferFileName(
+              RetraceUtils.inferSourceFile(
                   retraceClassElement.getRetracedClass().getTypeName(), "nofile.java", true));
         }));
   }
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiInferSourceFileTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiInferSourceFileTest.java
index 829969d..5563fea 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiInferSourceFileTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiInferSourceFileTest.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.retrace.ProguardMapProducer;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import java.util.ArrayList;
 import java.util.List;
@@ -40,7 +40,7 @@
 
     @Test
     public void testRetracingSourceFile() {
-      List<RetraceSourceFileResult> sourceFileResults = new ArrayList<>();
+      List<RetracedSourceFile> sourceFileResults = new ArrayList<>();
       Retracer.createDefault(ProguardMapProducer.fromString(mapping), new DiagnosticsHandler() {})
           .retraceClass(Reference.classFromTypeName("a"))
           .forEach(clazz -> sourceFileResults.add(clazz.getSourceFile()));
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileNotFoundTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileNotFoundTest.java
index a567df1..29a97e9 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileNotFoundTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileNotFoundTest.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.retrace.ProguardMapProducer;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import java.util.ArrayList;
 import java.util.List;
@@ -40,7 +40,7 @@
 
     @Test
     public void testRetracingSourceFile() {
-      List<RetraceSourceFileResult> sourceFileResults = new ArrayList<>();
+      List<RetracedSourceFile> sourceFileResults = new ArrayList<>();
       Retracer.createDefault(ProguardMapProducer.fromString(mapping), new DiagnosticsHandler() {})
           .retraceClass(Reference.classFromTypeName("a"))
           .forEach(clazz -> sourceFileResults.add(clazz.getSourceFile()));
diff --git a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileTest.java b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileTest.java
index f94e0e4..e3152e8 100644
--- a/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileTest.java
+++ b/src/test/java/com/android/tools/r8/retrace/api/RetraceApiSourceFileTest.java
@@ -11,7 +11,7 @@
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.references.Reference;
 import com.android.tools.r8.retrace.ProguardMapProducer;
-import com.android.tools.r8.retrace.RetraceSourceFileResult;
+import com.android.tools.r8.retrace.RetracedSourceFile;
 import com.android.tools.r8.retrace.Retracer;
 import java.util.ArrayList;
 import java.util.List;
@@ -41,13 +41,13 @@
 
     @Test
     public void testRetracingSourceFile() {
-      List<RetraceSourceFileResult> sourceFileResults = new ArrayList<>();
+      List<RetracedSourceFile> sourceFileResults = new ArrayList<>();
       Retracer.createDefault(ProguardMapProducer.fromString(mapping), new DiagnosticsHandler() {})
           .retraceClass(Reference.classFromTypeName("a"))
           .forEach(clazz -> sourceFileResults.add(clazz.getSourceFile()));
       assertEquals(1, sourceFileResults.size());
       assertTrue(sourceFileResults.get(0).hasRetraceResult());
-      assertEquals("SomeFileName.kt", sourceFileResults.get(0).getFilename());
+      assertEquals("SomeFileName.kt", sourceFileResults.get(0).getSourceFile());
     }
   }
 }
diff --git a/third_party/retrace/binary_compatibility.tar.gz.sha1 b/third_party/retrace/binary_compatibility.tar.gz.sha1
index 0aafcf6..c0a96df 100644
--- a/third_party/retrace/binary_compatibility.tar.gz.sha1
+++ b/third_party/retrace/binary_compatibility.tar.gz.sha1
@@ -1 +1 @@
-23a607be2e3644321df25d73e1db663ad06e79cb
\ No newline at end of file
+023b8abaf2b44716bde90de6cf34327765651c3d
\ No newline at end of file