Create a wrapper around Hashing to allow using it from tests

Hasher is a guava type and is therefore not accessible when running
tests on r8lib.

Change-Id: I0d67486fcce98e2cf75f5a169cfe218246a8e90d
diff --git a/src/main/java/com/android/tools/r8/contexts/CompilationContext.java b/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
index f037883..d3db39a 100644
--- a/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
+++ b/src/main/java/com/android/tools/r8/contexts/CompilationContext.java
@@ -6,8 +6,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.utils.InternalOptions;
-import com.google.common.hash.Hasher;
-import com.google.common.hash.Hashing;
+import com.android.tools.r8.utils.structural.HasherWrapper;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
@@ -143,9 +142,9 @@
 
     private StringBuilder buildSuffix(StringBuilder builder) {
       // TODO(b/172194101): Sanitize the method descriptor instead of hashing.
-      Hasher hasher = Hashing.sha256().newHasher();
+      HasherWrapper hasher = HasherWrapper.sha256Hasher();
       method.getReference().hash(hasher);
-      return builder.append('$').append(hasher.hash().toString());
+      return builder.append('$').append(hasher.hashCodeAsString());
     }
 
     @Override
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassDefinition.java
index a05d505..c641e9e 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClasspathClassDefinition.java
@@ -5,8 +5,8 @@
 
 import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.structural.HasherWrapper;
 import com.android.tools.r8.utils.structural.RepresentativeMap;
-import com.google.common.hash.Hasher;
 
 /**
  * Definition of a synthetic classpath class.
@@ -44,7 +44,7 @@
   }
 
   @Override
-  void internalComputeHash(Hasher hasher, RepresentativeMap map) {
+  void internalComputeHash(HasherWrapper hasher, RepresentativeMap map) {
     clazz.hashWithTypeEquivalence(hasher, map);
   }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
index 7c1decc..ee6c8b0 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticDefinition.java
@@ -8,10 +8,9 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.structural.HasherWrapper;
 import com.android.tools.r8.utils.structural.RepresentativeMap;
 import com.google.common.hash.HashCode;
-import com.google.common.hash.Hasher;
-import com.google.common.hash.Hashing;
 
 /**
  * Base type for the definition of a synthetic item.
@@ -70,7 +69,7 @@
       boolean intermediate,
       ClassToFeatureSplitMap classToFeatureSplitMap,
       SyntheticItems syntheticItems) {
-    Hasher hasher = Hashing.murmur3_128().newHasher();
+    HasherWrapper hasher = HasherWrapper.murmur3_128Hasher();
     hasher.putInt(kind.id);
     if (getKind().isFixedSuffixSynthetic) {
       // Fixed synthetics are non-shareable. Its unique type is used as the hash key.
@@ -87,7 +86,7 @@
     return hasher.hash();
   }
 
-  abstract void internalComputeHash(Hasher hasher, RepresentativeMap map);
+  abstract void internalComputeHash(HasherWrapper hasher, RepresentativeMap map);
 
   final boolean isEquivalentTo(
       D other,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
index a9d11c7..d00eb21 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodDefinition.java
@@ -6,8 +6,8 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.structural.HasherWrapper;
 import com.android.tools.r8.utils.structural.RepresentativeMap;
-import com.google.common.hash.Hasher;
 import java.util.function.Consumer;
 
 /**
@@ -59,7 +59,7 @@
   }
 
   @Override
-  void internalComputeHash(Hasher hasher, RepresentativeMap map) {
+  void internalComputeHash(HasherWrapper hasher, RepresentativeMap map) {
     method.getDefinition().hashWithTypeEquivalence(hasher, map);
   }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassDefinition.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassDefinition.java
index 3506dab..077bc76 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassDefinition.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticProgramClassDefinition.java
@@ -5,8 +5,8 @@
 
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.structural.HasherWrapper;
 import com.android.tools.r8.utils.structural.RepresentativeMap;
-import com.google.common.hash.Hasher;
 import java.util.function.Consumer;
 
 /**
@@ -54,7 +54,7 @@
   }
 
   @Override
-  void internalComputeHash(Hasher hasher, RepresentativeMap map) {
+  void internalComputeHash(HasherWrapper hasher, RepresentativeMap map) {
     clazz.hashWithTypeEquivalence(hasher, map);
   }
 
diff --git a/src/main/java/com/android/tools/r8/utils/structural/DefaultHashingVisitor.java b/src/main/java/com/android/tools/r8/utils/structural/DefaultHashingVisitor.java
index d1b6653..2062478 100644
--- a/src/main/java/com/android/tools/r8/utils/structural/DefaultHashingVisitor.java
+++ b/src/main/java/com/android/tools/r8/utils/structural/DefaultHashingVisitor.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.utils.structural;
 
 import com.android.tools.r8.utils.structural.StructuralItem.HashingAccept;
-import com.google.common.hash.Hasher;
 
 /**
  * Default visitor for hashing a structural item.
@@ -14,11 +13,11 @@
  */
 public class DefaultHashingVisitor {
 
-  public static <T> void run(T item, Hasher hasher, StructuralMapping<T> accept) {
+  public static <T> void run(T item, HasherWrapper hasher, StructuralMapping<T> accept) {
     run(item, hasher, (i, visitor) -> visitor.visit(i, accept));
   }
 
-  public static <T> void run(T item, Hasher hasher, HashingAccept<T> hashingAccept) {
+  public static <T> void run(T item, HasherWrapper hasher, HashingAccept<T> hashingAccept) {
     HashingVisitorWithTypeEquivalence.run(item, hasher, t -> t, hashingAccept);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/utils/structural/HasherWrapper.java b/src/main/java/com/android/tools/r8/utils/structural/HasherWrapper.java
new file mode 100644
index 0000000..ef1c9f7
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/utils/structural/HasherWrapper.java
@@ -0,0 +1,90 @@
+// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.utils.structural;
+
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hasher;
+import com.google.common.hash.Hashing;
+
+/**
+ * This is an interface that mimics the Hasher interface in Guava which allows us to use hashing in
+ * the tests.
+ */
+public interface HasherWrapper {
+
+  void putBoolean(boolean value);
+
+  void putInt(int value);
+
+  void putFloat(float value);
+
+  void putLong(long value);
+
+  void putDouble(double value);
+
+  void putBytes(byte[] content);
+
+  /** Do not use from tests */
+  HashCode hash();
+
+  String hashCodeAsString();
+
+  static HasherWrapper sha256Hasher() {
+    return new HasherWrapped(Hashing.sha256().newHasher());
+  }
+
+  static HasherWrapper murmur3_128Hasher() {
+    return new HasherWrapped(Hashing.murmur3_128().newHasher());
+  }
+
+  class HasherWrapped implements HasherWrapper {
+
+    private final Hasher hasher;
+
+    public HasherWrapped(Hasher hasher) {
+      this.hasher = hasher;
+    }
+
+    @Override
+    public void putBoolean(boolean value) {
+      hasher.putBoolean(value);
+    }
+
+    @Override
+    public void putInt(int value) {
+      hasher.putInt(value);
+    }
+
+    @Override
+    public void putFloat(float value) {
+      hasher.putFloat(value);
+    }
+
+    @Override
+    public void putLong(long value) {
+      hasher.putLong(value);
+    }
+
+    @Override
+    public void putDouble(double value) {
+      hasher.putDouble(value);
+    }
+
+    @Override
+    public void putBytes(byte[] content) {
+      hasher.putBytes(content);
+    }
+
+    @Override
+    public HashCode hash() {
+      return hasher.hash();
+    }
+
+    @Override
+    public String hashCodeAsString() {
+      return hasher.hash().toString();
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/utils/structural/HashingVisitor.java b/src/main/java/com/android/tools/r8/utils/structural/HashingVisitor.java
index 696c454..538ddcd 100644
--- a/src/main/java/com/android/tools/r8/utils/structural/HashingVisitor.java
+++ b/src/main/java/com/android/tools/r8/utils/structural/HashingVisitor.java
@@ -9,11 +9,9 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.utils.structural.StructuralItem.HashingAccept;
-import com.google.common.hash.Hasher;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.function.BiConsumer;
 
 public abstract class HashingVisitor {
 
@@ -55,7 +53,4 @@
   }
 
   public abstract <S> void visit(S item, StructuralMapping<S> accept);
-
-  @Deprecated
-  public abstract <S> void visit(S item, BiConsumer<S, Hasher> hasher);
 }
diff --git a/src/main/java/com/android/tools/r8/utils/structural/HashingVisitorWithTypeEquivalence.java b/src/main/java/com/android/tools/r8/utils/structural/HashingVisitorWithTypeEquivalence.java
index ff0e4ba..303f212 100644
--- a/src/main/java/com/android/tools/r8/utils/structural/HashingVisitorWithTypeEquivalence.java
+++ b/src/main/java/com/android/tools/r8/utils/structural/HashingVisitorWithTypeEquivalence.java
@@ -8,9 +8,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.utils.structural.StructuralItem.CompareToAccept;
 import com.android.tools.r8.utils.structural.StructuralItem.HashingAccept;
-import com.google.common.hash.Hasher;
 import java.util.Iterator;
-import java.util.function.BiConsumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.ToDoubleFunction;
@@ -21,19 +19,19 @@
 public class HashingVisitorWithTypeEquivalence extends HashingVisitor {
 
   public static <T> void run(
-      T item, Hasher hasher, RepresentativeMap map, StructuralMapping<T> accept) {
+      T item, HasherWrapper hasher, RepresentativeMap map, StructuralMapping<T> accept) {
     run(item, hasher, map, (i, visitor) -> visitor.visit(i, accept));
   }
 
   public static <T> void run(
-      T item, Hasher hasher, RepresentativeMap map, HashingAccept<T> hashingAccept) {
+      T item, HasherWrapper hasher, RepresentativeMap map, HashingAccept<T> hashingAccept) {
     hashingAccept.acceptHashing(item, new HashingVisitorWithTypeEquivalence(hasher, map));
   }
 
-  private final Hasher hash;
+  private final HasherWrapper hash;
   private final RepresentativeMap representatives;
 
-  private HashingVisitorWithTypeEquivalence(Hasher hash, RepresentativeMap representatives) {
+  private HashingVisitorWithTypeEquivalence(HasherWrapper hash, RepresentativeMap representatives) {
     this.hash = hash;
     this.representatives = representatives;
   }
@@ -85,11 +83,6 @@
     }
   }
 
-  @Override
-  public <S> void visit(S item, BiConsumer<S, Hasher> hasher) {
-    hasher.accept(item, hash);
-  }
-
   private static class ItemSpecification<T>
       extends StructuralSpecification<T, ItemSpecification<T>> {
 
diff --git a/src/main/java/com/android/tools/r8/utils/structural/StructuralItem.java b/src/main/java/com/android/tools/r8/utils/structural/StructuralItem.java
index 8740299..057a18c 100644
--- a/src/main/java/com/android/tools/r8/utils/structural/StructuralItem.java
+++ b/src/main/java/com/android/tools/r8/utils/structural/StructuralItem.java
@@ -3,9 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.utils.structural;
 
-import com.google.common.hash.Hasher;
-import com.google.common.hash.Hashing;
-
 /** Specified types must implement methods to determine equality, hashing and order. */
 public interface StructuralItem<T extends StructuralItem<T>> extends Ordered<T> {
 
@@ -60,24 +57,17 @@
    * <p>This should *not* be overwritten, instead items should overwrite acceptHashing which will
    * ensure that the effect is in place for any HashingVisitor.
    */
-  default void hash(Hasher hasher) {
+  default void hash(HasherWrapper hasher) {
     DefaultHashingVisitor.run(self(), hasher, StructuralItem::acceptHashing);
   }
 
-  /** Hashing method to use from tests to avoid having guava types shared between R8 and tests. */
-  default String hashForTesting() {
-    Hasher hasher = Hashing.sha256().newHasher();
-    hash(hasher);
-    return hasher.hash().toString();
-  }
-
   /**
    * Implementation of the default hashing with a type equivalence on the item.
    *
    * <p>This should *not* be overwritten, instead items should overwrite acceptHashing which will
    * ensure that the effect is in place for any HashingVisitor.
    */
-  default void hashWithTypeEquivalence(Hasher hasher, RepresentativeMap map) {
+  default void hashWithTypeEquivalence(HasherWrapper hasher, RepresentativeMap map) {
     HashingVisitorWithTypeEquivalence.run(self(), hasher, map, StructuralItem::acceptHashing);
   }
 
diff --git a/src/test/java/com/android/tools/r8/utils/structural/StructuralItemsTest.java b/src/test/java/com/android/tools/r8/utils/structural/StructuralItemsTest.java
index b9580ed..147cc34 100644
--- a/src/test/java/com/android/tools/r8/utils/structural/StructuralItemsTest.java
+++ b/src/test/java/com/android/tools/r8/utils/structural/StructuralItemsTest.java
@@ -88,7 +88,9 @@
   }
 
   private String getHash(StructuralItem<?> item) {
-    return item.hashForTesting();
+    HasherWrapper hasherWrapper = HasherWrapper.sha256Hasher();
+    item.hash(hasherWrapper);
+    return hasherWrapper.hashCodeAsString();
   }
 
   @Test