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 package proguard.shrink;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.visitor.*;
     25 
     26 
     27 /**
     28  * This class can be used as a mark when keeping classes, class members, and
     29  * other elements. It can be certain or preliminary. It also contains additional
     30  * information about the reasons why an element is being kept.
     31  *
     32  * @see ClassShrinker
     33  *
     34  * @author Eric Lafortune
     35  */
     36 final class ShortestUsageMark
     37 {
     38     private final boolean certain;
     39     private final String  reason;
     40     private final int     depth;
     41     private       Clazz   clazz;
     42     private       Member  member;
     43 
     44 
     45     /**
     46      * Creates a new certain ShortestUsageMark.
     47      * @param reason the reason for this mark.
     48      */
     49     public ShortestUsageMark(String reason)
     50     {
     51         this.certain = true;
     52         this.reason  = reason;
     53         this.depth   = 0;
     54     }
     55 
     56 
     57     /**
     58      * Creates a new certain ShortestUsageMark.
     59      * @param previousUsageMark the previous mark to which this one is linked.
     60      * @param reason            the reason for this mark.
     61      * @param clazz             the class causing this mark.
     62      */
     63     public ShortestUsageMark(ShortestUsageMark previousUsageMark,
     64                              String            reason,
     65                              int               cost,
     66                              Clazz             clazz)
     67     {
     68         this(previousUsageMark, reason, cost, clazz, null);
     69     }
     70 
     71 
     72     /**
     73      * Creates a new certain ShortestUsageMark.
     74      * @param previousUsageMark the previous mark to which this one is linked.
     75      * @param reason            the reason for this mark.
     76      * @param clazz             the class causing this mark.
     77      * @param member            the member in the above class causing this mark.
     78      * @param cost              the added cost of following this path.
     79      */
     80     public ShortestUsageMark(ShortestUsageMark previousUsageMark,
     81                              String            reason,
     82                              int               cost,
     83                              Clazz             clazz,
     84                              Member            member)
     85     {
     86         this.certain = true;
     87         this.reason  = reason;
     88         this.depth   = previousUsageMark.depth + cost;
     89         this.clazz   = clazz;
     90         this.member  = member;
     91     }
     92 
     93 
     94     /**
     95      * Creates a new ShortestUsageMark, based on another mark.
     96      * @param otherUsageMark the other mark, whose properties will be copied.
     97      * @param certain        specifies whether this is a certain mark.
     98      */
     99     public ShortestUsageMark(ShortestUsageMark otherUsageMark,
    100                              boolean           certain)
    101     {
    102         this.certain = certain;
    103         this.reason  = otherUsageMark.reason;
    104         this.depth   = otherUsageMark.depth;
    105         this.clazz   = otherUsageMark.clazz;
    106         this.member  = otherUsageMark.member;
    107     }
    108 
    109 
    110     /**
    111      * Returns whether this is a certain mark.
    112      */
    113     public boolean isCertain()
    114     {
    115         return certain;
    116     }
    117 
    118 
    119     /**
    120      * Returns the reason for this mark.
    121      */
    122     public String getReason()
    123     {
    124         return reason;
    125     }
    126 
    127 
    128     /**
    129      * Returns whether this mark has a shorter chain of reasons than the
    130      * given mark.
    131      */
    132     public boolean isShorter(ShortestUsageMark otherUsageMark)
    133     {
    134         return this.depth < otherUsageMark.depth;
    135     }
    136 
    137 
    138     /**
    139      * Returns whether this is mark is caused by the given class.
    140      */
    141     public boolean isCausedBy(Clazz clazz)
    142     {
    143         return clazz.equals(this.clazz);
    144     }
    145 
    146 
    147     /**
    148      * Applies the given class visitor to this mark's class, if any,
    149      * and if this mark doesn't have a member.
    150      */
    151     public void acceptClassVisitor(ClassVisitor classVisitor)
    152     {
    153         if (clazz  != null &&
    154             member == null)
    155         {
    156             clazz.accept(classVisitor);
    157         }
    158     }
    159 
    160 
    161     /**
    162      * Applies the given class visitor to this mark's member, if any.
    163      */
    164     public void acceptMemberVisitor(MemberVisitor memberVisitor)
    165     {
    166         if (clazz  != null &&
    167             member != null)
    168         {
    169             member.accept(clazz, memberVisitor);
    170         }
    171     }
    172 
    173 
    174     // Implementations for Object.
    175 
    176     public String toString()
    177     {
    178         return "certain=" + certain + ", depth="+depth+": " +
    179                reason +
    180                (clazz      != null ? clazz.getName() : "(none)") + ": " +
    181                (member     != null ? member.getName(clazz) : "(none)");
    182     }
    183 }
    184