diff options
author | 2017-12-13 13:52:35 -0800 | |
---|---|---|
committer | 2017-12-13 13:55:15 -0800 | |
commit | 817b535d92ee7fdb4740e2a99505ab10d4b54a0d (patch) | |
tree | 449b1a158bd05e2ea9f566b04a39cc25e4adcf75 | |
parent | 0cb96d1e3db39cb3054d2bcedc8e959ec60b0d45 (diff) |
make desugar resilient to unrelated lambdas being dumped while it runs
RELNOTES: None.
PiperOrigin-RevId: 178952440
-rw-r--r-- | src/test/java/com/google/devtools/build/android/desugar/BUILD | 18 | ||||
-rw-r--r-- | src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java | 37 |
2 files changed, 37 insertions, 18 deletions
diff --git a/src/test/java/com/google/devtools/build/android/desugar/BUILD b/src/test/java/com/google/devtools/build/android/desugar/BUILD index c1e011a3bc..69b30c2287 100644 --- a/src/test/java/com/google/devtools/build/android/desugar/BUILD +++ b/src/test/java/com/google/devtools/build/android/desugar/BUILD @@ -1913,6 +1913,24 @@ genrule( ], ) +# Regression test for b/70415451 +genrule( + name = "desugar_guava_at_head", + srcs = [ + "//third_party:guava-jars", + # Depend on Jacoco runtime in case testdata was built with coverage + # instrumentation + "//third_party/java/jacoco:blaze-agent", + "//tools/defaults:android_jar", + ], + outs = ["guava_at_head_desugared.jar"], + cmd = "$(location //src/tools/android/java/com/google/devtools/build/android/desugar:Desugar) " + + "-i $(location //third_party:guava-jars) -o $@ " + + "--bootclasspath_entry $(location //tools/defaults:android_jar)", + tags = ["no_windows"], + tools = ["//src/tools/android/java/com/google/devtools/build/android/desugar:Desugar"], +) + java_binary( name = "generate_lambda_with_constant_arguments", srcs = ["Bug62060793TestDataGenerator.java"], diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java index beaeb0356f..1f240ef507 100644 --- a/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java +++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java @@ -14,18 +14,19 @@ package com.google.devtools.build.android.desugar; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.collect.Iterables.getOnlyElement; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterators; import java.io.IOException; import java.lang.invoke.MethodHandle; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.Predicate; -import java.util.stream.Stream; +import java.util.Set; class LambdaClassMaker { @@ -33,6 +34,7 @@ class LambdaClassMaker { private final Path rootDirectory; private final Map<Path, LambdaInfo> generatedClasses = new LinkedHashMap<>(); + private final Set<Path> existingPaths = new HashSet<>(); public LambdaClassMaker(Path rootDirectory) { checkArgument( @@ -42,7 +44,9 @@ class LambdaClassMaker { public void generateLambdaClass(String invokerInternalName, LambdaInfo lambdaInfo, MethodHandle bootstrapMethod, ArrayList<Object> bsmArgs) throws IOException { - // Invoking the bootstrap method will dump the generated class + // Invoking the bootstrap method will dump the generated class. Ignore any pre-existing + // matching files, which can come from desugar's implementation using classes being desugared. + existingPaths.addAll(findUnprocessed(invokerInternalName + "$$Lambda$")); try { bootstrapMethod.invokeWithArguments(bsmArgs); } catch (Throwable e) { @@ -50,8 +54,9 @@ class LambdaClassMaker { + invokerInternalName + " using " + bootstrapMethod + " with arguments " + bsmArgs, e); } - Path generatedClassFile = findOnlyUnprocessed(invokerInternalName + "$$Lambda$"); + Path generatedClassFile = getOnlyElement(findUnprocessed(invokerInternalName + "$$Lambda$")); generatedClasses.put(generatedClassFile, lambdaInfo); + existingPaths.add(generatedClassFile); } /** @@ -64,7 +69,7 @@ class LambdaClassMaker { return result; } - private Path findOnlyUnprocessed(String pathPrefix) throws IOException { + private ImmutableList<Path> findUnprocessed(String pathPrefix) throws IOException { // pathPrefix is an internal class name prefix containing '/', but paths obtained on Windows // will not contain '/' and searches will fail. So, construct an absolute path from the given // string and use its string representation to find the file we need regardless of host @@ -72,18 +77,14 @@ class LambdaClassMaker { Path rootPathPrefix = rootDirectory.resolve(pathPrefix); final String rootPathPrefixStr = rootPathPrefix.toString(); - // TODO(bazel-team): This could be much nicer with lambdas - try (Stream<Path> paths = - Files.list(rootPathPrefix.getParent()) - .filter( - new Predicate<Path>() { - @Override - public boolean test(Path path) { - return path.toString().startsWith(rootPathPrefixStr) - && !generatedClasses.containsKey(path); - } - })) { - return Iterators.getOnlyElement(paths.iterator()); + if (!Files.exists(rootPathPrefix.getParent())) { + return ImmutableList.of(); } + return Files.list(rootPathPrefix.getParent()) + .filter( + path -> + path.toString().startsWith(rootPathPrefixStr) + && !existingPaths.contains(path)) + .collect(ImmutableList.toImmutableList()); } } |