001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.obfuscate;
022:
023: import proguard.classfile.*;
024: import proguard.classfile.attribute.*;
025: import proguard.classfile.attribute.visitor.AttributeVisitor;
026: import proguard.classfile.util.SimplifiedVisitor;
027: import proguard.classfile.visitor.*;
028:
029: /**
030: * This ClassVisitor removes attributes that are not marked as being used or
031: * required.
032: *
033: * @see AttributeUsageMarker
034: *
035: * @author Eric Lafortune
036: */
037: public class AttributeShrinker extends SimplifiedVisitor implements
038: ClassVisitor, MemberVisitor, AttributeVisitor {
039: // Implementations for ClassVisitor.
040:
041: public void visitProgramClass(ProgramClass programClass) {
042: // Compact the array for class attributes.
043: programClass.u2attributesCount = shrinkArray(
044: programClass.attributes, programClass.u2attributesCount);
045:
046: // Compact the attributes in fields, methods, and class attributes,
047: programClass.fieldsAccept(this );
048: programClass.methodsAccept(this );
049: programClass.attributesAccept(this );
050: }
051:
052: public void visitLibraryClass(LibraryClass libraryClass) {
053: // Library classes are left unchanged.
054: }
055:
056: // Implementations for MemberVisitor.
057:
058: public void visitProgramMember(ProgramClass programClass,
059: ProgramMember programMember) {
060: // Compact the attributes array.
061: programMember.u2attributesCount = shrinkArray(
062: programMember.attributes,
063: programMember.u2attributesCount);
064:
065: // Compact any attributes of the remaining attributes.
066: programMember.attributesAccept(programClass, this );
067: }
068:
069: // Implementations for AttributeVisitor.
070:
071: public void visitAnyAttribute(Clazz clazz, Attribute attribute) {
072: }
073:
074: public void visitCodeAttribute(Clazz clazz, Method method,
075: CodeAttribute codeAttribute) {
076: // Compact the attributes array.
077: codeAttribute.u2attributesCount = shrinkArray(
078: codeAttribute.attributes,
079: codeAttribute.u2attributesCount);
080: }
081:
082: // Small utility methods.
083:
084: /**
085: * Removes all VisitorAccepter objects that are not marked as being used
086: * from the given array.
087: * @return the new number of VisitorAccepter objects.
088: */
089: private static int shrinkArray(VisitorAccepter[] array, int length) {
090: int counter = 0;
091:
092: // Shift the used objects together.
093: for (int index = 0; index < length; index++) {
094: if (AttributeUsageMarker.isUsed(array[index])) {
095: array[counter++] = array[index];
096: }
097: }
098:
099: // Clear the remaining array elements.
100: for (int index = counter; index < length; index++) {
101: array[index] = null;
102: }
103:
104: return counter;
105: }
106: }
|