Home | History | Annotate | Download | only in shrink
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 
     22 package proguard.shrink;
     23 
     24 import proguard.classfile.*;
     25 import proguard.classfile.attribute.*;
     26 import proguard.classfile.attribute.visitor.AttributeVisitor;
     27 import proguard.classfile.constant.Constant;
     28 import proguard.classfile.constant.visitor.ConstantVisitor;
     29 import proguard.classfile.util.SimplifiedVisitor;
     30 import proguard.classfile.visitor.ClassVisitor;
     31 
     32 /**
     33  * This AttributeVisitor recursively marks all Signature attributes that it
     34  * visits and that point to used classes.
     35  *
     36  * @see UsageMarker
     37  *
     38  * @author Eric Lafortune
     39  */
     40 public class SignatureUsageMarker
     41 extends      SimplifiedVisitor
     42 implements   AttributeVisitor,
     43              ClassVisitor,
     44              ConstantVisitor
     45 {
     46     private final UsageMarker usageMarker;
     47 
     48     // Fields acting as a return parameters for several methods.
     49     private boolean attributeUsed;
     50 
     51 
     52     /**
     53      * Creates a new SignatureUsageMarker.
     54      * @param usageMarker the usage marker that is used to mark the classes
     55      *                    and class members.
     56      */
     57     public SignatureUsageMarker(UsageMarker usageMarker)
     58     {
     59         this.usageMarker = usageMarker;
     60     }
     61 
     62 
     63     // Implementations for AttributeVisitor.
     64 
     65     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
     66 
     67 
     68     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
     69     {
     70         // Only keep the signature if any of its classes are used.
     71         attributeUsed = false;
     72         signatureAttribute.referencedClassesAccept(this);
     73 
     74         if (attributeUsed)
     75         {
     76             // We got a positive used flag, so the signature is useful.
     77             usageMarker.markAsUsed(signatureAttribute);
     78 
     79             markConstant(clazz, signatureAttribute.u2attributeNameIndex);
     80             markConstant(clazz, signatureAttribute.u2signatureIndex);
     81         }
     82     }
     83 
     84 
     85     // Implementations for ClassVisitor.
     86 
     87     public void visitLibraryClass(LibraryClass libraryClass)
     88     {
     89         attributeUsed = true;
     90     }
     91 
     92 
     93     public void visitProgramClass(ProgramClass programClass)
     94     {
     95         // Don't keep the signature if one of its classes is not used.
     96         if (usageMarker.isUsed(programClass))
     97         {
     98             attributeUsed = true;
     99         }
    100     }
    101 
    102 
    103     // Implementations for ConstantVisitor.
    104 
    105     public void visitAnyConstant(Clazz clazz, Constant constant)
    106     {
    107         usageMarker.markAsUsed(constant);
    108     }
    109 
    110 
    111     // Small utility methods.
    112 
    113     /**
    114      * Marks the given constant pool entry of the given class.
    115      */
    116     private void markConstant(Clazz clazz, int index)
    117     {
    118          clazz.constantPoolEntryAccept(index, this);
    119     }
    120 }
    121