Add validation of R8 partial include/exclude patterns

Failing compilation in presence of invalid patterns avoid confusion why the patterns are not evaluated correctly.

Fixes: b/410541056
Change-Id: Ibf3fbc466b69877c91d1afce3b5628017f7144be
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialCompilationConfiguration.java b/src/main/java/com/android/tools/r8/partial/R8PartialCompilationConfiguration.java
index d090004..20514e3 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialCompilationConfiguration.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialCompilationConfiguration.java
@@ -190,15 +190,28 @@
         return new UnnamedPackageMatcher();
       } else if (descriptorPrefix.endsWith("/**")) {
         return new PackageAndSubpackagePrefixMatcher(
-            descriptorPrefix.substring(0, descriptorPrefix.length() - 2));
+            extractDescriptorPrefixWithoutWildcards(descriptorPrefix, 2));
       } else if (descriptorPrefix.endsWith("/*")) {
         return new PackagePrefixMatcher(
-            descriptorPrefix.substring(0, descriptorPrefix.length() - 1));
+            extractDescriptorPrefixWithoutWildcards(descriptorPrefix, 1));
       } else if (descriptorPrefix.endsWith("*")) {
-        return new ClassPrefixMatcher(descriptorPrefix.substring(0, descriptorPrefix.length() - 1));
+        return new ClassPrefixMatcher(extractDescriptorPrefixWithoutWildcards(descriptorPrefix, 1));
       } else {
-        return new ClassNameMatcher(descriptorPrefix + ';');
+        return new ClassNameMatcher(
+            extractDescriptorPrefixWithoutWildcards(descriptorPrefix, 0) + ';');
       }
     }
+
+    private static String extractDescriptorPrefixWithoutWildcards(
+        String descriptorPattern, int numberOfWildcardsToRemove) {
+      String descriptorPrefixWithoutWildcards =
+          descriptorPattern.substring(0, descriptorPattern.length() - numberOfWildcardsToRemove);
+      if (descriptorPrefixWithoutWildcards.indexOf('*') >= 0) {
+        throw new IllegalArgumentException(
+            "Expected descriptor prefix without wildcards, got: "
+                + descriptorPrefixWithoutWildcards);
+      }
+      return descriptorPrefixWithoutWildcards;
+    }
   }
 }
diff --git a/src/main/java/com/android/tools/r8/partial/predicate/ClassNameMatcher.java b/src/main/java/com/android/tools/r8/partial/predicate/ClassNameMatcher.java
index 76f8603..8292d34 100644
--- a/src/main/java/com/android/tools/r8/partial/predicate/ClassNameMatcher.java
+++ b/src/main/java/com/android/tools/r8/partial/predicate/ClassNameMatcher.java
@@ -11,8 +11,7 @@
   private final String descriptor;
 
   public ClassNameMatcher(String descriptor) {
-    assert descriptor.charAt(0) == 'L';
-    assert descriptor.charAt(descriptor.length() - 1) == ';';
+    assert DescriptorUtils.isValidClassDescriptor(descriptor);
     this.descriptor = descriptor;
   }