summaryrefslogtreecommitdiff
path: root/src/proguard/classfile/util/AllParameterVisitor.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/classfile/util/AllParameterVisitor.java')
-rw-r--r--src/proguard/classfile/util/AllParameterVisitor.java239
1 files changed, 239 insertions, 0 deletions
diff --git a/src/proguard/classfile/util/AllParameterVisitor.java b/src/proguard/classfile/util/AllParameterVisitor.java
new file mode 100644
index 0000000..3695dbb
--- /dev/null
+++ b/src/proguard/classfile/util/AllParameterVisitor.java
@@ -0,0 +1,239 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * 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.util;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This MemberVisitor lets a given parameter visitor visit all the parameters
+ * of the methods that it visits. The parameters do not include or count the
+ * 'this' parameter or the return value.
+ *
+ * @author Eric Lafortune
+ */
+public class AllParameterVisitor
+implements MemberVisitor
+{
+ private final ParameterVisitor parameterVisitor;
+
+
+ /**
+ * Creates a new AllParameterVisitor for the given parameter
+ * visitor.
+ */
+ public AllParameterVisitor(ParameterVisitor parameterVisitor)
+ {
+ this.parameterVisitor = parameterVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ visitFieldType(programClass,
+ programField,
+ programField.referencedClass);
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ visitFieldType(libraryClass,
+ libraryField,
+ libraryField.referencedClass);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ visitParameters(programClass,
+ programMethod,
+ programMethod.referencedClasses);
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ visitParameters(libraryClass,
+ libraryMethod,
+ libraryMethod.referencedClasses);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Lets the parameter visitor visit the type of the given field.
+ */
+ private void visitFieldType(Clazz clazz,
+ Field field,
+ Clazz referencedClass)
+ {
+ String descriptor = field.getDescriptor(clazz);
+ parameterVisitor.visitParameter(clazz,
+ field,
+ 0,
+ 1,
+ 0,
+ ClassUtil.internalTypeSize(descriptor),
+ descriptor,
+ referencedClass);
+ }
+
+
+ /**
+ * Lets the parameter visitor visit the parameters of the given method.
+ */
+ private void visitParameters(Clazz clazz,
+ Method method,
+ Clazz[] referencedClasses)
+ {
+ String descriptor = method.getDescriptor(clazz);
+
+ // Count the number of parameters and their total size.
+ int parameterCount = 0;
+ int parameterSize = 0;
+
+ int index = 1;
+
+ loop: while (true)
+ {
+ char c = descriptor.charAt(index++);
+ switch (c)
+ {
+ case ClassConstants.TYPE_LONG:
+ case ClassConstants.TYPE_DOUBLE:
+ {
+ // Long and double primitive types.
+ parameterSize++;
+ break;
+ }
+ default:
+ {
+ // All other primitive types.
+ break;
+ }
+ case ClassConstants.TYPE_CLASS_START:
+ {
+ // Class types.
+ // Skip the class name.
+ index = descriptor.indexOf(ClassConstants.TYPE_CLASS_END, index) + 1;
+ break;
+ }
+ case ClassConstants.TYPE_ARRAY:
+ {
+ // Array types.
+ // Skip all array characters.
+ while ((c = descriptor.charAt(index++)) == ClassConstants.TYPE_ARRAY) {}
+
+ if (c == ClassConstants.TYPE_CLASS_START)
+ {
+ // Skip the class type.
+ index = descriptor.indexOf(ClassConstants.TYPE_CLASS_END, index) + 1;
+ }
+ break;
+ }
+ case ClassConstants.METHOD_ARGUMENTS_CLOSE:
+ {
+ break loop;
+ }
+ }
+
+ parameterCount++;
+ parameterSize++;
+ }
+
+ // Visit the parameters.
+ int parameterIndex = 0;
+ int parameterOffset = 0;
+ int referenceClassIndex = 0;
+
+ index = 1;
+
+ while (true)
+ {
+ int newIndex = index + 1;
+ int thisParameterSize = 1;
+ Clazz referencedClass = null;
+
+ char c = descriptor.charAt(index);
+ switch (c)
+ {
+ case ClassConstants.TYPE_LONG:
+ case ClassConstants.TYPE_DOUBLE:
+ {
+ // Long and double primitive types.
+ thisParameterSize = 2;
+ break;
+ }
+ default:
+ {
+ // All other primitive types.
+ break;
+ }
+ case ClassConstants.TYPE_CLASS_START:
+ {
+ // Class types.
+ // Skip the class name.
+ newIndex = descriptor.indexOf(ClassConstants.TYPE_CLASS_END, newIndex) + 1;
+ referencedClass = referencedClasses == null ? null :
+ referencedClasses[referenceClassIndex++];
+ break;
+ }
+ case ClassConstants.TYPE_ARRAY:
+ {
+ // Array types.
+ // Skip all array characters.
+ while ((c = descriptor.charAt(newIndex++)) == ClassConstants.TYPE_ARRAY) {}
+
+ if (c == ClassConstants.TYPE_CLASS_START)
+ {
+ // Skip the class type.
+ newIndex = descriptor.indexOf(ClassConstants.TYPE_CLASS_END, newIndex) + 1;
+ referencedClass = referencedClasses == null ? null :
+ referencedClasses[referenceClassIndex++];
+ }
+ break;
+ }
+ case ClassConstants.METHOD_ARGUMENTS_CLOSE:
+ {
+ // End of the method parameters.
+ return;
+ }
+ }
+
+ parameterVisitor.visitParameter(clazz,
+ method,
+ parameterIndex++,
+ parameterCount,
+ parameterOffset,
+ parameterSize,
+ descriptor.substring(index, newIndex),
+ referencedClass);
+
+ // Continue with the next parameter.
+ index = newIndex;
+ parameterOffset += thisParameterSize;
+ }
+ }
+}