[Git][java-team/proguard][upstream] 2 commits: New upstream version 6.0.2

Emmanuel Bourg gitlab at salsa.debian.org
Mon Dec 10 23:21:09 GMT 2018


Emmanuel Bourg pushed to branch upstream at Debian Java Maintainers / proguard


Commits:
dea12d6d by Emmanuel Bourg at 2018-12-10T23:15:23Z
New upstream version 6.0.2
- - - - -
89a9f2bf by Emmanuel Bourg at 2018-12-10T23:15:49Z
New upstream version 6.0.3
- - - - -


28 changed files:

- annotations/pom.xml
- ant/pom.xml
- buildscripts/pom.xml
- core/pom.xml
- core/src/proguard/ClassSpecificationVisitorFactory.java
- core/src/proguard/DataEntryReaderFactory.java
- core/src/proguard/DataEntryWriterFactory.java
- core/src/proguard/ProGuard.java
- core/src/proguard/backport/LambdaExpression.java
- core/src/proguard/backport/LambdaExpressionCollector.java
- core/src/proguard/classfile/ClassConstants.java
- core/src/proguard/classfile/JavaConstants.java
- core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
- core/src/proguard/classfile/constant/visitor/BootstrapMethodArgumentVisitor.java → core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java
- core/src/proguard/classfile/editor/AccessFixer.java
- core/src/proguard/classfile/util/ClassUtil.java
- + core/src/proguard/classfile/visitor/MultiConstantVisitor.java
- core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
- core/src/proguard/classfile/visitor/SimilarMemberVisitor.java
- core/src/proguard/io/JarWriter.java
- core/src/proguard/obfuscate/Obfuscator.java
- core/src/proguard/optimize/Optimizer.java
- core/src/proguard/preverify/CodePreverifier.java
- gradle/pom.xml
- gui/pom.xml
- gui/src/proguard/gui/GUIResources.properties
- retrace/pom.xml
- wtk/pom.xml


Changes:

=====================================
annotations/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-annotations</artifactId>


=====================================
ant/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-anttask</artifactId>


=====================================
buildscripts/pom.xml
=====================================
@@ -7,7 +7,7 @@
 
     <groupId>net.sf.proguard</groupId>
     <artifactId>proguard-parent</artifactId>
-    <version>6.0.1</version>
+    <version>6.0.3</version>
     <packaging>pom</packaging>
     <name>[${project.groupId}] ${project.artifactId}</name>
     <description>ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier.</description>


=====================================
core/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-base</artifactId>


=====================================
core/src/proguard/ClassSpecificationVisitorFactory.java
=====================================
@@ -545,7 +545,7 @@ public class ClassSpecificationVisitorFactory
         StringMatcher nameMatcher = name == null ? null :
             new ListParser(new NameParser(variableStringMatchers)).parse(name);
 
-        StringMatcher descriptorMatcher = name == null ? null :
+        StringMatcher descriptorMatcher = descriptor == null ? null :
             new ListParser(new ClassNameParser(variableStringMatchers)).parse(descriptor);
 
         StringMatcher attributesMatcher = attributeNames == null ? null :


=====================================
core/src/proguard/DataEntryReaderFactory.java
=====================================
@@ -95,31 +95,31 @@ public class DataEntryReaderFactory
         }
 
         // Unzip any apks, if necessary.
-        reader = wrapInJarReader(reader, false, isApk, apkFilter, ".apk");
+        reader = wrapInJarReader(reader, false, false, isApk, apkFilter, ".apk");
         if (!isApk)
         {
             // Unzip any jars, if necessary.
-            reader = wrapInJarReader(reader, false, isJar, jarFilter, ".jar");
+            reader = wrapInJarReader(reader, false, false, isJar, jarFilter, ".jar");
             if (!isJar)
             {
                 // Unzip any aars, if necessary.
-                reader = wrapInJarReader(reader, false, isAar, aarFilter, ".aar");
+                reader = wrapInJarReader(reader, false, false, isAar, aarFilter, ".aar");
                 if (!isAar)
                 {
                     // Unzip any wars, if necessary.
-                    reader = wrapInJarReader(reader, false, isWar, warFilter, ".war");
+                    reader = wrapInJarReader(reader, true, false, isWar, warFilter, ".war");
                     if (!isWar)
                     {
                         // Unzip any ears, if necessary.
-                        reader = wrapInJarReader(reader, false, isEar, earFilter, ".ear");
+                        reader = wrapInJarReader(reader, false, false, isEar, earFilter, ".ear");
                         if (!isEar)
                         {
                             // Unzip any jmods, if necessary.
-                            reader = wrapInJarReader(reader, true, isJmod, jmodFilter, ".jmod");
+                            reader = wrapInJarReader(reader, true, true, isJmod, jmodFilter, ".jmod");
                             if (!isJmod)
                             {
                                 // Unzip any zips, if necessary.
-                                reader = wrapInJarReader(reader, false, isZip, zipFilter, ".zip");
+                                reader = wrapInJarReader(reader, false, false, isZip, zipFilter, ".zip");
                             }
                         }
                     }
@@ -132,12 +132,14 @@ public class DataEntryReaderFactory
 
 
     /**
-     * Wraps the given DataEntryReader in a JarReader, filtering it if necessary.
+     * Wraps the given DataEntryReader in a JarReader, filtering it if
+     * necessary.
      * @param reader             the data entry reader that can read the
      *                           entries contained in the jar file.
-     * @param isJmod             specifies whether to strip the "classes/"
-     *                           prefix from contained .class data entries
-     *                           and the jmod magic bytes from the zip.
+     * @param stripClassesPrefix specifies whether to strip the ""classes/"
+     *                           prefix from contained .class data entries.
+     *@param stripJmodHeader     specifies whether to strip the jmod magic
+     *                           bytes from the zip.
      * @param isJar              specifies whether the data entries should
      *                           always be unzipped.
      * @param jarFilter          otherwise, an optional filter on the data
@@ -148,21 +150,22 @@ public class DataEntryReaderFactory
      *         entries.
      */
     private static DataEntryReader wrapInJarReader(DataEntryReader reader,
-                                                   boolean         isJmod,
+                                                   boolean         stripClassesPrefix,
+                                                   boolean         stripJmodHeader,
                                                    boolean         isJar,
                                                    List            jarFilter,
                                                    String          jarExtension)
     {
-        if (isJmod)
+        if (stripClassesPrefix)
         {
             reader = new FilteredDataEntryReader(
-                new DataEntryNameFilter(new ExtensionMatcher(".class")),
-                new PrefixStrippingDataEntryReader("classes/", reader),
+                new DataEntryNameFilter(new ExtensionMatcher(ClassConstants.CLASS_FILE_EXTENSION)),
+                new PrefixStrippingDataEntryReader(ClassConstants.JMOD_CLASS_FILE_PREFIX, reader),
                 reader);
         }
 
         // Unzip any jars, if necessary.
-        DataEntryReader jarReader = new JarReader(reader, isJmod);
+        DataEntryReader jarReader = new JarReader(reader, stripJmodHeader);
 
         if (isJar)
         {


=====================================
core/src/proguard/DataEntryWriterFactory.java
=====================================
@@ -129,19 +129,30 @@ public class DataEntryWriterFactory
                                                      isJmod ||
                                                      isZip);
 
+        // If the output is an archive, we'll flatten (unpack the contents of)
+        // higher level input archives, e.g. when writing into a jar file, we
+        // flatten zip files.
+        boolean flattenApks  = false;
+        boolean flattenJars  = flattenApks  || isApk;
+        boolean flattenAars  = flattenJars  || isJar;
+        boolean flattenWars  = flattenAars  || isAar;
+        boolean flattenEars  = flattenWars  || isWar;
+        boolean flattenJmods = flattenEars  || isEar;
+        boolean flattenZips  = flattenJmods || isJmod;
+
         // Set up the filtered jar writers.
-        writer = wrapInJarWriter(writer, false, null,                       isZip,  zipFilter,  ".zip",  isApk || isJar || isAar || isWar || isEar || isJmod);
-        writer = wrapInJarWriter(writer, true,  ClassConstants.JMOD_HEADER, isJmod, jmodFilter, ".jmod", isApk || isJar || isAar || isWar || isEar);
-        writer = wrapInJarWriter(writer, false, null,                       isEar,  earFilter,  ".ear",  isApk || isJar || isAar || isWar);
-        writer = wrapInJarWriter(writer, true,  null,                       isWar,  warFilter,  ".war",  isApk || isJar || isAar);
-        writer = wrapInJarWriter(writer, false, null,                       isAar,  aarFilter,  ".aar",  isApk || isJar);
-        writer = wrapInJarWriter(writer, false, null,                       isJar,  jarFilter,  ".jar",  isApk);
-        writer = wrapInJarWriter(writer, false, null,                       isApk,  apkFilter,  ".apk",  false);
+        writer = wrapInJarWriter(writer, flattenZips,  isZip,  ".zip",  zipFilter,  null,                       null);
+        writer = wrapInJarWriter(writer, flattenJmods, isJmod, ".jmod", jmodFilter, ClassConstants.JMOD_HEADER, ClassConstants.JMOD_CLASS_FILE_PREFIX);
+        writer = wrapInJarWriter(writer, flattenEars,  isEar,  ".ear",  earFilter,  null,                       null);
+        writer = wrapInJarWriter(writer, flattenWars,  isWar,  ".war",  warFilter,  null,                       ClassConstants.WAR_CLASS_FILE_PREFIX);
+        writer = wrapInJarWriter(writer, flattenAars,  isAar,  ".aar",  aarFilter,  null,                       null);
+        writer = wrapInJarWriter(writer, flattenJars,  isJar,  ".jar",  jarFilter,  null,                       null);
+        writer = wrapInJarWriter(writer, flattenApks,  isApk,  ".apk",  apkFilter,  null,                       null);
 
         // Set up for writing out the program classes.
         writer = new ClassDataEntryWriter(programClassPool, writer);
 
-        // Add a filter, if specified.
+        // Add a data entry filter, if specified.
         writer = filter != null ?
             new FilteredDataEntryWriter(
                 new DataEntryNameFilter(
@@ -166,46 +177,61 @@ public class DataEntryWriterFactory
      * Wraps the given DataEntryWriter in a JarWriter, filtering if necessary.
      */
     private DataEntryWriter wrapInJarWriter(DataEntryWriter writer,
-                                            boolean         addClassesPrefix,
-                                            byte[]          header,
-                                            boolean         isJar,
+                                            boolean         flatten,
+                                            boolean         isOutputJar,
+                                            String          jarFilterExtension,
                                             List            jarFilter,
-                                            String          jarExtension,
-                                            boolean         dontWrap)
+                                            byte[]          jarHeader,
+                                            String          classFilePrefix)
     {
-        // Zip up jars, if necessary.
-        DataEntryWriter jarWriter =
-            dontWrap ?
-                new ParentDataEntryWriter(writer) :
-                new JarWriter(header, writer);
-
-        // Add a "classes/" prefix for class files, if specified.
-        if (addClassesPrefix)
+        // Flatten jars or zip them up.
+        DataEntryWriter jarWriter;
+        if (flatten)
         {
-            writer = new FilteredDataEntryWriter(
-                new DataEntryNameFilter(
-                new ExtensionMatcher(".class")),
-                new PrefixAddingDataEntryWriter("classes/",
-                                                writer),
-                writer);
+            // Unpack the jar.
+            jarWriter = new ParentDataEntryWriter(writer);
+        }
+        else
+        {
+            // Pack the jar.
+            jarWriter = new JarWriter(jarHeader, writer);
+
+            // Add a prefix for class files inside the jar, if specified.
+            if (classFilePrefix != null)
+            {
+                jarWriter =
+                    new FilteredDataEntryWriter(
+                    new DataEntryNameFilter(
+                    new ExtensionMatcher(ClassConstants.CLASS_FILE_EXTENSION)),
+                    new PrefixAddingDataEntryWriter(classFilePrefix,
+                                                    jarWriter),
+                    jarWriter);
+            }
         }
 
-        // Add a filter, if specified.
-        DataEntryWriter filteredJarWriter = jarFilter != null ?
+        // Either zip up the jar or delegate to the original writer.
+        return
             new FilteredDataEntryWriter(
             new DataEntryParentFilter(
             new DataEntryNameFilter(
-            new ListParser(new FileNameParser()).parse(jarFilter))),
-            jarWriter) :
-
-            jarWriter;
-
-        // Only zip up jars, unless the output is a jar file itself.
-        return new FilteredDataEntryWriter(
-               new DataEntryParentFilter(
-               new DataEntryNameFilter(
-               new ExtensionMatcher(jarExtension))),
-                   filteredJarWriter,
-                   isJar ? jarWriter : writer);
+            new ExtensionMatcher(jarFilterExtension))),
+
+                // The parent of the data entry is a jar.
+                // Write the data entry to the jar.
+                // Apply the jar filter, if specified, to the parent.
+                jarFilter != null ?
+                    new FilteredDataEntryWriter(
+                    new DataEntryParentFilter(
+                    new DataEntryNameFilter(
+                    new ListParser(new FileNameParser()).parse(jarFilter))),
+                    jarWriter) :
+                    jarWriter,
+
+                // The parent of the data entry is not a jar.
+                // Write the entry to a jar anyway if the output is a jar.
+                // Otherwise just delegate to the original writer.
+                isOutputJar ?
+                    jarWriter :
+                    writer);
     }
 }


=====================================
core/src/proguard/ProGuard.java
=====================================
@@ -43,7 +43,7 @@ import java.io.*;
  */
 public class ProGuard
 {
-    public static final String VERSION = "ProGuard, version 6.0.1";
+    public static final String VERSION = "ProGuard, version 6.0.3";
 
     private final Configuration configuration;
     private       ClassPool     programClassPool = new ClassPool();


=====================================
core/src/proguard/backport/LambdaExpression.java
=====================================
@@ -3,6 +3,20 @@
  *             of Java bytecode.
  *
  * Copyright (c) 2002-2018 GuardSquare NV
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 package proguard.backport;
 


=====================================
core/src/proguard/backport/LambdaExpressionCollector.java
=====================================
@@ -185,7 +185,8 @@ implements ClassVisitor,
                     for (int i = 0; i < bridgeMethodCount; i++)
                     {
                         MethodTypeConstant methodTypeConstant =
-                            (MethodTypeConstant) programClass.getConstant(argumentIndex++);
+                            getMethodTypeConstant(programClass,
+                                                  bootstrapMethodInfo.u2methodArguments[argumentIndex++]);
 
                         lambdaExpression.bridgeMethodDescriptors =
                             ArrayUtil.add(lambdaExpression.bridgeMethodDescriptors,


=====================================
core/src/proguard/classfile/ClassConstants.java
=====================================
@@ -27,9 +27,12 @@ package proguard.classfile;
  */
 public class ClassConstants
 {
-    public static final byte[] JMOD_HEADER = new byte[] { 'J', 'M', 1, 0 };
+    public static final String WAR_CLASS_FILE_PREFIX  = "classes/";
 
-    public static final String CLASS_FILE_EXTENSION = ".class";
+    public static final byte[] JMOD_HEADER            = new byte[] { 'J', 'M', 1, 0 };
+    public static final String JMOD_CLASS_FILE_PREFIX = "classes/";
+
+    public static final String CLASS_FILE_EXTENSION   = ".class";
 
     public static final int MAGIC = 0xCAFEBABE;
 
@@ -51,6 +54,8 @@ public class ClassConstants
     public static final int CLASS_VERSION_1_8_MINOR = 0;
     public static final int CLASS_VERSION_1_9_MAJOR = 53;
     public static final int CLASS_VERSION_1_9_MINOR = 0;
+    public static final int CLASS_VERSION_10_MAJOR  = 54;
+    public static final int CLASS_VERSION_10_MINOR  = 0;
 
     public static final int CLASS_VERSION_1_0 = (CLASS_VERSION_1_0_MAJOR << 16) | CLASS_VERSION_1_0_MINOR;
     public static final int CLASS_VERSION_1_2 = (CLASS_VERSION_1_2_MAJOR << 16) | CLASS_VERSION_1_2_MINOR;
@@ -61,6 +66,7 @@ public class ClassConstants
     public static final int CLASS_VERSION_1_7 = (CLASS_VERSION_1_7_MAJOR << 16) | CLASS_VERSION_1_7_MINOR;
     public static final int CLASS_VERSION_1_8 = (CLASS_VERSION_1_8_MAJOR << 16) | CLASS_VERSION_1_8_MINOR;
     public static final int CLASS_VERSION_1_9 = (CLASS_VERSION_1_9_MAJOR << 16) | CLASS_VERSION_1_9_MINOR;
+    public static final int CLASS_VERSION_10  = (CLASS_VERSION_10_MAJOR  << 16) | CLASS_VERSION_10_MINOR;
 
     public static final int ACC_PUBLIC       = 0x0001;
     public static final int ACC_PRIVATE      = 0x0002;


=====================================
core/src/proguard/classfile/JavaConstants.java
=====================================
@@ -44,6 +44,7 @@ public interface JavaConstants
     public static final String CLASS_VERSION_1_7_ALIAS = "7";
     public static final String CLASS_VERSION_1_8_ALIAS = "8";
     public static final String CLASS_VERSION_1_9_ALIAS = "9";
+    public static final String CLASS_VERSION_10        = "10";
 
     public static final String ACC_PUBLIC       = "public";
     public static final String ACC_PRIVATE      = "private";
@@ -92,4 +93,4 @@ public interface JavaConstants
     public static final String TYPE_LONG    = "long";
     public static final String TYPE_DOUBLE  = "double";
     public static final String TYPE_ARRAY   = "[]";
-}
\ No newline at end of file
+}


=====================================
core/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
=====================================
@@ -23,7 +23,6 @@ package proguard.classfile.attribute.visitor;
 import proguard.classfile.Clazz;
 import proguard.classfile.attribute.BootstrapMethodInfo;
 
-
 /**
  * This interface specifies the methods for a visitor of
  * <code>BootstrapMethodInfo</code> objects. Note that there is only a single


=====================================
core/src/proguard/classfile/constant/visitor/BootstrapMethodArgumentVisitor.java → core/src/proguard/classfile/constant/visitor/AllBootstrapMethodArgumentVisitor.java
=====================================
@@ -28,19 +28,18 @@ import proguard.classfile.attribute.visitor.BootstrapMethodInfoVisitor;
  * This BootstrapMethodInfoVisitor lets a given ConstantVisitor visit all
  * constant pool entries of the bootstrap methods it visits.
  *
- *
  * @author Eric Lafortune
  */
-public class BootstrapMethodArgumentVisitor
+public class AllBootstrapMethodArgumentVisitor
 implements   BootstrapMethodInfoVisitor
 {
     private ConstantVisitor constantVisitor;
 
     /**
-     * Creates a new BootstrapMethodArgumentVisitor that will delegate to the
-     * given constant visitor.
+     * Creates a new AllBootstrapMethodArgumentVisitor that will delegate to
+     * the given constant visitor.
      */
-    public BootstrapMethodArgumentVisitor(ConstantVisitor constantVisitor)
+    public AllBootstrapMethodArgumentVisitor(ConstantVisitor constantVisitor)
     {
         this.constantVisitor = constantVisitor;
     }
@@ -50,7 +49,6 @@ implements   BootstrapMethodInfoVisitor
 
     public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
     {
-        // Check bootstrap method.
         bootstrapMethodInfo.methodArgumentsAccept(clazz, constantVisitor);
     }
 }


=====================================
core/src/proguard/classfile/editor/AccessFixer.java
=====================================
@@ -21,8 +21,13 @@
 package proguard.classfile.editor;
 
 import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.visitor.AllElementValueVisitor;
+import proguard.classfile.attribute.visitor.*;
 import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.*;
 import proguard.classfile.util.*;
 import proguard.classfile.visitor.*;
 
@@ -33,164 +38,155 @@ import proguard.classfile.visitor.*;
  * @author Eric Lafortune
  */
 public class AccessFixer
-extends      ReferencedClassVisitor
 implements   ClassVisitor
 {
-    private final ConstantVisitor referencedClassStorer = new MyReferencedClassStorer();
+    private final ClassVisitor referencedClassFixer  =
+        new ReferencedClassVisitor(
+        new MyReferencedClassAccessFixer());
 
+    private final ClassVisitor referencedMemberFixer =
+        new AllMethodVisitor(
+        new AllAttributeVisitor(
+        new AllInstructionVisitor(
+        new MyReferencedMemberVisitor(
+        new MyReferencedMemberAccessFixer()))));
 
-    /**
-     * Creates a new AccessFixer.
-     */
-    public AccessFixer()
-    {
-        // Unfortunately, the inner class must be static to be passed to the
-        // super constructor. We therefore can't let it refer to this class;
-        // we'll let this class refer to the inner class instead.
-        super(new MyAccessFixer());
-    }
+    private final ClassVisitor referencedAnnotationMethodFixer =
+        new AllAttributeVisitor(true,
+        new AllElementValueVisitor(
+        new MyReferencedMemberVisitor(
+        new MyReferencedMemberAccessFixer())));
 
+    private final ClassVisitor methodHierarchyFixer =
+        new AllMethodVisitor(
+        new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+                                  ClassConstants.ACC_STATIC,
+        new InitializerMethodFilter(null,
+        new SimilarMemberVisitor(false, true, false, true,
+        new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
+                                  ClassConstants.ACC_STATIC,
+        new MyReferencedMemberAccessFixer())))));
 
-    // Overridden methods for ClassVisitor.
+    
+    // Fields acting as parameters for the visitors.
 
-    public void visitProgramClass(ProgramClass programClass)
-    {
-        // Remember the referencing class.
-        ((MyAccessFixer)classVisitor).referencingClass = programClass;
+    private Clazz referencingClass;
+    private int   referencingMethodAccessFlags;
+    private Clazz referencedClass;
 
-        // Start visiting and fixing the referenced classes and class members.
-        super.visitProgramClass(programClass);
-    }
+
+    // Implementations for ClassVisitor.
+
+    public void visitLibraryClass(LibraryClass libraryClass) {}
 
 
-    public void visitLibraryClass(LibraryClass libraryClass)
+    public void visitProgramClass(ProgramClass programClass)
     {
         // Remember the referencing class.
-        ((MyAccessFixer)classVisitor).referencingClass = libraryClass;
+        referencingClass = programClass;
 
-        // Start visiting and fixing the referenced classes and class members.
-        super.visitLibraryClass(libraryClass);
-    }
+        // Fix the referenced classes.
+        referencedClassFixer.visitProgramClass(programClass);
 
+        // Fix the referenced class members.
+        referencedMemberFixer.visitProgramClass(programClass);
 
-    // Overridden methods for MemberVisitor.
+        // Fix the referenced annotation methods.
+        referencedAnnotationMethodFixer.visitProgramClass(programClass);
 
-    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
-    {
-        // Fix the referenced classes and class members.
-        super.visitProgramMember(programClass, programMethod);
-
-        // Fix overridden or implemented methods higher up the hierarchy.
-        // We can ignore private and static methods and initializers.
-        if ((programMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
-                                               ClassConstants.ACC_STATIC)) == 0 &&
-            !ClassUtil.isInitializer(programMethod.getName(programClass)))
-        {
-            programClass.hierarchyAccept(false, true, false, false,
-                new NamedMethodVisitor(programMethod.getName(programClass),
-                                       programMethod.getDescriptor(programClass),
-                new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
-                                          ClassConstants.ACC_STATIC,
-                                       (MemberVisitor)classVisitor)));
-        }
+        // Fix overridden and overriding methods up and down the hierarchy.
+        // They are referenced implicitly and need to be accessible too.
+        referencingMethodAccessFlags = 0;
+        referencedClass              = null;
+
+        methodHierarchyFixer.visitProgramClass(programClass);
     }
 
 
-    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+    /**
+     * This ReferencedMemberVisitor is an InstructionVisitor that also
+     * remembers the access flags of the referencing methods, and the
+     * referenced class.
+     */
+    private class MyReferencedMemberVisitor
+    extends       ReferencedMemberVisitor
+    implements    InstructionVisitor
     {
-        // Fix the referenced classes and class members.
-        super.visitLibraryMember(libraryClass, libraryMethod);
-
-        // Fix overridden or implemented methods higher up the hierarchy.
-        // We can ignore private and static methods and initializers.
-        if ((libraryMethod.getAccessFlags() & (ClassConstants.ACC_PRIVATE |
-                                               ClassConstants.ACC_STATIC)) == 0 &&
-            !ClassUtil.isInitializer(libraryMethod.getName(libraryClass)))
+        public MyReferencedMemberVisitor(MemberVisitor memberVisitor)
         {
-            libraryClass.hierarchyAccept(false, true, false, false,
-                new NamedMethodVisitor(libraryMethod.getName(libraryClass),
-                                       libraryMethod.getDescriptor(libraryClass),
-                new MemberAccessFilter(0, ClassConstants.ACC_PRIVATE |
-                                          ClassConstants.ACC_STATIC,
-                                       (MemberVisitor)classVisitor)));
+            super(memberVisitor);
         }
-    }
 
 
-    // Overridden methods for ConstantVisitor.
+        // Implementations for InstructionVisitor.
 
-    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
-    {
-        // Fix the access flags of the referenced class, if any.
-        super.visitStringConstant(clazz, stringConstant);
-
-        // Fix the access flags of the referenced class member, if any.
-        stringConstant.referencedMemberAccept((MemberVisitor)classVisitor);
-    }
+        public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
 
 
-    public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
-    {
-        // Remember the referenced class. Note that we're interested in the
-        // class of the invocation, not in the class in which the member was
-        // actually found, unless it is an array type.
-        if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz)))
+        public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
         {
-            // For an array type, the class will be java.lang.Object.
-            ((MyAccessFixer)classVisitor).referencedClass =
-                refConstant.referencedClass;
-        }
-        else
-        {
-            // Remember the referenced class.
-            clazz.constantPoolEntryAccept(refConstant.u2classIndex,
-                                          referencedClassStorer);
+            // Remember the access flags.
+            referencingMethodAccessFlags = method.getAccessFlags();
+
+            // Fix the referenced classes and class members.
+            clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
         }
 
-        // Fix the access flags of the class of the referenced class member.
-        super.visitAnyRefConstant(clazz, refConstant);
 
-        // Fix the access flags of the referenced class member.
-        refConstant.referencedMemberAccept((MemberVisitor)classVisitor);
-    }
+        // Overridden methods for ConstantVisitor.
 
+        public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+        {
+            // Remember the referenced class. Note that we're interested in the
+            // class of the invocation, not in the class in which the member was
+            // actually found, unless it is an array type.
+            if (ClassUtil.isInternalArrayType(refConstant.getClassName(clazz)))
+            {
+                // For an array type, the class will be java.lang.Object.
+                referencedClass = refConstant.referencedClass;
+            }
+            else
+            {
+                // Remember the referenced class.
+                clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+            }
+
+            // Fix the access flags of referenced class member.
+            super.visitAnyRefConstant(clazz, refConstant);
+        }
 
-    /**
-     * This ConstantVisitor stores the classes referenced by the class
-     * constants that it visits.
-     */
-    private class MyReferencedClassStorer
-    extends       SimplifiedVisitor
-    implements    ConstantVisitor
-    {
-        // Implementations for ConstantVisitor.
 
         public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
         {
             // Remember the referenced class.
-            ((MyAccessFixer)classVisitor).referencedClass =
-                classConstant.referencedClass;
+            referencedClass = classConstant.referencedClass;
+        }
+
+
+        // Implementations for ElementValueVisitor.
+
+        public void visitAnyElementValue(Clazz clazz, Annotation annotation, ElementValue elementValue)
+        {
+            // Set the referencing access flags and set the referenced class.
+            referencingMethodAccessFlags = ClassConstants.ACC_STATIC;
+            referencedClass              = elementValue.referencedClass;
+
+            // Fix the access flags of referenced annotation method.
+            super.visitAnyElementValue(clazz, annotation, elementValue);
         }
     }
 
 
     /**
-     * This ClassVisitor and MemberVisitor fixes the access flags of the
-     * classes and class members that it visits, relative to the referencing
-     * class.
-     *
-     * This class must be static so it can be passed to the super constructor
-     * of the outer class.
+     * This ClassVisitor fixes the access flags of the classes that it visits,
+     * relative to the referencing class.
      */
-    private static class MyAccessFixer
-    extends              SimplifiedVisitor
-    implements           ClassVisitor,
-                         MemberVisitor
+    private class MyReferencedClassAccessFixer
+    extends       SimplifiedVisitor
+    implements    ClassVisitor,
+                  AttributeVisitor,
+                  InnerClassesInfoVisitor
     {
-        private Clazz referencingClass;
-        private Clazz referencedClass;
-
-
         // Implementations for ClassVisitor.
 
         public void visitLibraryClass(LibraryClass libraryClass) {}
@@ -198,25 +194,86 @@ implements   ClassVisitor
 
         public void visitProgramClass(ProgramClass programClass)
         {
+            // Do we need to update the access flags?
             int currentAccessFlags = programClass.getAccessFlags();
             int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+            if (currentAccessLevel < AccessUtil.PUBLIC)
+            {
+                // Compute the required access level.
+                int requiredAccessLevel =
+                    inSamePackage(programClass, referencingClass) ?
+                        AccessUtil.PACKAGE_VISIBLE :
+                        AccessUtil.PUBLIC;
+
+                // Fix the class access flags if necessary.
+                if (currentAccessLevel < requiredAccessLevel)
+                {
+                    programClass.u2accessFlags =
+                        AccessUtil.replaceAccessFlags(currentAccessFlags,
+                                                      AccessUtil.accessFlags(requiredAccessLevel));
+                }
+            }
+
+            // Also check the InnerClasses attribute, if any.
+            programClass.attributesAccept(this);
+        }
+
+
+        // Implementations for AttributeVisitor.
+
+        public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
 
-            // Compute the required access level.
-            int requiredAccessLevel =
-                inSamePackage(programClass, referencingClass) ?
-                    AccessUtil.PACKAGE_VISIBLE :
-                    AccessUtil.PUBLIC;
 
-            // Fix the class access flags if necessary.
-            if (currentAccessLevel < requiredAccessLevel)
+        public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+        {
+            innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+        }
+
+
+        // Implementations for InnerClassesInfoVisitor.
+
+        public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+        {
+            // Is this an inner class?
+            int innerClassIndex = innerClassesInfo.u2innerClassIndex;
+            if (innerClassIndex != 0)
             {
-                programClass.u2accessFlags =
-                    AccessUtil.replaceAccessFlags(currentAccessFlags,
-                                                  AccessUtil.accessFlags(requiredAccessLevel));
+                String innerClassName = clazz.getClassName(innerClassIndex);
+                if (innerClassName.equals(clazz.getName()))
+                {
+                    // Do we need to update the access flags?
+                    int currentAccessFlags = innerClassesInfo.u2innerClassAccessFlags;
+                    int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+                    if (currentAccessLevel < AccessUtil.PUBLIC)
+                    {
+                        // Compute the required access level.
+                        int requiredAccessLevel =
+                            inSamePackage(clazz, referencingClass) ?
+                                AccessUtil.PACKAGE_VISIBLE :
+                                AccessUtil.PUBLIC;
+
+                        // Fix the inner class access flags if necessary.
+                        if (currentAccessLevel < requiredAccessLevel)
+                        {
+                            innerClassesInfo.u2innerClassAccessFlags =
+                                AccessUtil.replaceAccessFlags(currentAccessFlags,
+                                                              AccessUtil.accessFlags(requiredAccessLevel));
+                        }
+                    }
+                }
             }
         }
+    }
 
 
+    /**
+     * This MemberVisitor fixes the access flags of the class members that it
+     * visits, relative to the referencing class and method.
+     */
+    private class MyReferencedMemberAccessFixer
+    extends       SimplifiedVisitor
+    implements    MemberVisitor
+    {
         // Implementations for MemberVisitor.
 
         public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember) {}
@@ -224,39 +281,44 @@ implements   ClassVisitor
 
         public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
         {
+            // Do we need to update the access flags?
             int currentAccessFlags = programMember.getAccessFlags();
             int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
-
-            // Compute the required access level.
-            // For protected access, we're taking into account the class in the
-            // invocation and the class that actually contains the member.
-            int requiredAccessLevel =
-                programClass.equals(referencingClass)         ? AccessUtil.PRIVATE         :
-                inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
-                referencedClass != null                    &&
-                referencingClass.extends_(referencedClass) &&
-                referencingClass.extends_(programClass)       ? AccessUtil.PROTECTED       :
-                                                                AccessUtil.PUBLIC;
-
-            // Fix the class member access flags if necessary.
-            if (currentAccessLevel < requiredAccessLevel)
+            if (currentAccessLevel < AccessUtil.PUBLIC)
             {
-                programMember.u2accessFlags =
-                    AccessUtil.replaceAccessFlags(currentAccessFlags,
-                                                  AccessUtil.accessFlags(requiredAccessLevel));
+                // Compute the required access level.
+                // For protected access, the referencing method may not be
+                // static. We're also taking into account the class in the
+                // invocation and the class that actually contains the member.
+                int requiredAccessLevel =
+                    programClass.equals(referencingClass)         ? AccessUtil.PRIVATE         :
+                    inSamePackage(programClass, referencingClass) ? AccessUtil.PACKAGE_VISIBLE :
+                    (referencingMethodAccessFlags & ClassConstants.ACC_STATIC) == 0 &&
+                    (referencedClass == null ||
+                     referencingClass.extends_(referencedClass))                    &&
+                    referencingClass.extends_(programClass)       ? AccessUtil.PROTECTED       :
+                                                                    AccessUtil.PUBLIC;
+
+                // Fix the class member access flags if necessary.
+                if (currentAccessLevel < requiredAccessLevel)
+                {
+                    programMember.u2accessFlags =
+                        AccessUtil.replaceAccessFlags(currentAccessFlags,
+                                                      AccessUtil.accessFlags(requiredAccessLevel));
+                }
             }
         }
+    }
 
 
-        // Small utility methods.
+    // Small utility methods.
 
-        /**
-         * Returns whether the two given classes are in the same package.
-         */
-        private boolean inSamePackage(Clazz class1, Clazz class2)
-        {
-            return ClassUtil.internalPackageName(class1.getName()).equals(
-                   ClassUtil.internalPackageName(class2.getName()));
-        }
+    /**
+     * Returns whether the two given classes are in the same package.
+     */
+    private boolean inSamePackage(Clazz class1, Clazz class2)
+    {
+        return ClassUtil.internalPackageName(class1.getName()).equals(
+               ClassUtil.internalPackageName(class2.getName()));
     }
 }


=====================================
core/src/proguard/classfile/util/ClassUtil.java
=====================================
@@ -106,6 +106,7 @@ public class ClassUtil
             externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_8) ? ClassConstants.CLASS_VERSION_1_8 :
             externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_9_ALIAS) ||
             externalClassVersion.equals(JavaConstants.CLASS_VERSION_1_9) ? ClassConstants.CLASS_VERSION_1_9 :
+            externalClassVersion.equals(JavaConstants.CLASS_VERSION_10)  ? ClassConstants.CLASS_VERSION_10  :
                                                                            0;
     }
 
@@ -128,6 +129,7 @@ public class ClassUtil
             case ClassConstants.CLASS_VERSION_1_7: return JavaConstants.CLASS_VERSION_1_7;
             case ClassConstants.CLASS_VERSION_1_8: return JavaConstants.CLASS_VERSION_1_8;
             case ClassConstants.CLASS_VERSION_1_9: return JavaConstants.CLASS_VERSION_1_9;
+            case ClassConstants.CLASS_VERSION_10:  return JavaConstants.CLASS_VERSION_10;
             default:                               return null;
         }
     }
@@ -141,14 +143,14 @@ public class ClassUtil
     public static void checkVersionNumbers(int internalClassVersion) throws UnsupportedOperationException
     {
         if (internalClassVersion < ClassConstants.CLASS_VERSION_1_0 ||
-            internalClassVersion > ClassConstants.CLASS_VERSION_1_9)
+            internalClassVersion > ClassConstants.CLASS_VERSION_10)
         {
             throw new UnsupportedOperationException("Unsupported version number ["+
                                                     internalMajorClassVersion(internalClassVersion)+"."+
                                                     internalMinorClassVersion(internalClassVersion)+"] (maximum "+
-                                                    ClassConstants.CLASS_VERSION_1_9_MAJOR+"."+
-                                                    ClassConstants.CLASS_VERSION_1_9_MINOR+", Java "+
-                                                    JavaConstants.CLASS_VERSION_1_9+")");
+                                                    ClassConstants.CLASS_VERSION_10_MAJOR+"."+
+                                                    ClassConstants.CLASS_VERSION_10_MINOR+", Java "+
+                                                    JavaConstants.CLASS_VERSION_10+")");
         }
     }
 


=====================================
core/src/proguard/classfile/visitor/MultiConstantVisitor.java
=====================================
@@ -0,0 +1,74 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ *             of Java bytecode.
+ *
+ * Copyright (c) 2002-2018 GuardSquare NV
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.util.ArrayUtil;
+
+
+/**
+ * This ConstantVisitor delegates all visits to each ConstantVisitor in a given list.
+ *
+ * @author Johan Leys
+ */
+public class MultiConstantVisitor
+extends      SimplifiedVisitor
+implements   ConstantVisitor
+{
+    private ConstantVisitor[] constantVisitors;
+    private int               constantVisitorCount;
+
+
+    public MultiConstantVisitor()
+    {
+        this.constantVisitors = new ConstantVisitor[16];
+    }
+
+
+    public MultiConstantVisitor(ConstantVisitor... constantVisitors)
+    {
+        this.constantVisitors     = constantVisitors;
+        this.constantVisitorCount = this.constantVisitors.length;
+    }
+
+
+    public void addClassVisitor(ConstantVisitor constantVisitor)
+    {
+        constantVisitors =
+            ArrayUtil.add(constantVisitors,
+                          constantVisitorCount++,
+                          constantVisitor);
+    }
+
+
+    // Implementations for ConstantVisitor.
+
+    public void visitAnyConstant(Clazz clazz, Constant constant)
+    {
+        for (int index = 0; index < constantVisitorCount; index++)
+        {
+            constant.accept(clazz, constantVisitors[index]);
+        }
+    }
+}


=====================================
core/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
=====================================
@@ -38,7 +38,7 @@ extends      SimplifiedVisitor
 implements   ConstantVisitor,
              ElementValueVisitor
 {
-    private final MemberVisitor memberVisitor;
+    protected final MemberVisitor memberVisitor;
 
 
     public ReferencedMemberVisitor(MemberVisitor memberVisitor)


=====================================
core/src/proguard/classfile/visitor/SimilarMemberVisitor.java
=====================================
@@ -25,7 +25,7 @@ import proguard.classfile.*;
 /**
  * This <code>MemberVisitor</code> lets a given <code>MemberVisitor</code>
  * visit all members that have the same name and type as the visited methods
- * in the class hierarchy of a given target class.
+ * in the class hierarchy of the members' classes or of a given target class.
  *
  * @author Eric Lafortune
  */
@@ -40,6 +40,37 @@ implements   MemberVisitor
     private final MemberVisitor memberVisitor;
 
 
+    /**
+     * Creates a new SimilarMemberVisitor.
+     * @param visitThisMember        specifies whether to visit the class
+     *                               members in the members' classes themselves.
+     * @param visitSuperMembers      specifies whether to visit the class
+     *                               members in the super classes of the
+     *                               members' classes.
+     * @param visitInterfaceMembers  specifies whether to visit the class
+     *                               members in the interface classes of the
+     *                               members' classes.
+     * @param visitOverridingMembers specifies whether to visit the class
+     *                               members in the subclasses of the members'
+     *                               classes.
+     * @param memberVisitor          the <code>MemberVisitor</code> to which
+     *                               visits will be delegated.
+     */
+    public SimilarMemberVisitor(boolean       visitThisMember,
+                                boolean       visitSuperMembers,
+                                boolean       visitInterfaceMembers,
+                                boolean       visitOverridingMembers,
+                                MemberVisitor memberVisitor)
+    {
+        this(null,
+             visitThisMember,
+             visitSuperMembers,
+             visitInterfaceMembers,
+             visitOverridingMembers,
+             memberVisitor);
+    }
+
+
     /**
      * Creates a new SimilarMemberVisitor.
      * @param targetClass            the class in whose hierarchy to look for
@@ -78,6 +109,8 @@ implements   MemberVisitor
 
     public void visitProgramField(ProgramClass programClass, ProgramField programField)
     {
+        Clazz targetClass = targetClass(programClass);
+
         targetClass.hierarchyAccept(visitThisMember,
                                     visitSuperMembers,
                                     visitInterfaceMembers,
@@ -90,6 +123,8 @@ implements   MemberVisitor
 
     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
     {
+        Clazz targetClass = targetClass(libraryClass);
+
         targetClass.hierarchyAccept(visitThisMember,
                                     visitSuperMembers,
                                     visitInterfaceMembers,
@@ -102,6 +137,8 @@ implements   MemberVisitor
 
     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
     {
+        Clazz targetClass = targetClass(programClass);
+
         targetClass.hierarchyAccept(visitThisMember,
                                     visitSuperMembers,
                                     visitInterfaceMembers,
@@ -114,6 +151,8 @@ implements   MemberVisitor
 
     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
     {
+        Clazz targetClass = targetClass(libraryClass);
+
         targetClass.hierarchyAccept(visitThisMember,
                                     visitSuperMembers,
                                     visitInterfaceMembers,
@@ -122,4 +161,14 @@ implements   MemberVisitor
                                                            libraryMethod.getDescriptor(libraryClass),
                                                            memberVisitor));
     }
+
+
+    /**
+     * Returns the target class, or the given class if the target class is
+     * null.
+     */
+    private Clazz targetClass(Clazz clazz)
+    {
+        return targetClass != null ? targetClass : clazz;
+    }
 }
\ No newline at end of file


=====================================
core/src/proguard/io/JarWriter.java
=====================================
@@ -26,7 +26,8 @@ import java.io.*;
 import java.util.Date;
 
 /**
- * This DataEntryWriter sends data entries to a given jar/zip file.
+ * This DataEntryWriter sends data entries to a the jar/zip files specified by
+ * their parents.
  *
  * @author Eric Lafortune
  */


=====================================
core/src/proguard/obfuscate/Obfuscator.java
=====================================
@@ -23,7 +23,7 @@ package proguard.obfuscate;
 import proguard.*;
 import proguard.classfile.*;
 import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.constant.visitor.*;
 import proguard.classfile.editor.*;
 import proguard.classfile.util.*;
 import proguard.classfile.visitor.*;
@@ -98,10 +98,29 @@ public class Obfuscator
         libraryClassPool.classesAccept(nameMarker);
         libraryClassPool.classesAccept(new AllMemberVisitor(nameMarker));
 
+        // We also keep the names of the abstract methods of functional
+        // interfaces referenced from bootstrap method arguments (additional
+        // interfaces with LambdaMetafactory.altMetafactory).
+        // The functional method names have to match the names in the
+        // dynamic method invocations with LambdaMetafactory.
+        programClassPool.classesAccept(
+            new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
+            new AllAttributeVisitor(
+            new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
+            new AllBootstrapMethodInfoVisitor(
+            new AllBootstrapMethodArgumentVisitor(
+            new ConstantTagFilter(ClassConstants.CONSTANT_Class,
+            new ReferencedClassVisitor(
+            new FunctionalInterfaceFilter(
+            new ClassHierarchyTraveler(true, false, true, false,
+            new AllMethodVisitor(
+            new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0,
+            nameMarker))))))))))));
+
         // We also keep the names of the abstract methods of functional
         // interfaces that are returned by dynamic method invocations.
-        // The functional method names then have to match the names
-        // in the dynamic method invocations with LambdaMetafactory.
+        // The functional method names have to match the names in the
+        // dynamic method invocations with LambdaMetafactory.
         programClassPool.classesAccept(
             new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
             new AllConstantVisitor(


=====================================
core/src/proguard/optimize/Optimizer.java
=====================================
@@ -347,18 +347,33 @@ public class Optimizer
             new MethodrefTraveler(
             new ReferencedMemberVisitor(keepMarker))))))));
 
-        // We also keep all bootstrap method arguments that point to methods.
-        // These arguments are typically the method handles for
-        // java.lang.invoke.LambdaMetafactory#metafactory, which provides the
-        // implementations for closures.
+        // We also keep classes and methods referenced from bootstrap
+        // method arguments.
         programClassPool.classesAccept(
             new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_7,
             new AllAttributeVisitor(
             new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
             new AllBootstrapMethodInfoVisitor(
-            new BootstrapMethodArgumentVisitor(
-            new MethodrefTraveler(
-            new ReferencedMemberVisitor(keepMarker))))))));
+            new AllBootstrapMethodArgumentVisitor(
+            new MultiConstantVisitor(
+                // Class constants refer to additional functional
+                // interfaces (with LambdaMetafactory.altMetafactory).
+                new ConstantTagFilter(ClassConstants.CONSTANT_Class,
+                new ReferencedClassVisitor(
+                new FunctionalInterfaceFilter(
+                new ClassHierarchyTraveler(true, false, true, false,
+                new MultiClassVisitor(
+                    keepMarker,
+                    new AllMethodVisitor(
+                    new MemberAccessFilter(ClassConstants.ACC_ABSTRACT, 0,
+                    keepMarker))
+                ))))),
+
+                // Method handle constants refer to synthetic lambda
+                // methods (with LambdaMetafactory.metafactory and
+                // altMetafactory).
+                new MethodrefTraveler(
+                new ReferencedMemberVisitor(keepMarker)))))))));
 
         // We also keep the classes and abstract methods of functional
         // interfaces that are returned by dynamic method invocations.


=====================================
core/src/proguard/preverify/CodePreverifier.java
=====================================
@@ -26,7 +26,7 @@ import proguard.classfile.attribute.preverification.*;
 import proguard.classfile.attribute.visitor.AttributeVisitor;
 import proguard.classfile.editor.*;
 import proguard.classfile.instruction.InstructionConstants;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
 import proguard.classfile.visitor.ClassPrinter;
 import proguard.evaluation.*;
 import proguard.evaluation.value.*;
@@ -271,29 +271,41 @@ implements   AttributeVisitor
                                                               int             offset,
                                                               TracedVariables variables)
     {
-        int maximumVariablesSize = variables.size();
         int typeCount = 0;
-        int typeIndex = 0;
-
-        // Count the the number of verification types, ignoring any nulls at
-        // the end.
-        for (int index = 0; index < maximumVariablesSize; index++)
+        if (offset == AT_METHOD_ENTRY)
+        {
+            // Count the number of parameters, including any parameters
+            // that are unused and overwritten right away.
+            typeCount = ClassUtil.internalMethodParameterCount(
+                programMethod.getDescriptor(programClass),
+                programMethod.getAccessFlags());
+        }
+        else
         {
-            Value value = variables.getValue(index);
+            typeCount = 0;
 
-            typeIndex++;
+            int maximumVariablesSize = variables.size();
+            int typeIndex = 0;
 
-            // Remember the maximum live type index.
-            if (value != null &&
-                (offset == AT_METHOD_ENTRY ||
-                 livenessAnalyzer.isAliveBefore(offset, index)))
+            // Count the the number of verification types, ignoring any nulls at
+            // the end.
+            for (int index = 0; index < maximumVariablesSize; index++)
             {
-                typeCount = typeIndex;
+                Value value = variables.getValue(index);
 
-                // Category 2 types that are alive are stored as single entries.
-                if (value.isCategory2())
+                typeIndex++;
+
+                // Remember the maximum live type index.
+                if (value != null &&
+                    livenessAnalyzer.isAliveBefore(offset, index))
                 {
-                    index++;
+                    typeCount = typeIndex;
+
+                    // Category 2 types that are alive are stored as single entries.
+                    if (value.isCategory2())
+                    {
+                        index++;
+                    }
                 }
             }
         }
@@ -301,7 +313,7 @@ implements   AttributeVisitor
         // Create and fill out the verification types.
         VerificationType[] types = new VerificationType[typeCount];
 
-        typeIndex = 0;
+        int typeIndex = 0;
 
         // Note the slightly different terminating condition, because the
         // types may have been truncated.
@@ -332,7 +344,12 @@ implements   AttributeVisitor
             }
             else
             {
-                type = VerificationTypeFactory.createTopType();
+                // A null value at method entry means that there was a branch to
+                // offset 0 that has cleared the value. Then pick a dummy value so
+                // it never matches the next frame at offset 0.
+                type = offset == AT_METHOD_ENTRY ?
+                    VerificationTypeFactory.createUninitializedThisType() :
+                    VerificationTypeFactory.createTopType();
             }
 
             types[typeIndex++] = type;


=====================================
gradle/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-gradle</artifactId>


=====================================
gui/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-gui</artifactId>


=====================================
gui/src/proguard/gui/GUIResources.properties
=====================================
@@ -25,7 +25,7 @@ preverification = Preverification
 #
 # Panel titles.
 #
-welcome                       = Welcome to ProGuard, version 6.0.1
+welcome                       = Welcome to ProGuard, version 6.0.3
 options                       = Options
 keepAdditional                = Keep additional classes and class members
 keepNamesAdditional           = Keep additional class names and class member names
@@ -130,7 +130,7 @@ skipNonPublicLibraryClassMembers = Skip non-public library class members
 keepDirectories                  = Keep directories
 forceProcessing                  = Force processing
 target                           = Target
-targets                          = 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8
+targets                          = 1.0,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,10
 printSeeds                       = Print seeds
 printConfiguration               = Print configuration
 dump                             = Print class files


=====================================
retrace/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-retrace</artifactId>


=====================================
wtk/pom.xml
=====================================
@@ -8,7 +8,7 @@
     <parent>
         <groupId>net.sf.proguard</groupId>
         <artifactId>proguard-parent</artifactId>
-        <version>6.0.1</version>
+        <version>6.0.3</version>
         <relativePath>../buildscripts/pom.xml</relativePath>
     </parent>
     <artifactId>proguard-wtk-plugin</artifactId>



View it on GitLab: https://salsa.debian.org/java-team/proguard/compare/6eedd5704c39f5c456396f5b207af6c7e96a6a1f...89a9f2bf8739471013a7fd818a442c6ed896e271

-- 
View it on GitLab: https://salsa.debian.org/java-team/proguard/compare/6eedd5704c39f5c456396f5b207af6c7e96a6a1f...89a9f2bf8739471013a7fd818a442c6ed896e271
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20181210/7881eee0/attachment.html>


More information about the pkg-java-commits mailing list