Issue warning if -injars or -libraryjars are given non-archive arguments.
Bug: 133122577
Change-Id: I96adff1ddec9fcedd49bd85a2ae8af51aab80081
diff --git a/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java b/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
index 9badf35..9bef056 100644
--- a/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
+++ b/src/main/java/com/android/tools/r8/shaking/FilteredClassPath.java
@@ -3,10 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
import com.google.common.collect.ImmutableList;
-import java.io.File;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
/**
@@ -21,32 +21,36 @@
private final Path path;
private final ImmutableList<String> pattern;
+ private final Origin origin;
+ private final Position position;
- public FilteredClassPath(Path path, List<String> pattern) {
+ public FilteredClassPath(Path path, List<String> pattern, Origin origin, Position position) {
this.path = path;
this.pattern = ImmutableList.copyOf(pattern);
+ this.origin = origin;
+ this.position = position;
}
private FilteredClassPath(Path path) {
- this(path, ImmutableList.of());
- }
-
- public static FilteredClassPath unfiltered(File file) {
- return new FilteredClassPath(file.toPath());
+ this(path, ImmutableList.of(), Origin.unknown(), Position.UNKNOWN);
}
public static FilteredClassPath unfiltered(Path path) {
return new FilteredClassPath(path);
}
- public static FilteredClassPath unfiltered(String path) {
- return new FilteredClassPath(Paths.get(path));
- }
-
public Path getPath() {
return path;
}
+ public Origin getOrigin() {
+ return origin;
+ }
+
+ public Position getPosition() {
+ return position;
+ }
+
public boolean matchesFile(String name) {
if (isUnfiltered()) {
return true;
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index f5da927..8218679 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -1238,13 +1238,14 @@
private List<FilteredClassPath> parseClassPath() throws ProguardRuleParserException {
List<FilteredClassPath> classPath = new ArrayList<>();
skipWhitespace();
+ TextPosition position = getPosition();
Path file = parseFileName(true);
ImmutableList<String> filters = parseClassPathFilters();
- classPath.add(new FilteredClassPath(file, filters));
+ classPath.add(new FilteredClassPath(file, filters, origin, position));
while (acceptChar(File.pathSeparatorChar)) {
file = parseFileName(true);
filters = parseClassPathFilters();
- classPath.add(new FilteredClassPath(file, filters));
+ classPath.add(new FilteredClassPath(file, filters, origin, position));
}
return classPath;
}
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index f420261..4b0e3fc 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -440,10 +440,17 @@
/** Add filtered archives of program resources. */
public Builder addFilteredProgramArchives(Collection<FilteredClassPath> filteredArchives) {
for (FilteredClassPath archive : filteredArchives) {
- assert isArchive(archive.getPath());
- ArchiveResourceProvider archiveResourceProvider =
- new ArchiveResourceProvider(archive, ignoreDexInArchive);
- addProgramResourceProvider(archiveResourceProvider);
+ if (isArchive(archive.getPath())) {
+ ArchiveResourceProvider archiveResourceProvider =
+ new ArchiveResourceProvider(archive, ignoreDexInArchive);
+ addProgramResourceProvider(archiveResourceProvider);
+ } else {
+ reporter.error(
+ new StringDiagnostic(
+ "Unexpected input type. Only archive types are supported, e.g., .jar, .zip, etc.",
+ archive.getOrigin(),
+ archive.getPosition()));
+ }
}
return this;
}
@@ -503,13 +510,21 @@
/** Add library file resources. */
public Builder addFilteredLibraryArchives(Collection<FilteredClassPath> filteredArchives) {
for (FilteredClassPath archive : filteredArchives) {
- assert isArchive(archive.getPath());
- try {
- FilteredArchiveClassFileProvider provider = new FilteredArchiveClassFileProvider(archive);
- archiveProvidersToClose.add(provider);
- libraryResourceProviders.add(provider);
- } catch (IOException e) {
- reporter.error(new ExceptionDiagnostic(e, new PathOrigin(archive.getPath())));
+ if (isArchive(archive.getPath())) {
+ try {
+ FilteredArchiveClassFileProvider provider =
+ new FilteredArchiveClassFileProvider(archive);
+ archiveProvidersToClose.add(provider);
+ libraryResourceProviders.add(provider);
+ } catch (IOException e) {
+ reporter.error(new ExceptionDiagnostic(e, new PathOrigin(archive.getPath())));
+ }
+ } else {
+ reporter.error(
+ new StringDiagnostic(
+ "Unexpected input type. Only archive types are supported, e.g., .jar, .zip, etc.",
+ archive.getOrigin(),
+ archive.getPosition()));
}
}
return this;
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index a587685..62cb1e3 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -101,6 +101,10 @@
graphConsumer);
}
+ public Builder getBuilder() {
+ return builder;
+ }
+
public T addProgramResourceProvider(ProgramResourceProvider provider) {
builder.addProgramResourceProvider(provider);
return self();
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 1cc8eb0..9fef6f1 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -20,6 +20,8 @@
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
import com.android.tools.r8.shaking.FilteredClassPath;
import com.android.tools.r8.shaking.ProguardConfiguration;
import com.android.tools.r8.shaking.ProguardConfigurationParser;
@@ -1030,9 +1032,13 @@
}
public static void addFilteredAndroidJar(AndroidApp.Builder builder, AndroidApiLevel apiLevel) {
- builder.addFilteredLibraryArchives(Collections.singletonList(
- new FilteredClassPath(getAndroidJar(apiLevel),
- ImmutableList.of("!junit/**", "!android/test/**"))));
+ builder.addFilteredLibraryArchives(
+ Collections.singletonList(
+ new FilteredClassPath(
+ getAndroidJar(apiLevel),
+ ImmutableList.of("!junit/**", "!android/test/**"),
+ Origin.unknown(),
+ Position.UNKNOWN)));
}
public static AndroidApp runD8(AndroidApp app) throws CompilationFailedException {
diff --git a/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java b/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
index f5d642e..32ff5da 100644
--- a/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/FilteredClassPathTest.java
@@ -9,6 +9,8 @@
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.ThrowingBiFunction;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.Position;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidApp.Builder;
import com.android.tools.r8.utils.ListUtils;
@@ -42,7 +44,8 @@
}
private static FilteredClassPath makeFilteredClassPath(Path path, List<String> filters) {
- return new FilteredClassPath(path, ImmutableList.copyOf(filters));
+ return new FilteredClassPath(
+ path, ImmutableList.copyOf(filters), Origin.unknown(), Position.UNKNOWN);
}
@Test
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardDirectoryInputsTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardDirectoryInputsTest.java
new file mode 100644
index 0000000..352d268
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardDirectoryInputsTest.java
@@ -0,0 +1,116 @@
+// Copyright (c) 2019, 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.shaking;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.ByteDataView;
+import com.android.tools.r8.ClassFileConsumer.DirectoryConsumer;
+import com.android.tools.r8.CompilationFailedException;
+import com.android.tools.r8.Diagnostic;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.position.TextPosition;
+import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import java.util.Collections;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ProguardDirectoryInputsTest extends TestBase {
+
+ static final String EXPECTED = StringUtils.lines("Hello, world");
+
+ private final TestParameters parameters;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimes().withAllApiLevels().build();
+ }
+
+ public ProguardDirectoryInputsTest(TestParameters parameters) {
+ this.parameters = parameters;
+ }
+
+ @Test(expected = CompilationFailedException.class)
+ public void testInJars() throws Exception {
+ test("injars");
+ }
+
+ @Test(expected = CompilationFailedException.class)
+ public void testLibraryJars() throws Exception {
+ test("libraryjars");
+ }
+
+ private void test(String option) throws Exception {
+ Path directory = temp.newFolder().toPath();
+ {
+ DirectoryConsumer consumer = new DirectoryConsumer(directory);
+ consumer.accept(
+ ByteDataView.of(ToolHelper.getClassAsBytes(OtherClass.class)),
+ DescriptorUtils.javaTypeToDescriptor(OtherClass.class.getTypeName()),
+ null);
+ consumer.finished(null);
+ }
+ if (parameters.isCfRuntime()) {
+ testForJvm()
+ .addProgramClasses(TestClass.class)
+ .addClasspath(directory)
+ .run(parameters.getRuntime(), TestClass.class)
+ .assertSuccessWithOutput(EXPECTED);
+ }
+
+ Origin origin =
+ new Origin(Origin.root()) {
+ @Override
+ public String part() {
+ return "pg-test-input";
+ }
+ };
+
+ String prefix = "-" + option + " ";
+ testForR8(parameters.getBackend())
+ .addProgramClasses(TestClass.class)
+ .apply(
+ b -> {
+ b.getBuilder()
+ .addProguardConfiguration(
+ Collections.singletonList(prefix + directory.toAbsolutePath()), origin);
+ })
+ .addKeepMainRule(TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .compileWithExpectedDiagnostics(diagnostics -> {
+ diagnostics.assertOnlyErrors();
+ diagnostics.assertErrorsCount(1);
+ Diagnostic diagnostic = diagnostics.getErrors().get(0);
+ assertThat(diagnostic.getDiagnosticMessage(), containsString("Unexpected input type"));
+ assertEquals(origin, diagnostic.getOrigin());
+ TextPosition position = (TextPosition) diagnostic.getPosition();
+ assertEquals(1, position.getLine());
+ assertEquals(prefix.length() + 1, position.getColumn());
+ });
+ }
+
+ static class TestClass {
+
+ public static void main(String[] args) {
+ System.out.println("Hello, world");
+ }
+ }
+
+ static class OtherClass {
+
+ public void foo() {
+ System.out.println("foo");
+ }
+ }
+}