Upgrade from Progaurd 4.4 to 4.7.
Change-Id: Ie185d0be411a80cc6a330cafa8547252a7dc1d9c
You can find the changelog here
http://proguard.sourceforge.net/#downloads.html
diff --git a/README b/README
index 8766da5..62996f8 100644
--- a/README
+++ b/README
@@ -30,4 +30,4 @@
http://proguard.sourceforge.net/
-Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
diff --git a/bin/proguard.bat b/bin/proguard.bat
index 9e91ebf..73cb313 100644
--- a/bin/proguard.bat
+++ b/bin/proguard.bat
@@ -2,6 +2,10 @@
REM Start-up script for ProGuard -- free class file shrinker, optimizer,
REM obfuscator, and preverifier for Java bytecode.
+REM
+REM Note: when passing file names containing spaces to this script,
+REM you'll have to add escaped quotes around them, e.g.
+REM "\"C:/My Directory/My File.txt\""
IF EXIST "%PROGUARD_HOME%" GOTO home
SET PROGUARD_HOME=..
diff --git a/bin/proguard.sh b/bin/proguard.sh
index 5d441f9..5adc047 100755
--- a/bin/proguard.sh
+++ b/bin/proguard.sh
@@ -2,8 +2,11 @@
#
# Start-up script for ProGuard -- free class file shrinker, optimizer,
# obfuscator, and preverifier for Java bytecode.
+#
+# Note: when passing file names containing spaces to this script,
+# you'll have to add escaped quotes around them, e.g.
+# "\"/My Directory/My File.txt\""
-PROGUARD_HOME=`dirname "$0"`
-PROGUARD_HOME=`dirname "$PROGUARD_HOME"`
+PROGUARD_HOME=`dirname "$0"`/..
-java -jar "$PROGUARD_HOME"/lib/proguard.jar "$@"
+java -jar $PROGUARD_HOME/lib/proguard.jar "$@"
diff --git a/bin/proguardgui.bat b/bin/proguardgui.bat
index 073d98a..4aa9aeb 100644
--- a/bin/proguardgui.bat
+++ b/bin/proguardgui.bat
@@ -2,9 +2,13 @@
REM Start-up script for the GUI of ProGuard -- free class file shrinker,
REM optimizer, obfuscator, and preverifier for Java bytecode.
+REM
+REM Note: when passing file names containing spaces to this script,
+REM you'll have to add escaped quotes around them, e.g.
+REM "\"C:/My Directory/My File.txt\""
IF EXIST "%PROGUARD_HOME%" GOTO home
SET PROGUARD_HOME=..
:home
-java -jar "%PROGUARD_HOME%"\lib\proguardgui.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
+java -jar "%PROGUARD_HOME%"\lib\proguardgui.jar %*
diff --git a/bin/proguardgui.sh b/bin/proguardgui.sh
index 5a25d7b..c734906 100755
--- a/bin/proguardgui.sh
+++ b/bin/proguardgui.sh
@@ -2,8 +2,14 @@
#
# Start-up script for the GUI of ProGuard -- free class file shrinker,
# optimizer, obfuscator, and preverifier for Java bytecode.
+#
+# Note: when passing file names containing spaces to this script,
+# you'll have to add escaped quotes around them, e.g.
+# "\"/My Directory/My File.txt\""
-PROGUARD_HOME=`dirname "$0"`
-PROGUARD_HOME=`dirname "$PROGUARD_HOME"`
+PROGUARD_HOME=`dirname "$0"`/..
-java -jar $PROGUARD_HOME/lib/proguardgui.jar "$@"
+# On Linux, Java 1.6.0_24 and higher hang when starting the GUI:
+# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7027598
+# We're using the -D option as a workaround.
+java -DsuppressSwingDropSupport=true -jar $PROGUARD_HOME/lib/proguardgui.jar "$@"
diff --git a/bin/retrace.bat b/bin/retrace.bat
index 70603d3..c13b766 100644
--- a/bin/retrace.bat
+++ b/bin/retrace.bat
@@ -2,9 +2,13 @@
REM Start-up script for Retrace -- companion tool for ProGuard, free class file
REM shrinker, optimizer, obfuscator, and preverifier for Java bytecode.
+REM
+REM Note: when passing file names containing spaces to this script,
+REM you'll have to add escaped quotes around them, e.g.
+REM "\"C:/My Directory/My File.txt\""
IF EXIST "%PROGUARD_HOME%" GOTO home
SET PROGUARD_HOME=..
:home
-java -jar "%PROGUARD_HOME%"\lib\retrace.jar %1 %2 %3 %4 %5 %6 %7 %8 %9
+java -jar "%PROGUARD_HOME%"\lib\retrace.jar %*
diff --git a/bin/retrace.sh b/bin/retrace.sh
index 5db744e..85fd314 100755
--- a/bin/retrace.sh
+++ b/bin/retrace.sh
@@ -2,8 +2,11 @@
#
# Start-up script for Retrace -- companion tool for ProGuard, free class file
# shrinker, optimizer, obfuscator, and preverifier for Java bytecode.
+#
+# Note: when passing file names containing spaces to this script,
+# you'll have to add escaped quotes around them, e.g.
+# "\"/My Directory/My File.txt\""
-PROGUARD_HOME=`dirname "$0"`
-PROGUARD_HOME=`dirname "$PROGUARD_HOME"`
+PROGUARD_HOME=`dirname "$0"`/..
java -jar $PROGUARD_HOME/lib/retrace.jar "$@"
diff --git a/docs/FAQ.html b/docs/FAQ.html
index 8f19b15..bdc9c04 100644
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard FAQ</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -13,35 +24,37 @@
<h3>Contents</h3>
<ol>
-<li><a href="#shrinking">What is shrinking?</a>
-<li><a href="#obfuscation">What is obfuscation?</a>
-<li><a href="#preverification">What is preverification?</a>
+<li><a href="#shrinking">What is shrinking?</a></li>
+<li><a href="#obfuscation">What is obfuscation?</a></li>
+<li><a href="#preverification">What is preverification?</a></li>
<li><a href="#optimization">What kind of optimizations does <b>ProGuard</b>
- support?</a>
+ support?</a></li>
<li><a href="#commercial">Can I use <b>ProGuard</b> to process my commercial
- application?</a>
+ application?</a></li>
<li><a href="#jdk1.4">Does <b>ProGuard</b> work with Java 2? Java 5? Java
- 6?</a>
-<li><a href="#jme">Does <b>ProGuard</b> work with Java Micro Edition?</a>
-<li><a href="#android">Does <b>ProGuard</b> work for Google Android code?</a>
-<li><a href="#blackberry">Does <b>ProGuard</b> work for Blackberry code?</a>
-<li><a href="#ant">Does <b>ProGuard</b> have support for Ant?</a>
-<li><a href="#gui">Does <b>ProGuard</b> come with a GUI?</a>
+ 6?</a></li>
+<li><a href="#jme">Does <b>ProGuard</b> work with Java Micro Edition?</a></li>
+<li><a href="#android">Does <b>ProGuard</b> work for Google Android
+ code?</a></li>
+<li><a href="#blackberry">Does <b>ProGuard</b> work for Blackberry
+ code?</a></li>
+<li><a href="#ant">Does <b>ProGuard</b> have support for Ant?</a></li>
+<li><a href="#gui">Does <b>ProGuard</b> come with a GUI?</a></li>
<li><a href="#forname">Does <b>ProGuard</b> handle <code>Class.forName</code>
- calls?</a>
-<li><a href="#resource">Does <b>ProGuard</b> handle resource files?</a>
-<li><a href="#encrypt">Does <b>ProGuard</b> encrypt strings constants?</a>
-<li><a href="#flow">Does <b>ProGuard</b> perform control flow obfuscation?</a>
+ calls?</a></li>
+<li><a href="#resource">Does <b>ProGuard</b> handle resource files?</a></li>
+<li><a href="#encrypt">Does <b>ProGuard</b> encrypt strings constants?</a></li>
+<li><a href="#flow">Does <b>ProGuard</b> perform control flow
+ obfuscation?</a></li>
<li><a href="#incremental">Does <b>ProGuard</b> support incremental
- obfuscation?</a>
+ obfuscation?</a></li>
<li><a href="#keywords">Can <b>ProGuard</b> obfuscate using reserved
- keywords?</a>
+ keywords?</a></li>
<li><a href="#stacktrace">Can <b>ProGuard</b> reconstruct obfuscated stack
- traces?</a>
+ traces?</a></li>
</ol>
-<a name="shrinking"> </a>
-<h3>What is shrinking?</h3>
+<h3><a name="shrinking">What is shrinking?</a></h3>
Java source code (.java files) is typically compiled to bytecode (.class
files). Bytecode is more compact than Java source code, but it may still
@@ -50,8 +63,7 @@
unused classes, fields, and methods. The program remains functionally
equivalent, including the information given in exception stack traces.
-<a name="obfuscation"> </a>
-<h3>What is obfuscation?</h3>
+<h3><a name="obfuscation">What is obfuscation?</a></h3>
By default, compiled bytecode still contains a lot of debugging information:
source file names, line numbers, field names, method names, argument names,
@@ -63,8 +75,7 @@
bonus. The program remains functionally equivalent, except for the class
names, method names, and line numbers given in exception stack traces.
-<a name="preverification"> </a>
-<h3>What is preverification?</h3>
+<h3><a name="preverification">What is preverification?</a></h3>
When loading class files, the class loader performs some sophisticated
verification of the byte code. This analysis makes sure the code can't
@@ -77,8 +88,7 @@
perform the preverification step too, for instance allowing to retarget older
class files at Java 6.
-<a name="optimization"> </a>
-<h3>What kind of optimizations does <b>ProGuard</b> support?</h3>
+<h3><a name="optimization">What kind of optimizations does <b>ProGuard</b> support?</a></h3>
Apart from removing unused classes, fields, and methods in the shrinking step,
<b>ProGuard</b> can also perform optimizations at the bytecode level, inside
@@ -87,24 +97,24 @@
and liveness analysis, <b>ProGuard</b> can:
<ul>
-<li>Evaluate constant expressions.
-<li>Remove unnecessary field accesses and method calls.
-<li>Remove unnecessary branches.
-<li>Remove unnecessary comparisons and instanceof tests.
-<li>Remove unused code blocks.
-<li>Merge identical code blocks.
-<li>Reduce variable allocation.
-<li>Remove write-only fields and unused method parameters.
-<li>Inline constant fields, method parameters, and return values.
-<li>Inline methods that are short or only called once.
-<li>Simplify tail recursion calls.
-<li>Merge classes and interfaces.
-<li>Make methods private, static, and final when possible.
-<li>Make classes static and final when possible.
-<li>Replace interfaces that have single implementations.
+<li>Evaluate constant expressions.</li>
+<li>Remove unnecessary field accesses and method calls.</li>
+<li>Remove unnecessary branches.</li>
+<li>Remove unnecessary comparisons and instanceof tests.</li>
+<li>Remove unused code blocks.</li>
+<li>Merge identical code blocks.</li>
+<li>Reduce variable allocation.</li>
+<li>Remove write-only fields and unused method parameters.</li>
+<li>Inline constant fields, method parameters, and return values.</li>
+<li>Inline methods that are short or only called once.</li>
+<li>Simplify tail recursion calls.</li>
+<li>Merge classes and interfaces.</li>
+<li>Make methods private, static, and final when possible.</li>
+<li>Make classes static and final when possible.</li>
+<li>Replace interfaces that have single implementations.</li>
<li>Perform over 200 peephole optimizations, like replacing ...*2 by
- ...<<1.
-<li>Optionally remove logging code.
+ ...<<1.</li>
+<li>Optionally remove logging code.</li>
</ul>
The positive effects of these optimizations will depend on your code and on
the virtual machine on which the code is executed. Simple virtual machines may
@@ -113,27 +123,26 @@
<p>
Some notable optimizations that aren't supported yet:
<ul>
-<li>Moving constant expressions out of loops.
-<li>Optimizations that require escape analysis.
+<li>Moving constant expressions out of loops.</li>
+<li>Optimizations that require escape analysis.</li>
</ul>
-<a name="commercial"> </a>
-<h3>Can I use <b>ProGuard</b> to process my commercial application?</h3>
+<h3><a name="commercial">Can I use <b>ProGuard</b> to process my commercial application?</a></h3>
Yes, you can. <b>ProGuard</b> itself is distributed under the GPL, but this
doesn't affect the programs that you process. Your code remains yours, and
its license can remain the same.
-<a name="jdk1.4"> </a>
-<h3>Does <b>ProGuard</b> work with Java 2? Java 5? Java 6?</h3>
+<h3><a name="jdk1.4">Does <b>ProGuard</b> work with Java 2? Java 5? Java 6? Java 7?</a></h3>
-Yes, <b>ProGuard</b> supports all JDKs from 1.1 up to and including 6.0. Java 2
+Yes, <b>ProGuard</b> supports all JDKs from 1.1 up to and including 7.0. Java 2
introduced some small differences in the class file format. Java 5 added
-attributes for generics and for annotations. Java 6 introduced preverification
-attributes. <b>ProGuard</b> handles all versions correctly.
+attributes for generics and for annotations. Java 6 introduced optional
+preverification attributes. Java 7 made preverification obligatory and
+introduced support for dynamic languages. <b>ProGuard</b> handles all versions
+correctly.
-<a name="jme"> </a>
-<h3>Does <b>ProGuard</b> work with Java Micro Edition?</h3>
+<h3><a name="jme">Does <b>ProGuard</b> work with Java Micro Edition?</a></h3>
Yes. <b>ProGuard</b> itself runs in Java Standard Edition, but you can freely
specify the run-time environment at which your programs are targeted,
@@ -144,16 +153,14 @@
<b>ProGuard</b> also comes with an obfuscator plug-in for the JME Wireless
Toolkit.
-<a name="android"> </a>
-<h3>Does <b>ProGuard</b> work for Google Android code?</h3>
+<h3><a name="android">Does <b>ProGuard</b> work for Google Android code?</a></h3>
Yes. Google's <code>dx</code> compiler converts ordinary jar files into files
that run on Android devices. By preprocessing the original jar files,
<b>ProGuard</b> can significantly reduce the file sizes and boost the run-time
performance of the code.
-<a name="blackberry"> </a>
-<h3>Does <b>ProGuard</b> work for Blackberry code?</h3>
+<h3><a name="blackberry">Does <b>ProGuard</b> work for Blackberry code?</a></h3>
It should. RIM's proprietary <code>rapc</code> compiler converts ordinary JME
jar files into cod files that run on Blackberry devices. The compiler performs
@@ -163,24 +170,21 @@
bugs. It sometimes fails on obfuscated code that is valid and accepted by other
JME tools and VMs. Your mileage may therefore vary.
-<a name="ant"> </a>
-<h3>Does <b>ProGuard</b> have support for Ant?</h3>
+<h3><a name="ant">Does <b>ProGuard</b> have support for Ant?</a></h3>
Yes. <b>ProGuard</b> provides an Ant task, so that it integrates seamlessly
into your Ant build processes. You can still use configurations in
<b>ProGuard</b>'s own readable format. Alternatively, if you prefer XML, you
can specify the equivalent XML configuration.
-<a name="gui"> </a>
-<h3>Does <b>ProGuard</b> come with a GUI?</h3>
+<h3><a name="gui">Does <b>ProGuard</b> come with a GUI?</a></h3>
Yes. First of all, <b>ProGuard</b> is perfectly usable as a command-line tool
that can easily be integrated into any automatic build process. For casual
users, there's also a graphical user interface that simplifies creating,
loading, editing, executing, and saving ProGuard configurations.
-<a name="forname"> </a>
-<h3>Does <b>ProGuard</b> handle <code>Class.forName</code> calls?</h3>
+<h3><a name="forname">Does <b>ProGuard</b> handle <code>Class.forName</code> calls?</a></h3>
Yes. <b>ProGuard</b> automatically handles constructs like
<code>Class.forName("SomeClass")</code> and <code>SomeClass.class</code>. The
@@ -195,22 +199,19 @@
implementations may need to be preserved. The user can adapt his configuration
accordingly.
-<a name="resource"> </a>
-<h3>Does <b>ProGuard</b> handle resource files?</h3>
+<h3><a name="resource">Does <b>ProGuard</b> handle resource files?</a></h3>
Yes. <b>ProGuard</b> copies all non-class resource files, optionally adapting
their names and their contents to the obfuscation that has been applied.
-<a name="encrypt"> </a>
-<h3>Does <b>ProGuard</b> encrypt strings constants?</h3>
+<h3><a name="encrypt">Does <b>ProGuard</b> encrypt strings constants?</a></h3>
No. Storing encrypted string constants in program code is fairly futile, since
the encryption has to be perfectly reversible by definition. Moreover, the
decryption costs additional memory and computation at run-time. If this feature
is ever incorporated, I'll provide a tool to decrypt the strings as well.
-<a name="flow"> </a>
-<h3>Does <b>ProGuard</b> perform flow obfuscation?</h3>
+<h3><a name="flow">Does <b>ProGuard</b> perform flow obfuscation?</a></h3>
Not explicitly. Control flow obfuscation injects additional branches into the
bytecode, in an attempt to fool decompilers. <b>ProGuard</b> does not do this,
@@ -218,15 +219,13 @@
optimization step often already restructures the code to the point where most
decompilers get confused.
-<a name="incremental"> </a>
-<h3>Does <b>ProGuard</b> support incremental obfuscation?</h3>
+<h3><a name="incremental">Does <b>ProGuard</b> support incremental obfuscation?</a></h3>
Yes. This feature allows you to specify a previous obfuscation mapping file in
a new obfuscation step, in order to produce add-ons or patches for obfuscated
code.
-<a name="keywords"> </a>
-<h3>Can <b>ProGuard</b> obfuscate using reserved keywords?</h3>
+<h3><a name="keywords">Can <b>ProGuard</b> obfuscate using reserved keywords?</a></h3>
Yes. You can specify your own obfuscation dictionary, such as a list of
reserved key words, identifiers with foreign characters, random source files,
@@ -234,8 +233,7 @@
Decent decompilers can automatically replace reserved keywords, and the effect
can be undone fairly easily, by obfuscating again with simpler names.
-<a name="stacktrace"> </a>
-<h3>Can <b>ProGuard</b> reconstruct obfuscated stack traces?</h3>
+<h3><a name="stacktrace">Can <b>ProGuard</b> reconstruct obfuscated stack traces?</a></h3>
Yes. <b>ProGuard</b> comes with a companion tool, <b>ReTrace</b>, that can
'de-obfuscate' stack traces produced by obfuscated applications. The
@@ -245,10 +243,11 @@
reverse mapping. Please refer to the <a href="manual/index.html">ProGuard User
Manual</a> for more details.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/GPL_exception.html b/docs/GPL_exception.html
index 0a44d66..0a1cd4f 100644
--- a/docs/GPL_exception.html
+++ b/docs/GPL_exception.html
@@ -7,7 +7,7 @@
<H1>Special Exception to the GNU General Public License</H1>
<P>
-Copyright © 2002-2009 Eric Lafortune
+Copyright © 2002-2011 Eric Lafortune
</P>
<P>
@@ -33,13 +33,17 @@
In addition, as a special exception, Eric Lafortune gives permission to link
the code of this program with the following stand-alone applications:
<ul>
-<li>Apache Ant,
-<li>Apache Maven,
-<li>the Eclipse ProGuardDT GUI,
-<li>the EclipseME JME IDE,
-<li>the Sun NetBeans Java IDE,
-<li>the Sun JME Wireless Toolkit, and
-<li>the Javaground Tools,
+<li>Apache Ant,</li>
+<li>Apache Maven,</li>
+<li>the Google Android SDK,</li>
+<li>the Eclipse ProGuardDT GUI,</li>
+<li>the EclipseME JME IDE,</li>
+<li>the Oracle NetBeans Java IDE,</li>
+<li>the Oracle JME Wireless Toolkit,</li>
+<li>the Simple Build Tool for Scala (and its scripts),</li>
+<li>the NeoMAD Tools by Neomades,</li>
+<li>the Javaground Tools, and</li>
+<li>the Sanaware Tools,</li>
</ul>
and distribute linked combinations including the two. You must obey the GNU
General Public License in all respects for all of the code used other than
diff --git a/docs/acknowledgements.html b/docs/acknowledgements.html
index af19461..96ed635 100644
--- a/docs/acknowledgements.html
+++ b/docs/acknowledgements.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Acknowledgements</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -33,35 +44,32 @@
Daniel Sjöblom, Jan Filipsky, Charles Smith, Gerrit Telkamp, Noel
Grandin, Torbjörn Söderstedt, Clemens Eisserer, Clark Bassett,
Eduard Welch, Dawid Weiss, Andrew Wilson, Sean Owen, Niels Gron, Ishan Mehta,
-Steven Adams, Xavier Kral,
+Steven Adams, Xavier Kral, Stefan Martin, Toby Reyelts,
and many others. Thanks! Your feedback has been invaluable.
<p>
-I am developing ProGuard in my spare time, which is possible thanks to my
-day-time job at <a href="http://www.luciad.com/" target="other">Luciad</a>.
+<a href="http://www.saikoa.com/" target="_top">Saikoa</a> is providing the
+financial resources for this project.
<p>
<a href="http://sourceforge.net/projects/proguard/"
-target="other">SourceForge</a> is generously providing the resources for
-hosting this project and many other projects.
+target="other">SourceForge</a> is providing the resources for hosting this
+project and many other projects.
<p>
-JetBrains is kindly providing a license for its IntelliJ IDEA development
-environment.
+The code and these web pages were written using Oracle/Sun's JDKs, Linux,
+IntelliJ IDEA, GNU emacs, bash, sed, awk, and a whole host of other tools that
+continue to make programming interesting.
<p>
-The code and these web pages were written using Sun's JDKs, Linux, IntelliJ
-IDEA, GNU emacs, bash, sed, awk, and a whole host of other tools that continue
-to make programming interesting.
-<p>
-
-And finally, I'm a great fan of the <a
+And finally, I'm a great fan of Sanaware's <a
href="http://www.javadocking.com/" target="other">Java Docking Library</a>.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/alternatives.html b/docs/alternatives.html
index fa5db0c..f235692 100644
--- a/docs/alternatives.html
+++ b/docs/alternatives.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Alternatives</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -34,612 +45,642 @@
</tr>
<tr>
-<td><a target="other" href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a></td>
+<td><a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a></td>
<td><a target="_top" href="http://proguard.sourceforge.net/">ProGuard</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
<td>Free (GPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.informatik.uni-oldenburg.de/leute/hoenicke.html">Jochen Hoenicke</a></td>
<td><a target="other" href="http://jode.sourceforge.net/">Jode</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (GPL)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.nq4.de/">NQ4</a></td>
-<td><a target="other" href="http://www.nq4.de/">Joga</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Free (no source)</td>
-</tr>
-
-<tr>
<td><a target="other" rel="nofollow" href="http://www.cs.cornell.edu/nystrom/">Nate Nystrom</a></td>
<td><a target="other" href="http://www.cs.purdue.edu/homes/hosking/bloat/">Bloat</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://sourceforge.net/users/hchacha/">Hidetoshi Ohuchi</a></td>
<td><a target="other" href="http://jarg.sourceforge.net/">Jarg</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (BSD)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.geocities.com/CapeCanaveral/Hall/2334/resume.html">Alexander Shvets</a></td>
-<td><a target="other" href="http://www.geocities.com/CapeCanaveral/Hall/2334/Programs/cafebabe.html">CafeBabe</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Free</td>
-</tr>
-
-<tr>
<td><a target="other" rel="nofollow" href="http://www.yworks.com/">yWorks</a></td>
<td><a target="other" href="http://www.yworks.com/en/products_yguard_about.htm">yGuard</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (no source)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.cs.purdue.edu/homes/grothoff/">Christian Grothoff</a></td>
-<td><a target="other" href="http://www.ovmj.org/jamit/">Jamit</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td>Free (GPL)</td>
-</tr>
-
-<tr>
<td><a target="other" rel="nofollow" href="http://mojo.codehaus.org/">Mojo</a></td>
<td><a target="other" href="http://mojo.codehaus.org/minijar-maven-plugin/">Minijar</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (Apache)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.riggshill.com/">RiggsHill Software</a></td>
<td><a target="other" href="http://genjar.sourceforge.net/">GenJar</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (Apache)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://ant.apache.org/">Apache</a></td>
-<td><a target="other" href="http://ant.apache.org/manual/OptionalTypes/classfileset.html">Ant Classfileset</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td><a target="other" href="http://ant.apache.org/manual/Types/classfileset.html">Ant Classfileset</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (Apache)</td>
</tr>
<tr>
+<td><a target="other" rel="nofollow" href="http://www.celton.mobi/">Carsten Elton Sørensen</a></td>
+<td><a target="other" href="http://code.google.com/p/treeshaker/">Treeshaker</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td>Free (Apache)</td>
+</tr>
+
+<tr>
+<td><a target="other" rel="nofollow" href="http://www.ucdetector.org/">Jörg Spieler</a></td>
+<td><a target="other" href="http://www.ucdetector.org/">UCDetector</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td>Free (EPL)</td>
+</tr>
+
+<tr>
<td><a target="other" rel="nofollow" href="http://www.curious-creature.org/">Romain Guy</a></td>
<td><a target="other" href="http://www.jroller.com/gfx/entry/get_what_you_need_from">Harvester</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (BSD)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="https://dcd.dev.java.net/">Emeric Vernat</a></td>
-<td><a target="other" href="https://dcd.dev.java.net/">DCD</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://java.net/projects/dcd/">Emeric Vernat</a></td>
+<td><a target="other" href="http://java.net/projects/dcd/">DCD</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (LGPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://sadun-util.sourceforge.net/">Cristiano Sadun</a></td>
<td><a target="other" href="http://sadun-util.sourceforge.net/pack.html">Pack</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td>Free (LGPL)</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://darcs.brianweb.net/">Brian Alliet</a></td>
-<td><a target="other" href="http://darcs.brianweb.net/gcclass/">Gcclass</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (LGPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.sable.mcgill.ca/">Sable</a></td>
<td><a target="other" href="http://www.sable.mcgill.ca/soot/">Soot</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free (LGPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.garret.ru/~knizhnik/">Konstantin Knizhnik</a></td>
<td><a target="other" href="http://www.garret.ru/~knizhnik/javago/ReadMe.htm">JavaGO</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td>Free</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://donquixote.cafebabe.jp/">Haruaki Tamada</a></td>
-<td><a target="other" href="http://donquixote.cafebabe.jp/">DonQuixote</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Free</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.sable.mcgill.ca/">Sable</a></td>
<td><a target="other" href="http://www.sable.mcgill.ca/JBCO/">JBCO</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (LGPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://sourceforge.net/users/glurk/">Thorsten Heit</a></td>
<td><a target="other" href="http://sourceforge.net/projects/javaguard/">JavaGuard</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (LGPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://mwobfu.sourceforge.net/">Patrick Mueller</a></td>
<td><a target="other" href="http://mwobfu.sourceforge.net/">Mwobfu</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (GPL)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.elegant-software.com/">Elegant Software</a></td>
-<td><a target="other" href="http://www.elegant-software.com/software/jmangle/">JMangle</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Free</td>
-</tr>
-
-<tr>
<td><a target="other" rel="nofollow" href="http://www.bebbosoft.de/">BebboSoft</a></td>
-<td><a target="other" href="http://www.bebbosoft.de/index.html#java/mug/index.html">Bb_mug</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" href="http://www.bebbosoft.de/#java/mug/index.wiki">Bb_mug</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free (no source)</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.drjava.de/">Dr. Java</a></td>
-<td><a target="other" href="http://www.drjava.de/obfuscator/">Marvin Obfuscator</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Free (no source)</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.ibm.com/">IBM</a></td>
-<td><a target="other" href="http://www-306.ibm.com/software/wireless/wsdd/">WSDD</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
+<td><a target="other" rel="nofollow" href="http://github.com/v6ak">Vít Šesták</a></td>
+<td><a target="other" href="http://github.com/v6ak/Preverifier/">Preverifier</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td>Free (EPL)</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.preemptive.com/">PreEmptive</a></td>
<td><a target="other" href="http://www.preemptive.com/products/dasho/index.html">DashOPro</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.zelix.com/">Zelix</a></td>
<td><a target="other" href="http://www.zelix.com/klassmaster/index.html">KlassMaster</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.s5systems.com/">S5 Systems</a></td>
-<td><a target="other" href="http://www.s5systems.com/jPresto.htm">jPresto</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.s-cradle.com/english/index.html">Sophia Cradle</a></td>
<td><a target="other" href="http://www.s-cradle.com/english/products/sophiacompress_java/index.html">SophiaCompress</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.retrologic.com/">RetroLogic</a></td>
-<td><a target="other" href="http://www.retrologic.com/">RetroGuard</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.codingart.com/">CodingArt</a></td>
-<td><a target="other" href="http://www.codingart.com/codeshield.html">CodeShield</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.e-t.com/">Eastridge Technology</a></td>
<td><a target="other" href="http://www.e-t.com/jshrink.html">Jshrink</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.helseth.com/">Helseth</a></td>
-<td><a target="other" href="http://www.helseth.com/HJO.htm">JObfuscator</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.leesw.com/">LeeSoftware</a></td>
<td><a target="other" href="http://www.leesw.com/">Smokescreen Obfuscator</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.vegatech.com/">Vega Technologies</a></td>
-<td><a target="other" href="http://www.vegatech.com/jzipper/">JZipper</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.innaworks.com/">Innaworks</a></td>
-<td><a target="other" href="http://www.innaworks.com/">mBooster</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td><a target="other" href="http://www.innaworks.com/mBooster">mBooster</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.uni-vologda.ac.ru/~c3c/">Sergey Sverdlov</a></td>
<td><a target="other" href="http://www.uni-vologda.ac.ru/~c3c/jco/">J.Class Optimizer</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.smardec.com/">Smardec</a></td>
-<td><a target="other" href="//www.allatori.com/">Allatori</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" href="http://www.allatori.com/">Allatori</a></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://cs.arizona.edu/">U. of Arizona</a></td>
<td><a target="other" href="http://sandmark.cs.arizona.edu/">SandMark</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.force5.com/">Force 5</a></td>
-<td><a target="other" href="http://www.force5.com/">JCloak</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" href="http://www.force5.com/JCloak/ProductJCloak.html">JCloak</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.semdesigns.com/">Semantic Designs</a></td>
<td><a target="other" href="http://www.semdesigns.com/Products/Obfuscators/JavaObfuscator.html">Obfuscator</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
<td><a target="other" rel="nofollow" href="http://www.duckware.com/">Duckware</a></td>
<td><a target="other" href="http://www.duckware.com/jobfuscate/">Jobfuscate</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.jproof.com/">JProof</a></td>
-<td><a target="other" href="http://www.jproof.com/">JProof</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://www.arxan.com/">Arxan</a></td>
+<td><a target="other" href="http://www.arxan.com/software-protection-products/java-GuardIt/index.php">GuardIT</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial</td>
</tr>
<tr>
-<td><a target="other" rel="nofollow" href="http://www.solutia.ro/">GITS</a></td>
-<td><a target="other" href="http://www.solutia.ro/pages/javadc/">Blurfuscator</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.chainkey.com/">ChainKey</a></td>
-<td><a target="other" href="http://www.chainkey.com/en/jcp/">Java Code Protector</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://sourceforge.net/projects/flmobf/">Alain Moran</a></td>
-<td><a target="other" href="http://sourceforge.net/projects/flmobf/">flmObf</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td>Free (BSD)</td>
-</tr>
-
-<tr>
<td><a target="other" rel="nofollow" href="http://www.chez.com/vasile/">Vasile Calmatui</a></td>
<td><a target="other" href="http://www.chez.com/vasile/obfu/VasObfuLite.html">VasObfuLite</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Free</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.alphaworks.ibm.com/">IBM AlphaWorks</a></td>
<td><a target="other" href="http://www.research.ibm.com/jax/">JAX</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>(discontinued)</td>
</tr>
<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.nq4.de/">NQ4</a></td>
+<td><a target="other" rel="nofollow" href="http://www.nq4.de/">Joga</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>(discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www-i2.informatik.rwth-aachen.de/~markusj/">Markus Jansen</a></td>
<td><a target="other" rel="nofollow" href="http://www-i2.informatik.rwth-aachen.de/~markusj/jopt/">Jopt</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>(disappeared?)</td>
</tr>
<tr class="disappeared">
-<td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Eron Jokipii</a></td>
-<td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Jobe</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://www.geocities.com/CapeCanaveral/Hall/2334/resume.html">Alexander Shvets</a></td>
+<td><a target="other" rel="nofollow" href="http://www.geocities.com/CapeCanaveral/Hall/2334/Programs/cafebabe.html">CafeBabe</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>(disappeared?)</td>
</tr>
<tr class="disappeared">
-<td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/">JRC</a></td>
-<td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/decaf/">DeCaf</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://darcs.brianweb.net/">Brian Alliet</a></td>
+<td><a target="other" rel="nofollow" href="http://darcs.brianweb.net/gcclass/">Gcclass</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.cs.purdue.edu/homes/grothoff/">Christian Grothoff</a></td>
+<td><a target="other" rel="nofollow" href="http://www.ovmj.org/jamit/">Jamit</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://donquixote.cafebabe.jp/">Haruaki Tamada</a></td>
+<td><a target="other" rel="nofollow" href="http://donquixote.cafebabe.jp/">DonQuixote</a></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>(disappeared?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/">Bajie</a></td>
<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/jcmp/">JCMP</a></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>(disappeared?)</td>
</tr>
<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.elegant-software.com/">Elegant Software</a></td>
+<td><a target="other" rel="nofollow" href="http://www.elegant-software.com/software/jmangle/">JMangle</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Eron Jokipii</a></td>
+<td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Jobe</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/">JRC</a></td>
+<td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/decaf/">DeCaf</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.drjava.de/">Dr. Java</a></td>
+<td><a target="other" rel="nofollow" href="http://www.drjava.de/obfuscator/">Marvin Obfuscator</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.ibm.com/">IBM</a></td>
+<td><a target="other" rel="nofollow" href="http://www-306.ibm.com/software/wireless/wsdd/">WSDD</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.s5systems.com/">S5 Systems</a></td>
+<td><a target="other" rel="nofollow" href="http://www.s5systems.com/jPresto.htm">jPresto</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.plumbdesign.com/">Plumb Design</a></td>
<td><a target="other" rel="nofollow" href="http://www.condensity.com/">Condensity</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.4thpass.com/">4th Pass</a></td>
<td><a target="other" rel="nofollow" href="http://www.4thpass.com/">SourceGuard</a></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.codingart.com/">CodingArt</a></td>
+<td><a target="other" rel="nofollow" href="http://www.codingart.com/codeshield.html">CodeShield</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.software4j.com/">Software4j</a></td>
<td><a target="other" rel="nofollow" href="http://www.software4j.com/obfuscate4j/">Obfuscate4j</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/">JAMM Consulting</a></td>
<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/jamm/servlet/com.jammconsulting.servlet.JAMMServlet?pageId=ObfuscateProPage">ObfuscatePro</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/">JDevelop</a></td>
<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/best-java-obfuscator.html">JSCO</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.4fang.net/">4Fang</a></td>
<td><a target="other" rel="nofollow" href="http://www.4fang.net/jmix/">JMix</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (discontinued?)</td>
</tr>
<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.retrologic.com/">RetroLogic</a></td>
+<td><a target="other" rel="nofollow" href="http://www.retrologic.com/">RetroGuard</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.helseth.com/">Helseth</a></td>
+<td><a target="other" rel="nofollow" href="http://www.helseth.com/HJO.htm">JObfuscator</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.vegatech.com/">Vega Technologies</a></td>
+<td><a target="other" rel="nofollow" href="http://www.vegatech.com/jzipper/">JZipper</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.jproof.com/">JProof</a></td>
+<td><a target="other" rel="nofollow" href="http://www.jproof.com/">JProof</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.chainkey.com/">ChainKey</a></td>
+<td><a target="other" rel="nofollow" href="http://www.chainkey.com/en/jcp/">Java Code Protector</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.2lkit.com/">2LKit</a></td>
<td><a target="other" rel="nofollow" href="http://www.2lkit.com/products/2LKitObf/index.htm">2LKit Obfuscator</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (disappeared?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/">WingSoft</a></td>
<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/wingguard.html">WingGuard</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (disappeared?)</td>
</tr>
<tr class="disappeared">
<td><a target="other" rel="nofollow" href="http://www.sbktech.org/">HashJava</a></td>
<td><a target="other" rel="nofollow" href="http://www.sbktech.org/">HashJava</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><br></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.solutia.ro/">GITS</a></td>
+<td><a target="other" rel="nofollow" href="http://www.solutia.ro/pages/javadc/">Blurfuscator</a></td>
+<td align="center"><br /></td>
+<td align="center"><br /></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x" /></td>
+<td align="center"><br /></td>
<td>Commercial (disappeared?)</td>
</tr>
@@ -647,10 +688,11 @@
<p>
All trademarks are property of their respective holders.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/downloads.html b/docs/downloads.html
index ebd1b28..e322ca6 100644
--- a/docs/downloads.html
+++ b/docs/downloads.html
@@ -1,11 +1,22 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Downloads</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -44,6 +55,96 @@
collected since the previous release.
<p>
+<h3><div>Dec 2011</div> Version 4.7</h3>
+<ul>
+<li>Added support for Java 7.
+<li>Parsing unquoted file names with special characters more leniently.
+<li>Added support for instance methods overriding class methods.
+<li>Added removal of unused parameterless constructors.
+<li>Added removal of empty class initializers.
+<li>Added peephole optimizations for constant strings.
+<li>Avoiding idle optimization passes.
+<li>Improved removal of unused constants after obfuscation.
+<li>Fixed removal of unused classes referenced by annotations.
+<li>Fixed simplifying parameters of constructors that should actually be
+ preserved.
+<li>Fixed simplifying parameters of large numbers of similar constructors.
+<li>Fixed exceptions in optimization of unusual obfuscated code.
+<li>Fixed NullPointerException when specifying <code>-keepclassmembers</code>
+ without specific class or class members.
+<li>Fixed potential problems with mixed-case class name dictionaries when not
+ allowing mixed-case class names.
+<li>Fixed obfuscation of classes with EnclosingMethod attributes that don't
+ specify methods.
+<li>Fixed preverification of returning try blocks with finally blocks, inside
+ try blocks, when compiled with JDK 1.4.
+<li>Fixed sorting of interfaces containing generics.
+<li>Fixed paths in shell scripts.
+<li>Fixed filling in of text fields showing class obfuscation dictionary and
+ package obfuscation dictionary from configuration in GUI.
+<li>Worked around Oracle Java 6/7 bug #7027598 that locked the GUI on Linux.
+<li>Updated documentation and examples.
+</ul>
+
+<h3><div>Feb 2011</div> Version 4.6</h3>
+<ul>
+<li>Added support for synthetic, bridge, and varargs modifiers in configuration.
+<li>Added detection of atomic updater construction with constant arguments.
+<li>Fixed merging of package visible classes.
+<li>Fixed optimization of fields that are only accessed by reflection.
+<li>Fixed optimization of read-only or write-only fields that are volatile.
+<li>Fixed handling of side-effects due to static initializers.
+<li>Fixed handling of bridge flags in obfuscation step.
+<li>Fixed handling of super flag when merging classes.
+<li>Fixed updating of variable tables when optimizing variables.
+<li>Fixed removal of unused parameters with 32 or more parameters.
+<li>Fixed incorrect removal of exception handler for instanceof instruction.
+<li>Fixed inlining of methods with unusual exception handlers.
+<li>Fixed optimization of unusual code causing stack underflow.
+<li>Fixed keeping of constructor parameter names.
+<li>Fixed unwanted wrapping of non-standard META-INF files.
+<li>Fixed filtering of warnings about references to array types.
+<li>Fixed overriding of warning option and note option in Ant task.
+<li>Improved detection of file name extensions for canonical paths.
+<li>Improved printing of seeds specified by <code>-keep</code> options.
+<li>Improved printing of notes about unkept classes.
+<li>Improved checking whether output is up to date.
+<li>Updated documentation and examples.
+</ul>
+
+<h3><div>Jun 2010</div> Version 4.5</h3>
+<ul>
+<li>Added option <code>-keepparameternames</code>.
+<li><code>-dontskipnonpubliclibraryclasses</code> is now set by default. Added
+ <code>-skipnonpubliclibraryclasses</code> as an option.
+<li>Made processing independent of order of input classes to get even more
+ deterministic output.
+<li>Improved constant field propagation.
+<li>Improved renaming of resource files in subdirectories of packages.
+<li>Avoiding making fields in interfaces private.
+<li>Optimizing exception handlers for monitorexit instruction.
+<li>Reduced maximum allowed code length after inlining from 8000 bytes to
+ 7000 bytes.
+<li>Fixed missing warnings about missing library classes.
+<li>Fixed shrinking of annotations with arrays of length 0.
+<li>Fixed handling of -0.0 and NaN values when simplifying expressions.
+<li>Fixed copying of exception handlers when simplifying tail recursion calls.
+<li>Fixed optimization of introspected fields.
+<li>Fixed simplification of unnecessary variable initializations.
+<li>Fixed evaluation of subroutines in pre-JDK 1.5 code.
+<li>Fixed updating of access flags in inner classes information.
+<li>Fixed disabling of field privatization.
+<li>Fixed invocations of privatized methods.
+<li>Fixed updating of local variable debug information in optimization step.
+<li>Fixed print settings without file name in GUI.
+<li>Fixed field privatization setting in GUI.
+<li>Fixed saving incorrectly quoted arguments in GUI.
+<li>Fixed handling of regular expressions with only negators.
+<li>Fixed unwanted wrapping of non-standard META-INF files.
+<li>Fixed regular expression pattern for constructors in ReTrace.
+<li>Updated documentation and examples.
+</ul>
+
<h3><div>Jul 2009</div> Version 4.4</h3>
<ul>
<li>Added new peephole optimizations.
@@ -511,10 +612,11 @@
<b>RetroGuard</b>.
</ul>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/feedback.html b/docs/feedback.html
index a7e770b..197fc33 100644
--- a/docs/feedback.html
+++ b/docs/feedback.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -6,6 +6,17 @@
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Feedback</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -13,28 +24,32 @@
By now, I've invested a fair amount of time in <b>ProGuard</b>. You can help
by providing feedback! If you have problems, bugs, bug fixes, ideas,
-encouragements, etc., please let me know:
+encouragements, etc., please get in touch:
<p>
-<ul>
-<li>The <a href="http://sourceforge.net/forum/forum.php?forum_id=182456"
+<ul class="spacious">
+<li>Through
+ <a href="http://www.saikoa.com/proguard/support" target="_top">Saikoa</a>,
+ we provide professional support for ProGuard. If you find ProGuard useful
+ and you would like to have some professional backing, this is the place to
+ go.</li>
+
+<li>The <a href="https://sourceforge.net/projects/proguard/forums/forum/182456"
target="other">help forum</a> (at SourceForge) is the right place to ask
questions about any problems you might have configuring and running
- <b>ProGuard</b>.
- <p>
+ ProGuard. At this time, I can generally only assist other open source
+ projects though. If you're working on commercial software, please consider
+ our professional support above.</li>
-<li>The <a href="http://sourceforge.net/forum/forum.php?forum_id=182455"
+<li>The <a href="https://sourceforge.net/projects/proguard/forums/forum/182455"
target="other">open discussion forum</a> (at SourceForge) offers a place
- to share your thoughts and discuss new ideas.
- <p>
+ to share your thoughts and discuss new ideas.</li>
<li>The <a
-
href="http://sourceforge.net/tracker/?atid=474704&group_id=54750&func=browse"
target="other">bug tracking page</a> (at SourceForge) allows you to submit
and consult bug reports. Please make sure the reports are complete and
concise. If I can't reproduce the problem, I most likely can't fix it
- either.
- <p>
+ either.</li>
<li>The <a
@@ -42,16 +57,14 @@
target="other">feature request page</a> (at SourceForge) allows you to
submit and consult feature requests. I generally have my own road map in
mind, but this is the place express your interest in new and existing
- ideas.
- <p>
+ ideas.</li>
-<li>The <a href="http://sourceforge.net/project/showfiles.php?group_id=54750"
+<li>The <a href="https://sourceforge.net/projects/proguard/files/"
target="other">download section</a> at SourceForge and the <a
href="http://software.freshmeat.net/projects/proguard/"
target="other">project page</a> at FreshMeat offer the possibility to
subscribe to the announcements of new releases. They are the most
- efficient way to stay abreast of the latest developments.
- <p>
+ efficient way to stay abreast of the latest developments.</li>
<li>For anything that doesn't fall in the above categories, you can mail me
directly at
@@ -84,7 +97,7 @@
<em>or</em> at
< eric @ graphics . cornell . edu > (please remove the spaces)
</noscript>
-.
+.</li>
</ul>
<p>
I can't promise a swift answer, or any answer at all, for that matter, but I
@@ -96,10 +109,11 @@
do things my way, without the overhead and compromises associated with larger
projects.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/index.html b/docs/index.html
index 771bb6a..866fc3d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -11,18 +11,34 @@
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<title>ProGuard</title>
</head>
+
+<script type="text/javascript" language="JavaScript">
+<!--
+var main="main.html";
+if (window.location.hash.length > 1)
+ main=window.location.hash.substr(1);
+var sections="sections.html";
+if (main.search(/manual\//) >= 0)
+ sections="manual/sections.html";
+
+document.write("<frameset rows=\"50,*\" framespacing=\"0\" frameborder=\"no\"><frame id=\"title\" name=\"title\" src=\"title.html\" scrolling=\"no\" marginwidth=\"0\" marginheight=\"0\" noresize /><frameset cols=\"120,*\" framespacing=\"0\" frameborder=\"no\"><frame id=\"sections\" name=\"sections\" src=\""+sections+"\" scrolling=\"no\" marginwidth=\"0\" marginheight=\"0\" noresize /><frame id=\"main\" name=\"main\" src=\""+main+"\" scrolling=\"auto\" marginwidth=\"10\" marginheight=\"10\" noresize /></frameset></frameset>");
+//-->
+</script>
+
+<noscript>
<frameset
rows="50,*"
framespacing="0"
frameborder="no">
<frame
+ id="title"
name="title"
src="title.html"
scrolling="no"
marginwidth="0"
marginheight="0"
- noresize>
+ noresize />
<frameset
cols="120,*"
@@ -30,42 +46,46 @@
frameborder="no">
<frame
+ id="sections"
name="sections"
src="sections.html"
scrolling="no"
marginwidth="0"
marginheight="0"
- noresize>
+ noresize />
<frame
+ id="main"
name="main"
src="main.html"
scrolling="auto"
marginwidth="10"
marginheight="10"
- noresize>
+ noresize />
</frameset>
</frameset>
+</noscript>
<noframes>
<body>
<p class="intro">
-<b>ProGuard</b> is a free Java class file shrinker, optimizer, and obfuscator.
-It can detect and remove unused classes, fields, methods, and attributes. It
-can then optimize bytecode and remove unused instructions. Finally, it can
-rename the remaining classes, fields, and methods using short meaningless
-names. The resulting jars are smaller and harder to reverse-engineer.
+<b>ProGuard</b> is a free Java class file shrinker, optimizer, obfuscator, and
+preverifier. It detects and removes unused classes, fields, methods, and
+attributes. It optimizes bytecode and removes unused instructions. It renames
+the remaining classes, fields, and methods using short meaningless names.
+Finally, it preverifies the processed code for Java 6 or for Java Micro
+Edition.
</p>
<p>
Your browser doesn't support frames, but that's cool.
<p>
You can go straight to the <a href="main.html">main page</a>.
-<hr>
+<hr />
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</noframes>
diff --git a/docs/license.html b/docs/license.html
index b4654fd..0a10092 100644
--- a/docs/license.html
+++ b/docs/license.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard License</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -29,19 +40,21 @@
exception</a> to the latter clause (in wording suggested by
the <a href="http://www.gnu.org/copyleft/gpl-faq.html#GPLIncompatibleLibs"
target="other">FSF</a>), for combinations with the following stand-alone
-applications: Apache Ant, Apache Maven, the Eclipse ProGuardDT GUI, the
-EclipseME JME IDE, the Sun NetBeans Java IDE, the Sun JME Wireless Toolkit,
-and the Javaground Tools.
+applications: Apache Ant, Apache Maven, the Google Android SDK, the Eclipse
+ProGuardDT GUI, the EclipseME JME IDE, the Oracle NetBeans Java IDE, the Oracle
+JME Wireless Toolkit, the Simple Build Tool for Scala, the NeoMAD Tools by
+Neomades, the Javaground Tools, and the Sanaware Tools.
<p>
The <b>ProGuard user documentation</b> represents an important part of this
work. It may only be redistributed without changes, along with the unmodified
version of the code.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/luciadlogo.png b/docs/luciadlogo.png
deleted file mode 100644
index 0147ce3..0000000
--- a/docs/luciadlogo.png
+++ /dev/null
Binary files differ
diff --git a/docs/main.html b/docs/main.html
index e988c79..0a89673 100644
--- a/docs/main.html
+++ b/docs/main.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -8,6 +8,16 @@
<meta name="keywords" content="java obfuscator, optimizer, shrinker, preverfier">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Main</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ if (window.top.location.hash!="")
+ window.top.location.hash="";
+}
+//-->
+</script>
</head>
<body>
@@ -25,25 +35,21 @@
<ul>
<li>Creating more compact code, for smaller code archives, faster transfer
- across networks, faster loading, and smaller memory footprints.
+ across networks, faster loading, and smaller memory footprints.</li>
-<li>Making programs and libraries harder to reverse-engineer.
+<li>Making programs and libraries harder to reverse-engineer.</li>
-<li>Listing dead code, so it can be removed from the source code.
+<li>Listing dead code, so it can be removed from the source code.</li>
<li>Retargeting and preverifying existing class files for Java 6, to take full
- advantage of Java 6's faster class loading.
+ advantage of Java 6's faster class loading.</li>
</ul>
<p>
<b>ProGuard</b>'s main advantage compared to other Java obfuscators is
probably its compact template-based configuration. A few intuitive command
-line options or a simple configuration file are usually sufficient. For
-instance, the following configuration option preserves all applets in a jar:
-<pre>
- -keep public class * extends java.applet.Applet
-</pre>
-The user manual explains all available options and shows more examples of this
+line options or a simple configuration file are usually sufficient.
+The user manual explains all available options and shows examples of this
powerful configuration style.
<p>
<b>ProGuard</b> is fast. It only takes seconds to process programs and
@@ -55,38 +61,42 @@
Toolkit.
<p>
<p class="intro">
-Version 4.0 introduced preverification and more bytecode optimizations. Please
-report any problems, so they can be fixed soon.
+<b>ProGuard</b> is being used in various development contexts, ranging from
+small Android apps to large Java applications and libraries. Its user base is
+continuing to grow at a fast pace. In order to better manage the many
+questions and requests, we are now providing professional support at
+<a target="_top" href="http://www.saikoa.com/proguard/support">Saikoa</a>.
</p>
The following sections provide more detailed information:
<ul>
-<li><a href="main.html">Main</a>: this overview page.
+<li><a href="main.html">Main</a>: this overview page.</li>
<li><a href="results.html">Results</a>: some results obtained with
- <b>ProGuard</b>, including timings and memory usage.
-<li><a href="FAQ.html">FAQ</a>: answers to some Frequently Asked Questions.
+ <b>ProGuard</b>, including timings and memory usage.</li>
+<li><a href="FAQ.html">FAQ</a>: answers to some Frequently Asked Questions.</li>
<li><a href="manual/index.html">Manual</a>: the complete <b>ProGuard</b> user
- manual, with examples and troubleshooting tips.
+ manual, with examples and troubleshooting tips.</li>
<li><a href="quality.html">Quality</a>: a discussion of the (excellent) quality
- of <b>ProGuard</b>'s code.
-<li><a href="screenshots.html">Screenshots</a>: some impressions of what <b>ProGuard</b> looks like.
+ of <b>ProGuard</b>'s code.</li>
+<li><a href="screenshots.html">Screenshots</a>: some impressions of what <b>ProGuard</b> looks like.</li>
<li><a href="testimonials.html">Testimonials</a>: what users think of
- <b>ProGuard</b>.
+ <b>ProGuard</b>.</li>
<li><a href="license.html">License</a>: <b>ProGuard</b> is free, under a GPL
- license.
+ license.</li>
<li><a href="downloads.html">Downloads</a>: download the <b>ProGuard</b>
- package yourself.
+ package yourself.</li>
<li><a href="feedback.html">Feedback</a>: tell me about your experiences, or
- learn from others on our forums.
+ learn from others on our forums.</li>
<li><a href="acknowledgements.html">Acknowledgements</a>: people who have been
- helpful.
+ helpful.</li>
<li><a href="alternatives.html">Alternatives</a>: other Java obfuscators,
- optimizers, and shrinkers.
+ optimizers, and shrinkers.</li>
</ul>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/ant.html b/docs/manual/ant.html
index bc3a3b4..26c6853 100644
--- a/docs/manual/ant.html
+++ b/docs/manual/ant.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Ant Task</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -107,8 +118,7 @@
files in the <code>examples/ant</code> directory of the ProGuard distribution.
<p>
-<a name="proguard"> </a>
-<h2>Task Attributes and Nested Elements</h2>
+<h2><a name="proguard">Task Attributes and Nested Elements</a></h2>
The <code><b><proguard></b></code> task and the
<code><b><proguardconfiguration></b></code> task can have the following
@@ -124,9 +134,9 @@
href="#configuration_element"><code>configuration</code></a>
<i>element</i>.</dd>
-<dt><a href="usage.html#dontskipnonpubliclibraryclasses"><code><b>skipnonpubliclibraryclasses</b></code></a>
+<dt><a href="usage.html#skipnonpubliclibraryclasses"><code><b>skipnonpubliclibraryclasses</b></code></a>
= "<i>boolean</i>"
- (default = true)</dt>
+ (default = false)</dt>
<dd>Ignore non-public library classes.</dd>
<dt><a href="usage.html#dontskipnonpubliclibraryclassmembers"><code><b>skipnonpubliclibraryclassmembers</b></code></a>
@@ -242,6 +252,11 @@
<dd>Repackage all class files that are renamed into the single given
package.</dd>
+<dt><a href="usage.html#keepparameternames"><code><b>keepparameternames</b></code></a>
+ = "<i>boolean</i>"
+ (default = false)</dt>
+<dd>Keep the parameter names and types of methods that are kept.</dd>
+
<dt><a href="usage.html#renamesourcefileattribute"><code><b>renamesourcefileattribute</b></code></a>
= "<i>string</i>"
(default = none)</dt>
@@ -448,8 +463,7 @@
</dl>
-<a name="classpath"> </a>
-<h2>Class Path Attributes and Nested Elements</h2>
+<h2><a name="classpath">Class Path Attributes and Nested Elements</a></h2>
The jar tags are path tags, so they can have any of the path attributes (or
nested elements). The most common attributes are:
@@ -499,8 +513,7 @@
</dl>
-<a name="keepmodifier"> </a>
-<h2>Keep Modifier Attributes</h2>
+<h2><a name="keepmodifier">Keep Modifier Attributes</a></h2>
The keep tags can have the following <i>modifier</i> attributes:
@@ -526,8 +539,7 @@
</dl>
-<a name="classspecification"> </a>
-<h2>Class Specification Attributes and Nested Elements</h2>
+<h2><a name="classspecification">Class Specification Attributes and Nested Elements</a></h2>
The keep tags can have the following <i>class_specification</i> attributes and
<i>class_member_specifications</i> nested elements:
@@ -538,6 +550,10 @@
<dd>The optional access modifiers of the class. Any space-separated list of
"public", "final", and "abstract", with optional negators "!".</dd>
+<dt><code><b>annotation</b></code> = "<i>annotation_name</i>"</dt>
+<dd>The optional fully qualified name of an annotation of the class, with
+ optional wildcards.</dd>
+
<dt><code><b>type</b></code> = "<i>type</i>"</dt>
<dd>The optional type of the class: one of "class", "interface", or
"!interface".</dd>
@@ -546,6 +562,10 @@
<dd>The optional fully qualified name of the class, with optional
wildcards.</dd>
+<dt><code><b>extendsannotation</b></code> = "<i>annotation_name</i>"</dt>
+<dd>The optional fully qualified name of an annotation of the the class that
+ the specified classes must extend, with optional wildcards.</dd>
+
<dt><code><b>extends</b></code> = "<i>class_name</i>"</dt>
<dd>The optional fully qualified name of the class the specified classes
must extend, with optional wildcards.</dd>
@@ -571,8 +591,7 @@
</dl>
-<a name="classmemberspecification"> </a>
-<h2>Class Member Specification Attributes</h2>
+<h2><a name="classmemberspecification">Class Member Specification Attributes</a></h2>
The class member tags can have the following <i>class_member_specification</i>
attributes:
@@ -584,6 +603,10 @@
"public", "protected", "private", "static", etc., with optional negators
"!".</dd>
+<dt><code><b>annotation</b></code> = "<i>annotation_name</i>"</dt>
+<dd>The optional fully qualified name of an annotation of the class member,
+ with optional wildcards.</dd>
+
<dt><code><b>type</b></code> = "<i>type</i>"</dt>
<dd>The optional fully qualified type of the class member, with optional
wildcards. Not applicable for constructors, but required for methods for
@@ -601,10 +624,11 @@
</dl>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/examples.html b/docs/manual/examples.html
index 3f47fca..14e0758 100644
--- a/docs/manual/examples.html
+++ b/docs/manual/examples.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Examples</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -12,76 +23,82 @@
Some typical useful configurations:
<ol>
-<li><a href="#application">A typical application</a>
-<li><a href="#applet">A typical applet</a>
-<li><a href="#midlet">A typical midlet</a>
-<li><a href="#jcapplet">A typical Java Card applet</a>
-<li><a href="#xlet">A typical xlet</a>
-<li><a href="#androidapplication">A typical Android application</a>
-<li><a href="#library">A typical library</a>
-<li><a href="#applications">All possible applications in the input jars</a>
-<li><a href="#applets">All possible applets in the input jars</a>
-<li><a href="#midlets">All possible midlets in the input jars</a>
-<li><a href="#jcapplets">All possible Java Card applets in the input jars</a>
-<li><a href="#xlets">All possible xlets in the input jars</a>
-<li><a href="#androidapplications">All possible Android applications in the input jars</a>
-<li><a href="#servlets">All possible servlets in the input jars</a>
-<li><a href="#native">Processing native methods</a>
-<li><a href="#callback">Processing callback methods</a>
-<li><a href="#enumerations">Processing enumeration classes</a>
-<li><a href="#serializable">Processing serializable classes</a>
-<li><a href="#beans">Processing bean classes</a>
-<li><a href="#annotations">Processing annotations</a>
-<li><a href="#database">Processing database drivers</a>
-<li><a href="#componentui">Processing ComponentUI classes</a>
-<li><a href="#rmi">Processing RMI code</a>
-<li><a href="#resourcefiles">Processing resource files</a>
-<li><a href="#stacktrace">Producing useful obfuscated stack traces</a>
-<li><a href="#repackaging">Obfuscating package names</a>
-<li><a href="#restructuring">Restructuring the output archives</a>
-<li><a href="#filtering">Filtering the input and the output</a>
-<li><a href="#multiple">Processing multiple applications at once</a>
-<li><a href="#incremental">Incremental obfuscation</a>
-<li><a href="#microedition">Preverifying class files for Java Micro Edition</a>
-<li><a href="#upgrade">Upgrading class files to Java 6</a>
-<li><a href="#deadcode">Finding dead code</a>
-<li><a href="#structure">Printing out the internal structure of class files</a>
-<li><a href="#annotated">Using annotations to configure ProGuard</a>
+<li><a href="#application">A typical application</a></li>
+<li><a href="#applet">A typical applet</a></li>
+<li><a href="#midlet">A typical midlet</a></li>
+<li><a href="#jcapplet">A typical Java Card applet</a></li>
+<li><a href="#xlet">A typical xlet</a></li>
+<li><a href="#androidactivity">A simple Android activity</a></li>
+<li><a href="#androidapplication">A complete Android application</a></li>
+<li><a href="#library">A typical library</a></li>
+<li><a href="#applications">All possible applications in the input jars</a></li>
+<li><a href="#applets">All possible applets in the input jars</a></li>
+<li><a href="#midlets">All possible midlets in the input jars</a></li>
+<li><a href="#jcapplets">All possible Java Card applets in the input jars</a></li>
+<li><a href="#xlets">All possible xlets in the input jars</a></li>
+<li><a href="#servlets">All possible servlets in the input jars</a></li>
+<li><a href="#scala">Scala applications with the Scala runtime</a></li>
+<li><a href="#native">Processing native methods</a></li>
+<li><a href="#callback">Processing callback methods</a></li>
+<li><a href="#enumerations">Processing enumeration classes</a></li>
+<li><a href="#serializable">Processing serializable classes</a></li>
+<li><a href="#beans">Processing bean classes</a></li>
+<li><a href="#annotations">Processing annotations</a></li>
+<li><a href="#database">Processing database drivers</a></li>
+<li><a href="#componentui">Processing ComponentUI classes</a></li>
+<li><a href="#rmi">Processing RMI code</a></li>
+<li><a href="#resourcefiles">Processing resource files</a></li>
+<li><a href="#manifestfiles">Processing manifest files</a></li>
+<li><a href="#stacktrace">Producing useful obfuscated stack traces</a></li>
+<li><a href="#repackaging">Obfuscating package names</a></li>
+<li><a href="#restructuring">Restructuring the output archives</a></li>
+<li><a href="#filtering">Filtering the input and the output</a></li>
+<li><a href="#multiple">Processing multiple applications at once</a></li>
+<li><a href="#incremental">Incremental obfuscation</a></li>
+<li><a href="#microedition">Preverifying class files for Java Micro Edition</a></li>
+<li><a href="#upgrade">Upgrading class files to Java 6</a></li>
+<li><a href="#deadcode">Finding dead code</a></li>
+<li><a href="#structure">Printing out the internal structure of class files</a></li>
+<li><a href="#annotated">Using annotations to configure ProGuard</a></li>
</ol>
You can find some sample configuration files in the <code>examples</code>
directory of the ProGuard distribution.
-<a name="application"> </a>
-<h3>A typical application</h3>
-To shrink, optimize, and obfuscate the ProGuard application itself, one would
-typically create a configuration file <code>proguard.pro</code> and then type:
+<h3><a name="application">A typical application</a></h3>
+
+To shrink, optimize, and obfuscate a simple Java application, you typically
+create a configuration file like <code>myconfig.pro</code>, which can be used
+with
<pre>
-java -jar proguard.jar @proguard.pro
+bin/proguard @myconfig.pro
</pre>
<p>
-The configuration file would contain the following options:
+The configuration file specifies the input, the output, and the entry points
+of the application:
<pre>
--injars proguard.jar
--outjars proguard_out.jar
+-injars myapplication.jar
+-outjars myapplication_out.jar
-libraryjars <java.home>/lib/rt.jar
--printmapping proguard.map
+-printmapping myapplication.map
--keep public class proguard.ProGuard {
+-keep public class mypackage.MyMain {
public static void main(java.lang.String[]);
}
</pre>
<p>
-Note the use of the <code><java.home></code> system property; it is
-replaced automatically.
+Note the use of the <code><java.home></code> system property. ProGuard
+automatically replaces it when parsing the file.
<p>
-Also note that all type names are fully specified:
-<code>proguard.ProGuard</code> and <code>java.lang.String[]</code>.
-<p>
+The <a href="usage.html#keep"><code>-keep</code></a> option specifies the
+entry point of the application that has to be preserved.
The access modifiers <code>public</code> and <code>static</code> are not
really required in this case, since we know a priori that the specified class
and method have the proper access flags. It just looks more familiar this way.
<p>
+Note that all type names are fully specified:
+<code>mypackage.MyMain</code> and <code>java.lang.String[]</code>.
+<p>
We're writing out an obfuscation mapping file with <a
href="usage.html#printmapping"><code>-printmapping</code></a>, for
de-obfuscating any stack traces later on, or for incremental obfuscation of
@@ -103,11 +120,10 @@
<a href="#enumerations">enumerations</a>, <a href="#serializable">serializable
classes</a>, <a href="#beans">bean classes</a>, <a
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
-files</a>. For processing 'simple' applications like ProGuard, that is not
-required.
+files</a>.
-<a name="applet"> </a>
-<h3>A typical applet</h3>
+<h3><a name="applet">A typical applet</a></h3>
+
These options shrink, optimize, and obfuscate the applet
<code>mypackage.MyApplet</code>:
<pre>
@@ -129,15 +145,15 @@
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="midlet"> </a>
-<h3>A typical midlet</h3>
+<h3><a name="midlet">A typical midlet</a></h3>
+
These options shrink, optimize, obfuscate, and preverify the midlet
<code>mypackage.MyMIDlet</code>:
<pre>
-injars in.jar
-outjars out.jar
--libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
@@ -172,8 +188,8 @@
Note that you will still have to adapt the midlet jar size in the
corresponding jad file; ProGuard doesn't do that for you.
-<a name="jcapplet"> </a>
-<h3>A typical Java Card applet</h3>
+<h3><a name="jcapplet">A typical Java Card applet</a></h3>
+
These options shrink, optimize, and obfuscate the Java Card applet
<code>mypackage.MyApplet</code>:
<pre>
@@ -192,8 +208,8 @@
it now targets the Java Card run-time environment. This environment doesn't
have java.lang.Class, so we're telling ProGuard not to worry about it.
-<a name="xlet"> </a>
-<h3>A typical xlet</h3>
+<h3><a name="xlet">A typical xlet</a></h3>
+
These options shrink, optimize, and obfuscate the xlet
<code>mypackage.MyXlet</code>:
<pre>
@@ -212,15 +228,16 @@
The configuration is very similar to the configuration for midlets, except that
it now targets the CDC run-time environment with the Java TV API.
-<a name="androidapplication"> </a>
-<h3>A typical Android application</h3>
-These options shrink, optimize, and obfuscate the simple Android application
-based on a single activity <code>mypackage.MyActivity</code>:
+<h3><a name="androidactivity">A simple Android activity</a></h3>
+
+These options shrink, optimize, and obfuscate the single Android
+activity <code>mypackage.MyActivity</code>:
<pre>
--injars in.jar
--outjars out.jar
--libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
--overloadaggressively
+-injars bin/classes
+-outjars bin/classes-processed.jar
+-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar
+
+-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
@@ -228,27 +245,145 @@
-keep public class mypackage.MyActivity
</pre>
<p>
-The configuration is very similar to the configuration for midlets, except that
-it now targets the Android run-time environment.
+We're targeting the Android run-time and keeping the activity as an entry
+point.
+<p>
+Preverification is irrelevant for the dex compiler and the Dalvik VM, so we
+can switch it off with the
+<a href="usage.html#dontpreverify"><code>-dontpreverify</code></a> option.
<p>
The <a href="usage.html#optimizations"><code>-optimizations</code></a> option
disables some arithmetic simplifications that Dalvik 1.0 and 1.5 can't handle.
+Note that the Dalvik VM also can't
+handle <a href="usage.html#overloadaggressively">aggressive overloading</a>
+(of static fields).
<p>
If applicable, you should add options for processing <a href="#native">native
-methods</a>, <a href="#callback">callback methods</a>, and <a
-href="#resourcefiles">resource files</a>.
+methods</a>, <a href="#callback">callback methods</a>,
+<a href="#enumerations">enumerations</a>,
+<a href="#annotations">annotations</a>, and
+<a href="#resourcefiles">resource files</a>.
-<a name="library"> </a>
-<h3>A typical library</h3>
+<h3><a name="androidapplication">A complete Android application</a></h3>
+
+These options shrink, optimize, and obfuscate all public activities, services,
+broadcast receivers, and content providers from the compiled classes and
+external libraries:
+<pre>
+-injars bin/classes
+-injars libs
+-outjars bin/classes-processed.jar
+-libraryjars /usr/local/java/android-sdk/platforms/android-9/android.jar
+
+-dontpreverify
+-repackageclasses ''
+-allowaccessmodification
+-optimizations !code/simplification/arithmetic
+-keepattributes *Annotation*
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+
+-keep public class * extends android.view.View {
+ public <init>(android.content.Context);
+ public <init>(android.content.Context, android.util.AttributeSet);
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+ public void set*(...);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+-keepclassmembers class * implements android.os.Parcelable {
+ static android.os.Parcelable$Creator CREATOR;
+}
+
+-keepclassmembers class **.R$* {
+ public static <fields>;
+}
+</pre>
+<p>
+Most importantly, we're keeping all fundamental classes that may be referenced
+by the <code>AndroidManifest.xml</code> file of the application. If your
+manifest file contains other classes and methods, you may have to specify
+those as well.
+<p>
+We're keeping annotations, since they might be used by custom
+<code>RemoteViews</code>.
+<p>
+We're keeping any custom <code>View</code> extensions and other classes with
+typical constructors, since they might be referenced from XML layout files.
+<p>
+We're also keeping the required static fields in <code>Parcelable</code>
+implementations, since they are accessed by introspection.
+<p>
+Finally, we're keeping the static fields of referenced inner classes of
+auto-generated <code>R</code> classes, just in case your code is accessing
+those fields by introspection. Note that the compiler already inlines
+primitive fields, so ProGuard can generally remove all these classes entirely
+anyway (because the classes are not referenced and therefore not required).
+<p>
+If you're using additional Google APIs, you'll have to specify
+those as well, for instance:
+<pre>
+-libraryjars /usr/local/android-sdk/add-ons/google_apis-7_r01/libs/maps.jar
+</pre>
+<p>
+If you're using Google's optional License Verification Library, you can
+obfuscate its code along with your own code. You do have to preserve
+its <code>ILicensingService</code> interface for the library to work:
+<pre>
+-keep public interface com.android.vending.licensing.ILicensingService
+</pre>
+<p>
+If you're using the Android Compatibility library, you should add the
+following line, to let ProGuard know it's ok that the library references some
+classes that are not available in all versions of the API:
+<pre>
+-dontwarn android.support.**
+</pre>
+<p>
+If applicable, you should add options for processing <a href="#native">native
+methods</a>, <a href="#callback">callback methods</a>,
+<a href="#enumerations">enumerations</a>,
+and <a href="#resourcefiles">resource files</a>. You may also want to add
+options for producing <a href="#stacktrace">useful stack traces</a>. You can
+find a complete sample configuration in <code>examples/android.pro</code> in
+the ProGuard distribution.
+<p>
+The build process of the Android SDK (version 2.3 and higher) already
+integrates ProGuard by default. You only need to enable it (for release
+builds) by adding <code>proguard.config=proguard.cfg</code> to the file
+<code>build.properties</code>. In case of problems, you may want to check if
+the automatically generated file <code>proguard.cfg</code> contains the
+settings discussed above. The generated Ant build file already sets the input
+and output files for you.
+<p>
+For more information, you can consult the official <a target="other"
+href="http://developer.android.com/guide/developing/tools/proguard.html">Developer
+Guide</a> in the Android SDK.
+
+<h3><a name="library">A typical library</a></h3>
+
These options shrink, optimize, and obfuscate an entire library, keeping all
public and protected classes and class members, native method names, and
-serialization code:
+serialization code. The processed version of the library can then still be
+used as such, for developing code based on its public API.
<pre>
-injars in.jar
-outjars out.jar
-libraryjars <java.home>/lib/rt.jar
-printmapping out.map
+-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,*Annotation*,EnclosingMethod
@@ -273,6 +408,7 @@
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
@@ -289,12 +425,12 @@
href="usage.html#keepclassmembernames"><code>-keepclassmembernames</code></a>
option for the <code>class$</code> methods is not strictly necessary. These
methods are inserted by the <code>javac</code> compiler and the
-<code>jikes</code> compiler respectively, to implement the <code>.class</code>
-construct. ProGuard will automatically detect them and deal with them, even
-when their names have been obfuscated. However, older versions of ProGuard and
-other obfuscators may rely on the original method names. It may therefore be
-helpful to preserve them, in case these other obfuscators are ever used for
-further obfuscation of the library.
+<code>jikes</code> compiler respectively, in JDK 1.2 and older, to implement
+the <code>.class</code> construct. ProGuard will automatically detect them and
+deal with them, even when their names have been obfuscated. However, other
+obfuscators may rely on the original method names. It may therefore be helpful
+to preserve them, in case these other obfuscators are ever used for further
+obfuscation of the library.
<p>
The "Exceptions" attribute has to be preserved, so the compiler knows which
exceptions methods may throw.
@@ -307,6 +443,11 @@
The "Signature" attribute is required to be able to access generic types when
compiling in JDK 5.0 and higher.
<p>
+The <a href="usage.html#keepparameternames"><code>-keepparameternames</code></a>
+option keeps the parameter names in the "LocalVariableTable" and
+"LocalVariableTypeTable" attributes of public library methods. Some IDEs can
+present these names to the developers who use the library.
+<p>
Finally, we're keeping the "Deprecated" attribute and the attributes for
producing <a href="#stacktrace">useful stack traces</a>.
<p>
@@ -316,8 +457,8 @@
href="#annotations">annotations</a>, which are all discussed in their
respective examples.
-<a name="applications"> </a>
-<h3>All possible applications in the input jars</h3>
+<h3><a name="applications">All possible applications in the input jars</a></h3>
+
These options shrink, optimize, and obfuscate all public applications in
<code>in.jar</code>:
<pre>
@@ -347,8 +488,8 @@
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="applets"> </a>
-<h3>All possible applets in the input jars</h3>
+<h3><a name="applets">All possible applets in the input jars</a></h3>
+
These options shrink, optimize, and obfuscate all public applets in
<code>in.jar</code>:
<pre>
@@ -372,15 +513,15 @@
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="midlets"> </a>
-<h3>All possible midlets in the input jars</h3>
+<h3><a name="midlets">All possible midlets in the input jars</a></h3>
+
These options shrink, optimize, obfuscate, and preverify all public midlets in
<code>in.jar</code>:
<pre>
-injars in.jar
-outjars out.jar
--libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-overloadaggressively
-repackageclasses ''
-allowaccessmodification
@@ -412,8 +553,8 @@
Note that you will still have to adapt the midlet jar size in the
corresponding jad file; ProGuard doesn't do that for you.
-<a name="jcapplets"> </a>
-<h3>All possible Java Card applets in the input jars</h3>
+<h3><a name="jcapplets">All possible Java Card applets in the input jars</a></h3>
+
These options shrink, optimize, and obfuscate all public Java Card applets in
<code>in.jar</code>:
<pre>
@@ -435,8 +576,8 @@
The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
out which applets exactly will be preserved.
-<a name="xlets"> </a>
-<h3>All possible xlets in the input jars</h3>
+<h3><a name="xlets">All possible xlets in the input jars</a></h3>
+
These options shrink, optimize, and obfuscate all public xlets in
<code>in.jar</code>:
<pre>
@@ -458,38 +599,8 @@
The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
out which xlets exactly will be preserved.
-<a name="androidapplications"> </a>
-<h3>All possible Android applications in the input jars</h3>
-These options shrink, optimize, and obfuscate all public activities, services,
-broadcast receivers, and content providers in <code>in.jar</code>:
-<pre>
--injars in.jar
--outjars out.jar
--libraryjars /usr/local/java/android-1.5_r1/platforms/android-1.5/android.jar
--overloadaggressively
--repackageclasses ''
--allowaccessmodification
--optimizations !code/simplification/arithmetic
--printseeds
+<h3><a name="servlets">All possible servlets in the input jars</a></h3>
--keep public class * extends android.app.Activity
--keep public class * extends android.app.Service
--keep public class * extends android.content.BroadcastReceiver
--keep public class * extends android.content.ContentProvider
-</pre>
-<p>
-We're keeping all classes that extend the base classes that may be referenced
-by the <code>AndroidManifest.xml</code> file of the application.
-<p>
-The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
-out which implementations exactly will be preserved.
-<p>
-If applicable, you should add options for processing <a href="#native">native
-methods</a>, <a href="#callback">callback methods</a>, and <a
-href="#resourcefiles">resource files</a>.
-
-<a name="servlets"> </a>
-<h3>All possible servlets in the input jars</h3>
These options shrink, optimize, and obfuscate all public servlets in
<code>in.jar</code>:
<pre>
@@ -521,8 +632,77 @@
href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
files</a>.
-<a name="native"> </a>
-<h3>Processing native methods</h3>
+<h3><a name="scala">Scala applications with the Scala runtime</a></h3>
+
+These options shrink, optimize, and obfuscate all public Scala applications in
+<code>in.jar</code>:
+<pre>
+-injars in.jar
+-injars /usr/local/java/scala-2.9.1/lib/scala-library.jar
+-outjars out.jar
+-libraryjars <java.home>/lib/rt.jar
+
+-dontwarn scala.**
+
+-keepclasseswithmembers public class * {
+ public static void main(java.lang.String[]);
+}
+
+-keep class * implements org.xml.sax.EntityResolver
+
+-keepclassmembers class * {
+ ** MODULE$;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
+ long eventCount;
+ int workerCounts;
+ int runControl;
+ scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
+ scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
+ int base;
+ int sp;
+ int runState;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
+ int status;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue {
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
+}
+</pre>
+<p>
+The configuration is essentially the same as
+for <a href="#applications">processing applications</a>, because Scala is
+compiled to ordinary Java bytecode. However, the example processes the Scala
+runtime library as well. The processed jar can be an order of magnitude
+smaller and a few times faster than the original code (for the Scala code
+examples, for instance).
+<p>
+The <a href="usage.html#dontwarn"><code>-dontwarn</code></a> option tells
+ProGuard not to complain about some artefacts in the Scala runtime, the way it
+is compiled by the <code>scalac</code> compiler (at least in Scala 2.9.1 and
+older). Note that this option should always be used with care.
+<p>
+The additional <a href="usage.html#keepoverview"><code>-keep</code></a>
+options make sure that some classes and some fields that are accessed by means
+of introspection are not removed or renamed.
+<p>
+If applicable, you should add options for processing <a href="#native">native
+methods</a>, <a href="#callback">callback methods</a>, <a
+href="#enumerations">enumerations</a>, <a href="#serializable">serializable
+classes</a>, <a href="#beans">bean classes</a>, <a
+href="#annotations">annotations</a>, and <a href="#resourcefiles">resource
+files</a>.
+<h3><a name="native">Processing native methods</a></h3>
+
If your application, applet, servlet, library, etc., contains native methods,
you'll want to preserve their names and their classes' names, so they can
still be linked to the native library. The following additional option will
@@ -543,8 +723,8 @@
entry points, which you'll have to specify explicitly. <a
href="callback">Callback methods</a> are discussed below as a typical example.
-<a name="callback"> </a>
-<h3>Processing callback methods</h3>
+<h3><a name="callback">Processing callback methods</a></h3>
+
If your application, applet, servlet, library, etc., contains callback
methods, which are called from external code (native code, scripts,...),
you'll want to preserve them, and probably their classes too. They are just
@@ -559,8 +739,8 @@
<p>
This will preserve the given class and method from being removed or renamed.
-<a name="enumerations"> </a>
-<h3>Processing enumeration classes</h3>
+<h3><a name="enumerations">Processing enumeration classes</a></h3>
+
If your application, applet, servlet, library, etc., contains enumeration
classes, you'll have to preserve some special methods. Enumerations were
introduced in Java 5. The java compiler translates enumerations into classes
@@ -576,8 +756,8 @@
}
</pre>
-<a name="serializable"> </a>
-<h3>Processing serializable classes</h3>
+<h3><a name="serializable">Processing serializable classes</a></h3>
+
More complex applications, applets, servlets, libraries, etc., may contain
classes that are serialized. Depending on the way in which they are used, they
may require special attention:
@@ -589,6 +769,7 @@
<pre>
-keepclassmembers class * implements java.io.Serializable {
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
@@ -602,8 +783,7 @@
option makes sure that any serialization methods are kept. By using this
option instead of the basic <code>-keep</code> option, we're not
forcing preservation of <i>all</i> serializable classes, just preservation
- of the listed members of classes that are actually used.
- <p>
+ of the listed members of classes that are actually used.</li>
<li>Sometimes, the serialized data are stored, and read back later into newer
versions of the serializable classes. One then has to take care the classes
@@ -617,7 +797,7 @@
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
- static final java.io.ObjectStreamField[] serialPersistentFields;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
@@ -632,7 +812,7 @@
The <code><fields></code> line preserves all non-static,
non-transient fields, with their original names. The introspection of the
serialization process and the de-serialization process will then find
- consistent names.
+ consistent names.</li>
<li>Occasionally, the serialized data have to remain compatible, but the
classes involved lack <code>serialVersionUID</code> fields. I imagine the
@@ -651,7 +831,7 @@
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
- static final java.io.ObjectStreamField[] serialPersistentFields;
+ private static final java.io.ObjectStreamField[] serialPersistentFields;
!static !transient <fields>;
!private <fields>;
!private <methods>;
@@ -668,7 +848,7 @@
interfaces of the serializable classes (using something like "<code>-keep
interface MyInterface</code>"), since these names are also used when
computing the UID. A fast but sub-optimal alternative would be simply
- keeping all interfaces with "<code>-keep interface *</code>".
+ keeping all interfaces with "<code>-keep interface *</code>".</li>
</ul>
<p>
@@ -679,8 +859,8 @@
ever be serialized. Knowing your application and tuning the configuration
often produces more compact results.
-<a name="beans"> </a>
-<h3>Processing bean classes</h3>
+<h3><a name="beans">Processing bean classes</a></h3>
+
If your application, applet, servlet, library, etc., makes extensive use of
introspection on bean classes to find bean editor classes, or getter and
setter methods, then configuration may become painful. There's not much else
@@ -715,8 +895,8 @@
array or non-array). The methods with the '<code>int</code>' arguments matches
properties that are lists.
-<a name="annotations"> </a>
-<h3>Processing annotations</h3>
+<h3><a name="annotations">Processing annotations</a></h3>
+
If your application, applet, servlet, library, etc., uses annotations, you may
want to preserve them in the processed output. Annotations are represented by
attributes that have no direct effect on the execution of the code. However,
@@ -744,8 +924,8 @@
-keepattributes EnclosingMethod
</pre>
-<a name="database"> </a>
-<h3>Processing database drivers</h3>
+<h3><a name="database">Processing database drivers</a></h3>
+
Database drivers are implementations of the <code>Driver</code> interface.
Since they are often created dynamically, you may want to preserve any
implementations that you are processing as entry points:
@@ -758,8 +938,8 @@
instantiating a driver in your code (without necessarily implementing any
drivers yourself).
-<a name="componentui"> </a>
-<h3>Processing ComponentUI classes</h3>
+<h3><a name="componentui">Processing ComponentUI classes</a></h3>
+
Swing UI look and feels are implemented as extensions of the
<code>ComponentUI</code> class. For some reason, these have to contain a
static method <code>createUI</code>, which the Swing API invokes using
@@ -773,8 +953,8 @@
<p>
This option also keeps the classes themselves.
-<a name="rmi"> </a>
-<h3>Processing RMI code</h3>
+<h3><a name="rmi">Processing RMI code</a></h3>
+
Reportedly, the easiest way to handle RMI code is to process the code with
ProGuard first and then invoke the <code>rmic</code> tool. If that is not
possible, you may want to try something like this:
@@ -798,8 +978,8 @@
handling code performs introspection to check whether the method signatures
are compatible.
-<a name="resourcefiles"> </a>
-<h3>Processing resource files</h3>
+<h3><a name="resourcefiles">Processing resource files</a></h3>
+
If your application, applet, servlet, library, etc., contains resource files,
it may be necessary to adapt their names and/or their contents when the
application is obfuscated. The following two options can achieve this
@@ -818,8 +998,31 @@
replaces these names by the obfuscated names (if any). You'll probably want to
adapt the filters to suit your application.
-<a name="stacktrace"> </a>
-<h3>Producing useful obfuscated stack traces</h3>
+<h3><a name="manifestfiles">Processing manifest files</a></h3>
+
+As illustrated in the previous section, manifest files can be treated like
+ordinary resource files. ProGuard can adapt obfuscated class names in the
+files, but it won't make any other changes. If you want anything else, you
+should apply an external tool. For instance, if a manifest file contains
+signing information, you should sign the jar again after it has been
+processed.
+<p>
+If you're merging several input jars into a single output jar, you'll have to
+pick one, typically by specifying <a href="usage.html#filters">filters</a>:
+<pre>
+-injars in1.jar
+-injars in2.jar(!META-INF/MANIFEST.MF)
+-injars in3.jar(!META-INF/MANIFEST.MF)
+-outjars out.jar
+</pre>
+<p>
+The filters will let ProGuard copy the manifest file from the first jar and
+ignore any manifest files in the second and third input jars. Note that
+ProGuard will leave the order of the files in the jars unchanged; manifest
+files are not necessarily put first.
+
+<h3><a name="stacktrace">Producing useful obfuscated stack traces</a></h3>
+
These options let obfuscated applications or libraries produce stack traces
that can still be deciphered later on:
<pre>
@@ -844,8 +1047,8 @@
<code>out.map</code>. The information can then be used by the <a
href="retrace/index.html">ReTrace</a> tool to restore the original stack trace.
-<a name="repackaging"> </a>
-<h3>Obfuscating package names</h3>
+<h3><a name="repackaging">Obfuscating package names</a></h3>
+
Package names can be obfuscated in various ways, with increasing levels of
obfuscation and compactness. For example, consider the following classes:
<pre>
@@ -951,8 +1154,8 @@
all code. Notably, you may have to take into account that your application may
contain <a href="#resourcefiles">resource files</a> that have to be adapted.
-<a name="restructuring"> </a>
-<h3>Restructuring the output archives</h3>
+<h3><a name="restructuring">Restructuring the output archives</a></h3>
+
In simple applications, all output classes and resources files are merged into
a single jar. For example:
<pre>
@@ -1022,12 +1225,12 @@
always tries to package output archives in a sensible way, reconstructing the
input entries as much as required.
-<a name="filtering"> </a>
-<h3>Filtering the input and the output</h3>
+<h3><a name="filtering">Filtering the input and the output</a></h3>
-If you want even greater control, you can add filters to the input and the
-output, filtering out zips, ears, wars, jars, and/or ordinary files. For
-example, if you want to disregard certain files from an input jar:
+If you want even greater control, you can add
+<a href="usage.html#filters">filters</a> to the input and the output,
+filtering out zips, ears, wars, jars, and/or ordinary files. For example, if
+you want to disregard certain files from an input jar:
<pre>
-injars in.jar(!images/**)
-outjars out.jar
@@ -1080,10 +1283,10 @@
<code>resources_out.jar</code>.
<p>
Again, the filtering can be arbitrarily complex, especially when combined with
-the grouping of input and output.
+grouping input and output.
-<a name="multiple"> </a>
-<h3>Processing multiple applications at once</h3>
+<h3><a name="multiple">Processing multiple applications at once</a></h3>
+
You can process several dependent or independent applications (or applets,
midlets,...) in one go, in order to save time and effort. ProGuard's input and
output handling offers various ways to keep the output nicely structured.
@@ -1100,10 +1303,10 @@
</pre>
<p>
After processing, the directory <code>processed_applications</code> will
-contain the processed application jars, with their original names.
+contain processed versions of application jars, with their original names.
-<a name="incremental"> </a>
-<h3>Incremental obfuscation</h3>
+<h3><a name="incremental">Incremental obfuscation</a></h3>
+
After having <a href="#application">processed an application</a>, e.g.
ProGuard itself, you can still incrementally add other pieces of code that
depend on it, e.g. the ProGuard GUI:
@@ -1149,18 +1352,18 @@
}
</pre>
-<a name="microedition"> </a>
-<h3>Preverifying class files for Java Micro Edition</h3>
+<h3><a name="microedition">Preverifying class files for Java Micro Edition</a></h3>
+
Even if you're not interested in shrinking, optimizing, and obfuscating your
midlets, as shown in the <a href="#midlets">midlets example</a>, you can still
use ProGuard to preverify the class files for Java Micro Edition. ProGuard
-produces slightly more compact results compared to the traditional external
+produces slightly more compact results than the traditional external
preverifier.
<pre>
-injars in.jar
-outjars out.jar
--libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
-dontshrink
-dontoptimize
@@ -1175,8 +1378,8 @@
that we don't need any <code>-keep</code> options to specify entry points; all
class files are simply preverified.
-<a name="upgrade"> </a>
-<h3>Upgrading class files to Java 6</h3>
+<h3><a name="upgrade">Upgrading class files to Java 6</a></h3>
+
The following options upgrade class files to Java 6, by updating their
internal version numbers and preverifying them. The class files can then be
loaded more efficiently by the Java 6 Virtual Machine.
@@ -1198,8 +1401,8 @@
any <code>-keep</code> options to specify entry points; all class files are
simply updated and preverified.
-<a name="deadcode"> </a>
-<h3>Finding dead code</h3>
+<h3><a name="deadcode">Finding dead code</a></h3>
+
These options list unused classes, fields, and methods in the application
<code>mypackage.MyApplication</code>:
<pre>
@@ -1232,8 +1435,8 @@
}
</pre>
-<a name="structure"> </a>
-<h3>Printing out the internal structure of class files</h3>
+<h3><a name="structure">Printing out the internal structure of class files</a></h3>
+
These options print out the internal structure of all class files in the input
jar:
<pre>
@@ -1250,8 +1453,7 @@
Note how we don't need to specify the Java run-time jar, because we're not
processing the input jar at all.
-<a name="annotated"> </a>
-<h3>Using annotations to configure ProGuard</h3>
+<h3><a name="annotated">Using annotations to configure ProGuard</a></h3>
The traditional ProGuard configuration allows to keep a clean separation
between the code and the configuration for shrinking, optimization, and
@@ -1291,12 +1493,12 @@
<p>
The directory <code>examples/annotations</code> contains more examples that
illustrate some of the possibilities.
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/gui.html b/docs/manual/gui.html
index 37684a6..aa41b1b 100644
--- a/docs/manual/gui.html
+++ b/docs/manual/gui.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard GUI</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -57,8 +68,7 @@
href="introduction.html">Introduction</a> of this manual.
<p>
-<a name="proguard"> </a>
-<h2>The ProGuard Tab</h2>
+<h2><a name="proguard">The ProGuard Tab</a></h2>
The <i>ProGuard</i> tab presents a welcome message and one important button at
the bottom:
@@ -75,8 +85,7 @@
creating a new configuration from scratch.
<p>
-<a name="inputoutput"> </a>
-<h2>The Input/Output Tab</h2>
+<h2><a name="inputoutput">The Input/Output Tab</a></h2>
The <i>Input/Output</i> tab contains two lists, respectively to specify the
program jars (or wars, ears, zips, or directories), and the library jars (or
@@ -88,12 +97,12 @@
entries specify the destinations to which the processed results will be
written. They are preceded by arrows, to distinguish them from input
entries. The results of each consecutive list of input entries will be
- written to the subsequent consecutive list of output entries.
+ written to the subsequent consecutive list of output entries.</li>
<li>The library jars are not copied to the output jars; they contain class
files that are used by class files in the program jars and that are
necessary for correct processing. This list typically at least contains the
- targeted Java runtime jar.
+ targeted Java runtime jar.</li>
</ul>
<p>
@@ -145,16 +154,15 @@
Corresponding configuration options:
<ul type="none">
-<li>-<a href="usage.html#injars">injars</a>
-<li>-<a href="usage.html#outjars">outjars</a>
-<li>-<a href="usage.html#libraryjars">libraryjars</a>
-<li><a href="usage.html#classpath"><i>class_path</i></a>
-<li><a href="usage.html#filters"><i>filters</i></a>
+<li>-<a href="usage.html#injars">injars</a></li>
+<li>-<a href="usage.html#outjars">outjars</a></li>
+<li>-<a href="usage.html#libraryjars">libraryjars</a></li>
+<li><a href="usage.html#classpath"><i>class_path</i></a></li>
+<li><a href="usage.html#filters"><i>filters</i></a></li>
</ul>
<p>
-<a name="shrinking"> </a>
-<h2>The Shrinking Tab</h2>
+<h2><a name="shrinking">The Shrinking Tab</a></h2>
The <i>Shrinking</i> tab presents a number of options that affect the
shrinking step. The basic options are followed by a few lists of classes and
@@ -224,41 +232,41 @@
<ul>
<li>The <b>Comments</b> text field allows to add optional comments to this
entry. The comments will identify the entry in the list and they will
- appear as comments in the configuration file.
+ appear as comments in the configuration file.</li>
<li>The <b>Keep</b> selection allows to specify whether you want to protect
the specified classes and their specified class members, or just the
specified class members from the specified classes, or the specified
classes and the specified class members, if the class members are present.
Note that class members will only be protected if they are explicitly
- specified, even if only by means of a wildcard.
+ specified, even if only by means of a wildcard.</li>
<li>The <b>Allow</b> selection allows to specify whether you want to allow the
the specified classes and their specified class members to be shrunk,
- optimized and/or obfuscated.
+ optimized and/or obfuscated.</li>
<li>The <b>Access</b> selections allows to specify constraints on the class or
- classes, based on their access modifiers.
+ classes, based on their access modifiers.</li>
<li>The <b>Annotation</b> text field takes the fully-qualified name of an
annotation that is required for matching classes. The annotation name can
contain wildcards. This is an advanced option for defining <i>keep</i>
- annotations.
+ annotations.</li>
<li>The <b>Class</b> text field takes the fully-qualified name of the class or
- classes. The class name can contain wildcards.
+ classes. The class name can contain wildcards.</li>
<li>The <b>Annotation</b> text field takes the fully-qualified name of an
annotation that is required for the class or interface that the above
class must extend. The annotation name can contain wildcards. This is an
- advanced option for defining <i>keep</i> annotations.
+ advanced option for defining <i>keep</i> annotations.</li>
<li>The <b>Extends/implements class</b> text field takes the fully-qualified
- name of the class or interface that the above classes must extend.
+ name of the class or interface that the above classes must extend.</li>
<li>The <b>Class members</b> list allows to specify a list of fields and
methods to keep. It can be edited by means of a list of buttons on the
- right-hand side.
+ right-hand side.</li>
</ul>
<p>
@@ -270,18 +278,18 @@
<ul>
<li>The <b>Access</b> selections allows to specify constraints on the field or
- fields, based on their access modifiers.
+ fields, based on their access modifiers.</li>
<li>The <b>Annotation</b> text field takes the fully-qualified name of an
annotation that is required for matching fields. The annotation name can
contain wildcards. This is an advanced option for defining <i>keep</i>
- annotations.
+ annotations.</li>
<li>The <b>Return type</b> text field takes the fully-qualified type of the
- field or fields. The type can contain wildcards.
+ field or fields. The type can contain wildcards.</li>
<li>The <b>Name</b> text field takes the name of the field or fields. The field
- name can contain wildcards.
+ name can contain wildcards.</li>
</ul>
<p>
@@ -293,36 +301,35 @@
<ul>
<li>The <b>Access</b> selections allows to specify constraints on the method or
- methods, based on their access modifiers.
+ methods, based on their access modifiers.</li>
<li>The <b>Annotation</b> text field takes the fully-qualified name of an
annotation that is required for matching methods. The annotation name can
contain wildcards. This is an advanced option for defining <i>keep</i>
- annotations.
+ annotations.</li>
-<li>The <b>Return type</b> text field takes the fully-qualified type of the method or methods. The type can contain wildcards.
+<li>The <b>Return type</b> text field takes the fully-qualified type of the method or methods. The type can contain wildcards.</li>
<li>The <b>Name</b> text field takes the name of the method or methods. The
- method name can contain wildcards.
+ method name can contain wildcards.</li>
<li>The <b>Arguments</b> text field takes the comma-separated list of
fully-qualified method arguments. Each of these arguments can contain
- wildcards.
+ wildcards.</li>
</ul>
<p>
Corresponding configuration options:
<ul type="none">
-<li>-<a href="usage.html#dontshrink">dontshrink</a>
-<li>-<a href="usage.html#printusage">printusage</a>
-<li>-<a href="usage.html#keep">keep</a>
-<li>-<a href="usage.html#keepclassmembers">keepclassmembers</a>
-<li>-<a href="usage.html#keepclasseswithmembers">keepclasseswithmembers</a>
+<li>-<a href="usage.html#dontshrink">dontshrink</a></li>
+<li>-<a href="usage.html#printusage">printusage</a></li>
+<li>-<a href="usage.html#keep">keep</a></li>
+<li>-<a href="usage.html#keepclassmembers">keepclassmembers</a></li>
+<li>-<a href="usage.html#keepclasseswithmembers">keepclasseswithmembers</a></li>
</ul>
<p>
-<a name="obfuscation"> </a>
-<h2>The Obfuscation Tab</h2>
+<h2><a name="obfuscation">The Obfuscation Tab</a></h2>
The <i>Obfuscation</i> tab presents a number of options that affect the
obfuscation step. The basic options are followed by a few lists of classes and
@@ -336,32 +343,32 @@
Corresponding configuration options:
<ul type="none">
-<li>-<a href="usage.html#dontobfuscate">dontobfuscate</a>
-<li>-<a href="usage.html#printmapping">printmapping</a>
-<li>-<a href="usage.html#applymapping">applymapping</a>
-<li>-<a href="usage.html#obfuscationdictionary">obfuscationdictionary</a>
-<li>-<a href="usage.html#classobfuscationdictionary">classobfuscationdictionary</a>
-<li>-<a href="usage.html#packageobfuscationdictionary">packageobfuscationdictionary</a>
-<li>-<a href="usage.html#overloadaggressively">overloadaggressively</a>
-<li>-<a href="usage.html#useuniqueclassmembernames">useuniqueclassmembernames</a>
-<li>-<a href="usage.html#dontusemixedcaseclassnames">dontusemixedcaseclassnames</a>
-<li>-<a href="usage.html#keeppackagenames">keeppackagenames</a>
-<li>-<a href="usage.html#flattenpackagehierarchy">flattenpackagehierarchy</a>
-<li>-<a href="usage.html#repackageclasses">repackageclasses</a>
-<li>-<a href="usage.html#keepattributes">keepattributes</a>
-<li>-<a href="usage.html#renamesourcefileattribute">renamesourcefileattribute</a>
-<li>-<a href="usage.html#adaptclassstrings">adaptclassstrings</a>
-<li>-<a href="usage.html#adaptresourcefilenames">adaptresourcefilenames</a>
-<li>-<a href="usage.html#adaptresourcefilecontents">adaptresourcefilecontents</a>
-<li>-<a href="usage.html#keepnames">keepnames</a>
-<li>-<a href="usage.html#keepclassmembernames">keepclassmembernames</a>
-<li>-<a href="usage.html#keepclasseswithmembernames">keepclasseswithmembernames</a>
-<li><a href="usage.html#classspecification"><i>class_specification</i></a>
+<li>-<a href="usage.html#dontobfuscate">dontobfuscate</a></li>
+<li>-<a href="usage.html#printmapping">printmapping</a></li>
+<li>-<a href="usage.html#applymapping">applymapping</a></li>
+<li>-<a href="usage.html#obfuscationdictionary">obfuscationdictionary</a></li>
+<li>-<a href="usage.html#classobfuscationdictionary">classobfuscationdictionary</a></li>
+<li>-<a href="usage.html#packageobfuscationdictionary">packageobfuscationdictionary</a></li>
+<li>-<a href="usage.html#overloadaggressively">overloadaggressively</a></li>
+<li>-<a href="usage.html#useuniqueclassmembernames">useuniqueclassmembernames</a></li>
+<li>-<a href="usage.html#dontusemixedcaseclassnames">dontusemixedcaseclassnames</a></li>
+<li>-<a href="usage.html#keeppackagenames">keeppackagenames</a></li>
+<li>-<a href="usage.html#flattenpackagehierarchy">flattenpackagehierarchy</a></li>
+<li>-<a href="usage.html#repackageclasses">repackageclasses</a></li>
+<li>-<a href="usage.html#keepattributes">keepattributes</a></li>
+<li>-<a href="usage.html#keepparameternames">keepparameternames</a></li>
+<li>-<a href="usage.html#renamesourcefileattribute">renamesourcefileattribute</a></li>
+<li>-<a href="usage.html#adaptclassstrings">adaptclassstrings</a></li>
+<li>-<a href="usage.html#adaptresourcefilenames">adaptresourcefilenames</a></li>
+<li>-<a href="usage.html#adaptresourcefilecontents">adaptresourcefilecontents</a></li>
+<li>-<a href="usage.html#keepnames">keepnames</a></li>
+<li>-<a href="usage.html#keepclassmembernames">keepclassmembernames</a></li>
+<li>-<a href="usage.html#keepclasseswithmembernames">keepclasseswithmembernames</a></li>
+<li><a href="usage.html#classspecification"><i>class_specification</i></a></li>
</ul>
<p>
-<a name="optimization"> </a>
-<h2>The Optimization Tab</h2>
+<h2><a name="optimization">The Optimization Tab</a></h2>
The <i>Optimization</i> tab presents a number of options that affect the
optimization step. The basic options are followed by a few lists of class
@@ -375,18 +382,17 @@
Corresponding configuration options:
<ul type="none">
-<li>-<a href="usage.html#dontoptimize">dontoptimize</a>
-<li>-<a href="usage.html#optimizations">optimizations</a>
-<li>-<a href="usage.html#optimizationpasses">optimizationpasses</a>
-<li>-<a href="usage.html#allowaccessmodification">allowaccessmodification</a>
-<li>-<a href="usage.html#mergeinterfacesaggressively">mergeinterfacesaggressively</a>
-<li>-<a href="usage.html#assumenosideeffects">assumenosideeffects</a>
-<li><a href="usage.html#classspecification"><i>class_specification</i></a>
+<li>-<a href="usage.html#dontoptimize">dontoptimize</a></li>
+<li>-<a href="usage.html#optimizations">optimizations</a></li>
+<li>-<a href="usage.html#optimizationpasses">optimizationpasses</a></li>
+<li>-<a href="usage.html#allowaccessmodification">allowaccessmodification</a></li>
+<li>-<a href="usage.html#mergeinterfacesaggressively">mergeinterfacesaggressively</a></li>
+<li>-<a href="usage.html#assumenosideeffects">assumenosideeffects</a></li>
+<li><a href="usage.html#classspecification"><i>class_specification</i></a></li>
</ul>
<p>
-<a name="information"> </a>
-<h2>The Information Tab</h2>
+<h2><a name="information">The Information Tab</a></h2>
The <i>Information</i> tab presents a number of options for preverification
and targeting, and for the information that ProGuard returns when processing
@@ -396,26 +402,26 @@
Corresponding configuration options:
<ul type="none">
-<li>-<a href="usage.html#dontpreverify">dontpreverify</a>
-<li>-<a href="usage.html#microedition">microedition</a>
-<li>-<a href="usage.html#target">target</a>
-<li>-<a href="usage.html#verbose">verbose</a>
-<li>-<a href="usage.html#dontnote">dontnote</a>
-<li>-<a href="usage.html#dontwarn">dontwarn</a>
-<li>-<a href="usage.html#ignorewarnings">ignorewarnings</a>
-<li>-<a href="usage.html#dontskipnonpubliclibraryclasses">dontskipnonpubliclibraryclasses</a>
-<li>-<a href="usage.html#dontskipnonpubliclibraryclassmembers">dontskipnonpubliclibraryclassmembers</a>
-<li>-<a href="usage.html#keepdirectories">keepdirectories</a>
-<li>-<a href="usage.html#forceprocessing">forceprocessing</a>
-<li>-<a href="usage.html#printseeds">printseeds</a>
-<li>-<a href="usage.html#printconfiguration">printconfiguration</a>
-<li>-<a href="usage.html#dump">dump</a>
-<li>-<a href="usage.html#whyareyoukeeping">whyareyoukeeping</a>
+<li>-<a href="usage.html#dontpreverify">dontpreverify</a></li>
+<li>-<a href="usage.html#microedition">microedition</a></li>
+<li>-<a href="usage.html#target">target</a></li>
+<li>-<a href="usage.html#verbose">verbose</a></li>
+<li>-<a href="usage.html#dontnote">dontnote</a></li>
+<li>-<a href="usage.html#dontwarn">dontwarn</a></li>
+<li>-<a href="usage.html#ignorewarnings">ignorewarnings</a></li>
+<li>-<a href="usage.html#skipnonpubliclibraryclasses">skipnonpubliclibraryclasses</a></li>
+<li>-<a href="usage.html#dontskipnonpubliclibraryclasses">dontskipnonpubliclibraryclasses</a></li>
+<li>-<a href="usage.html#dontskipnonpubliclibraryclassmembers">dontskipnonpubliclibraryclassmembers</a></li>
+<li>-<a href="usage.html#keepdirectories">keepdirectories</a></li>
+<li>-<a href="usage.html#forceprocessing">forceprocessing</a></li>
+<li>-<a href="usage.html#printseeds">printseeds</a></li>
+<li>-<a href="usage.html#printconfiguration">printconfiguration</a></li>
+<li>-<a href="usage.html#dump">dump</a></li>
+<li>-<a href="usage.html#whyareyoukeeping">whyareyoukeeping</a></li>
</ul>
<p>
-<a name="process"> </a>
-<h2>The Process Tab</h2>
+<h2><a name="process">The Process Tab</a></h2>
The <i>Process</i> tab has an output console for displaying the configuration
and the messages while processing. There are three important buttons at the
@@ -433,8 +439,7 @@
</table>
<p>
-<a name="retrace"> </a>
-<h2>The ReTrace Tab</h2>
+<h2><a name="retrace">The ReTrace Tab</a></h2>
The <i>ReTrace</i> tab has a panel with a few settings, an input text area for
the obfuscated stack trace, and an output console to view the de-obfuscated
@@ -442,16 +447,16 @@
<ul>
<li>The <b>Verbose</b> check box in the settings panel allows to toggle between
- normal mode and verbose mode.
+ normal mode and verbose mode.</li>
<li>The <b>Mapping file</b> text field takes the name of the required mapping
file that ProGuard wrote while processing the original code. The file name
can be entered manually or by means of the <b>Browse...</b> button that
- opens a file chooser.
+ opens a file chooser.</li>
<li>The <b>Obfuscated stack trace</b> text area allows to enter the stack
trace, typically by copying and pasting it from elsewhere. Alternatively,
- it can be loaded from a file by means of the load button below.
+ it can be loaded from a file by means of the load button below.</li>
</ul>
There are two buttons at the bottom:
@@ -463,12 +468,12 @@
<tr><td class="button">ReTrace!</td>
<td>executes ReTrace with the current settings.</td></tr>
</table>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/index.html b/docs/manual/index.html
index 397b910..5b62d50 100644
--- a/docs/manual/index.html
+++ b/docs/manual/index.html
@@ -1,39 +1,51 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Manual</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
<h2>ProGuard</h2>
<ol>
-<li><a href="introduction.html">Introduction</a>
-<li><a href="usage.html">Usage</a>
-<li><a href="limitations.html">Limitations</a>
-<li><a href="examples.html">Examples</a>
-<li><a href="troubleshooting.html">Troubleshooting</a>
-<li><a href="refcard.html">Reference Card</a>
-<li><a href="gui.html">Graphical User Interface</a>
-<li><a href="ant.html">Ant Task</a>
-<li><a href="wtk.html">JME Wireless Toolkit Integration</a>
+<li><a href="introduction.html">Introduction</a></li>
+<li><a href="usage.html">Usage</a></li>
+<li><a href="limitations.html">Limitations</a></li>
+<li><a href="examples.html">Examples</a></li>
+<li><a href="troubleshooting.html">Troubleshooting</a></li>
+<li><a href="refcard.html">Reference Card</a></li>
+<li><a href="gui.html">Graphical User Interface</a></li>
+<li><a href="ant.html">Ant Task</a></li>
+<li><a href="wtk.html">JME Wireless Toolkit Integration</a></li>
</ol>
<h2>ReTrace</h2>
<ol>
-<li><a href="retrace/introduction.html">Introduction</a>
-<li><a href="retrace/usage.html">Usage</a>
-<li><a href="retrace/examples.html">Examples</a>
+<li><a href="retrace/introduction.html">Introduction</a></li>
+<li><a href="retrace/usage.html">Usage</a></li>
+<li><a href="retrace/examples.html">Examples</a></li>
</ol>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/introduction.html b/docs/manual/introduction.html
index cdab330..bc71f4a 100644
--- a/docs/manual/introduction.html
+++ b/docs/manual/introduction.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Introduction</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -76,7 +87,9 @@
reconstruct the class dependencies that are necessary for proper processing.
The library jars themselves always remain unchanged. You should still put them
in the class path of your final application.
-<p>
+
+<h3>Entry points</h3>
+
In order to determine which code has to be preserved and which code can be
discarded or obfuscated, you have to specify one or more <i>entry points</i> to
your code. These entry points are typically classes with main methods, applets,
@@ -84,55 +97,59 @@
<ul>
<li>In the <b>shrinking step</b>, ProGuard starts from these seeds and
recursively determines which classes and class members are used. All other
- classes and class members are discarded.
+ classes and class members are discarded.</li>
<li>In the <b>optimization step</b>, ProGuard further optimizes the code.
Among other optimizations, classes and methods that are not entry points
can be made private, static, or final, unused parameters can be removed,
- and some methods may be inlined.
+ and some methods may be inlined.</li>
<li>In the <b>obfuscation step</b>, ProGuard renames classes and class members
that are not entry points. In this entire process, keeping the entry
- points ensures that they can still be accessed by their original names.
+ points ensures that they can still be accessed by their original names.</li>
<li>The <b>preverification step</b> is the only step that doesn't have to know
- the entry points.
+ the entry points.</li>
</ul>
<p>
The <a href="usage.html">Usage section</a> of this manual describes the
necessary <a href="usage.html#keepoptions"><code>-keep</code> options</a> and
the <a href="examples.html">Examples section</a> provides plenty of examples.
-<h3>Introspection</h3>
+<h3>Reflection</h3>
-Introspection presents particular problems for any automatic processing of
-code. In ProGuard, classes or class members in your code that are created or
-invoked dynamically (that is, by name) have to be specified as entry points
-too. For example, <code>Class.forName()</code> constructs may refer to any
-class at run-time. It is generally impossible to foresee which classes have to
-be preserved (with their original names), since the class names might be read
-from a configuration file, for instance. You therefore have to specify them in
-your ProGuard configuration, with the same simple <code>-keep</code> options.
+Reflection and introspection present particular problems for any automatic
+processing of code. In ProGuard, classes or class members in your code that
+are created or invoked dynamically (that is, by name) have to be specified as
+entry points too. For example, <code>Class.forName()</code> constructs may
+refer to any class at run-time. It is generally impossible to foresee which
+classes have to be preserved (with their original names), since the class
+names might be read from a configuration file, for instance. You therefore
+have to specify them in your ProGuard configuration, with the same
+simple <code>-keep</code> options.
<p>
However, ProGuard will already detect and handle the following cases for you:
<ul>
-<li><code>Class.forName("SomeClass")</code>
-<li><code>SomeClass.class</code>
-<li><code>SomeClass.class.getField("someField")</code>
-<li><code>SomeClass.class.getDeclaredField("someField")</code>
-<li><code>SomeClass.class.getMethod("someMethod", new Class[] {})</code>
-<li><code>SomeClass.class.getMethod("someMethod", new Class[] { A.class })</code>
-<li><code>SomeClass.class.getMethod("someMethod", new Class[] { A.class, B.class })</code>
-<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] {})</code>
-<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class })</code>
-<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class, B.class })</code>
+<li><code>Class.forName("SomeClass")</code></li>
+<li><code>SomeClass.class</code></li>
+<li><code>SomeClass.class.getField("someField")</code></li>
+<li><code>SomeClass.class.getDeclaredField("someField")</code></li>
+<li><code>SomeClass.class.getMethod("someMethod", new Class[] {})</code></li>
+<li><code>SomeClass.class.getMethod("someMethod", new Class[] { A.class })</code></li>
+<li><code>SomeClass.class.getMethod("someMethod", new Class[] { A.class, B.class })</code></li>
+<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] {})</code></li>
+<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class })</code></li>
+<li><code>SomeClass.class.getDeclaredMethod("someMethod", new Class[] { A.class, B.class })</code></li>
+<li><code>AtomicIntegerFieldUpdater.newUpdater(SomeClass.class, "someField")</code></li>
+<li><code>AtomicLongFieldUpdater.newUpdater(SomeClass.class, "someField")</code></li>
+<li><code>AtomicReferenceFieldUpdater.newUpdater(SomeClass.class, SomeType.class, "someField")</code></li>
</ul>
The names of the classes and class members may of course be different, but the
constructs should be literally the same for ProGuard to recognize them. The
referenced classes and class members are preserved in the shrinking phase, and
-the string arguments are properly replaced in the obfuscation phase.
+the string arguments are properly updated in the obfuscation phase.
<p>
Furthermore, ProGuard will offer some suggestions if keeping some classes or
class members appears necessary. For example, ProGuard will note constructs
@@ -142,15 +159,15 @@
configuration accordingly.
<p>
For proper results, you should at least be somewhat familiar with the code
-that you are processing. Obfuscating code that performs a lot of introspection
+that you are processing. Obfuscating code that performs a lot of reflection
may require trial and error, especially without the necessary information
about the internals of the code.
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/limitations.html b/docs/manual/limitations.html
index cfe0ff5..3b28a30 100644
--- a/docs/manual/limitations.html
+++ b/docs/manual/limitations.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Limitations</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -13,16 +24,7 @@
When using ProGuard, you should be aware of a few technical issues, all of
which are easily avoided or resolved:
<p>
-<ul>
-
-<li>For efficiency, ProGuard always ignores any <b>private or package visible
- library classes</b> while reading library jars. If any of them are
- extended by public library classes, and then extended again by input
- classes, ProGuard will complain it can't find them. In that case, you'll
- have to use the <code>-dontskipnonpubliclibraryclasses</code> option, and
- maybe even the <code>-dontskipnonpubliclibraryclassmembers</code> option.
- The graphical user interface has checkboxes for these settings.
- <p>
+<ul class="spacious">
<li>For best results, ProGuard's optimization algorithms assume that the
processed code never <b>intentionally throws NullPointerExceptions</b> or
@@ -33,32 +35,35 @@
<code>myObject</code> might be null, causing a NullPointerException. In
some way this is a good thing: optimized code may throw fewer exceptions.
Should this entire assumption be false, you'll have to switch off
- optimization using the <code>-dontoptimize</code> option.
- <p>
+ optimization using the <code>-dontoptimize</code> option.</li>
+
+<li>ProGuard's optimization algorithms currently also assume that the
+ processed code never creates <b>busy-waiting loops</b> without at least
+ testing on a volatile field. Again, it may remove such loops. Should this
+ assumption be false, you'll have to switch off optimization using
+ the <code>-dontoptimize</code> option.</li>
<li>If an input jar and a library jar contain classes in the <b>same
package</b>, the obfuscated output jar may contain class names that
overlap with class names in the library jar. This is most likely if the
library jar has been obfuscated before, as it will then probably contain
classes named 'a', 'b', etc. Packages should therefore never be split
- across input jars and library jars.
- <p>
+ across input jars and library jars.</li>
-<li>When obfuscating, ProGuard will write out class files named
- "<code>a.class</code>", "<code>b.class</code>", etc. If there is a large
- numbers of classes in the same package, it may also write out
- <b>"<code>aux.class</code>"</b>. Windows doesn't allow creating files with
- this reserved name (among a few other names), so it's generally better to
- write the output to a jar, in order to avoid such problems.
- <p>
+<li>When obfuscating, ProGuard writes out class files named
+ "<code>a.class</code>", "<code>b.class</code>", etc. If a package contains
+ a large number of classes, ProGuard may also write out
+ <b>"<code>aux.class</code>"</b>. Inconveniently, Windows refuses to create
+ files with this reserved name (among a few other names). It's generally
+ better to write the output to a jar, in order to avoid such problems.</li>
</ul>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/optimizations.html b/docs/manual/optimizations.html
index 9c20571..4711f83 100644
--- a/docs/manual/optimizations.html
+++ b/docs/manual/optimizations.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>Optimizations</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -124,6 +135,9 @@
<code><b>code/simplification/branch</b></code></dt>
<dd>Performs peephole optimizations for branch instructions.</dd>
+<dt><code><b>code/simplification/string</b></code></dt>
+<dd>Performs peephole optimizations for constant strings.</dd>
+
<dt><div>(<i>best used with</i> <code>code/removal/advanced</code>)</div>
<code><b>code/simplification/advanced</b></code></dt>
<dd>Simplifies code based on control flow analysis and data flow
@@ -142,17 +156,17 @@
<dd>Removes unused variables from the local variable frame.</dd>
<dt><code><b>code/removal/exception</b></code></dt>
-<dd>Removes exceptions with empty catch blocks.</dd>
+<dd>Removes exceptions with empty try blocks.</dd>
<dt><code><b>code/allocation/variable</b></code></dt>
<dd>Optimizes variable allocation on the local variable frame.</dd>
</dl>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/refcard.html b/docs/manual/refcard.html
index 236f049..02a8e50 100644
--- a/docs/manual/refcard.html
+++ b/docs/manual/refcard.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Reference Card</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -63,8 +74,13 @@
</tr>
<tr>
+<td valign="top"><a href="usage.html#skipnonpubliclibraryclasses"><code><b>-skipnonpubliclibraryclasses</b></code></a></td>
+<td>Ignore non-public library classes.</td>
+</tr>
+
+<tr>
<td valign="top"><a href="usage.html#dontskipnonpubliclibraryclasses"><code><b>-dontskipnonpubliclibraryclasses</b></code></a></td>
-<td>Don't ignore non-public library classes.</td>
+<td>Don't ignore non-public library classes (the default).</td>
</tr>
<tr>
@@ -281,6 +297,11 @@
</tr>
<tr>
+<td valign="top"><a href="usage.html#keepparameternames"><code><b>-keepparameternames</b></code></a></td>
+<td>Keep the parameter names and types of methods that are kept.</td>
+</tr>
+
+<tr>
<td valign="top"><a href="usage.html#renamesourcefileattribute"><code><b>-renamesourcefileattribute</b></code></a>
[<i>string</i>]</td>
<td>Put the given constant string in the <code>SourceFile</code>
@@ -362,11 +383,11 @@
<ul>
<li><i>class_path</i> is a list of jars, wars, ears, zips, and directories,
- with optional filters, separated by path separators.
+ with optional filters, separated by path separators.</li>
<li><i>filename</i> can contain Java system properties delimited by
- '<b><</b>' and '<b>></b>'.
+ '<b><</b>' and '<b>></b>'.</li>
<li>If <i>filename</i> contains special characters, the entire name
- should be quoted with single or double quotes.
+ should be quoted with single or double quotes.</li>
</ul>
<p>
@@ -443,23 +464,23 @@
Notes:
<ul>
<li>Class names must always be fully qualified, i.e. including their package
- names.
+ names.</li>
<li>Types in <i>classname</i>, <i>annotationtype</i>, <i>returntype</i>, and
<i>argumenttype</i> can contain wildcards: '<code><b>?</b></code>' for a
single character, '<code><b>*</b></code>' for any number of characters
(but not the package separator), '<code><b>**</b></code>' for any number
of (any) characters, '<code><b>%</b></code>' for any primitive type,
- '<code><b>***</b></code>' for any type, and '<code><b>...</b></code>' for any number of arguments..
+ '<code><b>***</b></code>' for any type, and '<code><b>...</b></code>' for any number of arguments.</li>
<li><i>fieldname</i> and <i>methodname</i> can contain wildcards as well:
'<code><b>?</b></code>' for a single character and '<code><b>*</b></code>'
- for any number of characters.
+ for any number of characters.</li>
</ul>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/retrace/examples.html b/docs/manual/retrace/examples.html
index 211017b..c372491 100644
--- a/docs/manual/retrace/examples.html
+++ b/docs/manual/retrace/examples.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>ReTrace Examples</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -12,13 +23,13 @@
Some typical example uses:
<ol>
-<li><a href="#with">Restoring a stack trace with line numbers</a>
-<li><a href="#withverbose">Restoring a stack trace with line numbers (verbose)</a>
-<li><a href="#without">Restoring a stack trace without line numbers</a>
+<li><a href="#with">Restoring a stack trace with line numbers</a></li>
+<li><a href="#withverbose">Restoring a stack trace with line numbers
+ (verbose)</a></li>
+<li><a href="#without">Restoring a stack trace without line numbers</a></li>
</ol>
-<a name="with"> </a>
-<h3>Restoring a stack trace with line numbers</h3>
+<h3><a name="with">Restoring a stack trace with line numbers</a></h3>
Assume for instance ProGuard itself has been obfuscated using the following
extra options:
@@ -133,8 +144,7 @@
at proguard.ProGuard.main(ProGuard:429)
</pre>
-<a name="withverbose"> </a>
-<h3>Restoring a stack trace with line numbers (verbose)</h3>
+<h3><a name="withverbose">Restoring a stack trace with line numbers (verbose)</a></h3>
In the previous example, we could also use the verbose flag:
<pre>
@@ -189,8 +199,7 @@
</pre>
-<a name="without"> </a>
-<h3>Restoring a stack trace without line numbers</h3>
+<h3><a name="without">Restoring a stack trace without line numbers</a></h3>
Assume for instance ProGuard itself has been obfuscated using the following
extra options, this time without preserving the line number tables:
@@ -324,12 +333,12 @@
execute
at proguard.ProGuard.main(Unknown Source)
</pre>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/retrace/index.html b/docs/manual/retrace/index.html
index ebb23ac..7c45c28 100644
--- a/docs/manual/retrace/index.html
+++ b/docs/manual/retrace/index.html
@@ -1,25 +1,37 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>ReTrace Manual</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
<h2>ReTrace</h2>
<ol>
-<li><a href="introduction.html">Introduction</a>
-<li><a href="usage.html">Usage</a>
-<li><a href="examples.html">Examples</a>
+<li><a href="introduction.html">Introduction</a></li>
+<li><a href="usage.html">Usage</a></li>
+<li><a href="examples.html">Examples</a></li>
</ol>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/retrace/introduction.html b/docs/manual/retrace/introduction.html
index 19f9471..f6b6a07 100644
--- a/docs/manual/retrace/introduction.html
+++ b/docs/manual/retrace/introduction.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>ReTrace Introduction</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -56,12 +67,12 @@
look like without obfuscation. The restoration is based on the mapping file
that ProGuard can write out during obfuscation. The mapping file links the
original class names and class member names to their obfuscated names.
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/retrace/usage.html b/docs/manual/retrace/usage.html
index 88587ff..a227635 100644
--- a/docs/manual/retrace/usage.html
+++ b/docs/manual/retrace/usage.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>ReTrace Usage</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -87,14 +98,13 @@
<ul>
<li>If all line numbers have been preserved while obfuscating the application,
- ReTrace will be able to restore the stack trace completely.
- <p>
+ ReTrace will be able to restore the stack trace completely.</li>
<li>If the line numbers have been removed, mapping obfuscated method names
back to their original names has become ambiguous. Retrace will list all
possible original method names for each line in the stack trace. The user
can then try to deduce the actual stack trace manually, based on the logic
- of the program.
+ of the program.</li>
</ul>
<p>
@@ -105,12 +115,12 @@
Unobfuscated elements and obfuscated elements for which no mapping is available
will be left unchanged.
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/sections.html b/docs/manual/sections.html
index 62df9c3..fb72573 100644
--- a/docs/manual/sections.html
+++ b/docs/manual/sections.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -42,22 +42,18 @@
document.write(document.location.hostname == "proguard.sourceforge.net" ?
"http://sourceforge.net/sflogo.php?group_id=54750&type=1" :
"../sflogo.png");
-document.write("\" width=\"88\" height=\"31\" alt=\"SourceForge\">");
+document.write("\" width=\"88\" height=\"31\" alt=\"SourceForge\" />");
//-->
</script>
<noscript>
-<img src="../sflogo.png" width="88" height="31" alt="SourceForge">
+<img src="../sflogo.png" width="88" height="31" alt="SourceForge" />
</noscript>
</a>
<p>
-<a href="http://www.luciad.com/" target="other">
-<img src="../luciadlogo.png" width="88" height="24" alt="Luciad"></a>
-
-<p>
-<a href="http://www.javadocking.com/" target="other">
-<img src="../sanawarelogo.png" width="88" height="24" alt="Luciad"></a>
+<a href="http://www.saikoa.com/" target="_top">
+<img src="../saikoalogo.png" width="88" height="19" alt="Saikoa" /></a>
</center>
</body>
diff --git a/docs/manual/style.css b/docs/manual/style.css
index 28fc112..9a876aa 100644
--- a/docs/manual/style.css
+++ b/docs/manual/style.css
@@ -34,11 +34,24 @@
background: #E0E0E0;
}
+ul.spacious li
+{
+ padding: 8px;
+}
+
a
{
text-decoration: none;
}
+a.button {
+ color: #000000;
+ text-decoration: none;
+ background: #E0E0E0;
+ border: 1px outset #FFFFFF;
+ float: right;
+}
+
/* Settings for variable width code. */
p.code {
@@ -63,7 +76,7 @@
td.whiteblock {
width: 100px;
text-align: center;
- border: solid #C0C0C0 1px;
+ border: 1px solid #C0C0C0;
background: #E0E0E0;
padding: 10px 0px;
}
@@ -71,7 +84,7 @@
td.lightblock {
width: 100px;
text-align: center;
- border: solid #8888FF 1px;
+ border: 1px solid #8888FF;
background: #BBBBFF;
padding: 20px 0px;
}
@@ -87,6 +100,6 @@
td.button {
background: #E0E0E0;
- border: outset #FFFFFF 1px;
+ border: 1px outset #FFFFFF;
font-weight: bold;
}
diff --git a/docs/manual/troubleshooting.html b/docs/manual/troubleshooting.html
index d3ed14e..6b0c1a9 100644
--- a/docs/manual/troubleshooting.html
+++ b/docs/manual/troubleshooting.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Troubleshooting</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -19,19 +30,24 @@
<li><a href="#dynamicalclasscast">Note: ... calls '(...)Class.forName(variable).newInstance()'</a></li>
<li><a href="#dynamicalclassmember">Note: ... accesses a field/method '...' dynamically</a></li>
<li><a href="#descriptorclass">Note: the configuration keeps the entry point '...', but not the descriptor class '...'</a></li>
+<li><a href="#classmembers">Note: the configuration doesn't specify which class members to keep for class '...'</a></li>
<li><a href="#duplicateclass">Note: duplicate definition of program/library class</a></li>
<li><a href="#duplicatezipentry">Warning: can't write resource ... Duplicate zip entry</a></li>
<li><a href="#unresolvedclass">Warning: can't find superclass or interface</a></li>
<li><a href="#unresolvedclass">Warning: can't find referenced class</a></li>
+<li><a href="#superclass">Error: Can't find any super classes of ... (not even immediate super class ...)</a></li>
+<li><a href="#superclass">Error: Can't find common super class of ... and ...</a></li>
<li><a href="#unresolvedclassmember">Warning: can't find referenced field/method</a></li>
<li><a href="#unresolvedenclosingmethod">Warning: can't find enclosing class/method</a></li>
<li><a href="#dependency">Warning: library class ... depends on program class ...</a></li>
<li><a href="#unexpectedclass">Warning: class file ... unexpectedly contains class ...</a></li>
<li><a href="#mappingconflict1">Warning: ... is not being kept as ..., but remapped to ...</a></li>
<li><a href="#mappingconflict2">Warning: field/method ... can't be mapped to ...</a></li>
+<li><a href="#unsupportedclassversion">Error: Unsupported class version number</a></li>
<li><a href="#keep">Error: You have to specify '-keep' options</a></li>
<li><a href="#filename">Error: Expecting class path separator ';' before 'Files\Java\...' (in Windows)</a></li>
<li><a href="#macosx">Error: Can't read [.../lib/rt.jar] (No such file or directory) (in MacOS X)</a></li>
+<li><a href="#startinggui">Internal problem starting the ProGuard GUI (Cannot write XdndAware property) (in Linux)</a></li>
<li><a href="#outofmemoryerror">OutOfMemoryError</a></li>
<li><a href="#stackoverflowerror">StackOverflowError</a></li>
<li><a href="#unexpectederror">Unexpected error</a></li>
@@ -45,6 +61,13 @@
<li><a href="#notobfuscated">Variable names not being obfuscated</a></li>
</ul>
+<h3><a href="#dalvik">Problems while converting to Android Dalvik bytecode</a></h3>
+
+<ul>
+<li><a href="#simexception">SimException: local variable type mismatch</a></li>
+<li><a href="#conversionerror">Conversion to Dalvik format failed with error 1</a></li>
+</ul>
+
<h3><a href="#preverifying">Problems while preverifying for Java Micro Edition</a></h3>
<ul>
@@ -58,7 +81,9 @@
<li><a href="#classnotfoundexception">ClassNotFoundException</a></li>
<li><a href="#nosuchmethodexception">NoSuchMethodException</a></li>
<li><a href="#missingresourceexception">MissingResourceException or NullPointerException</a></li>
+<li><a href="#disappearingannotations">Disappearing annotations</a></li>
<li><a href="#invalidjarfile">Invalid or corrupt jarfile</a></li>
+<li><a href="#invalidjarindexexception">InvalidJarIndexException: Invalid index</a></li>
<li><a href="#invalidclassexception2">InvalidClassException, class loading error, or verification error (in Java Micro Edition)</a></li>
<li><a href="#nosuchfieldormethod">Error: No Such Field or Method, Error verifying method (in a Java Micro Edition emulator)</a></li>
<li><a href="#failingmidlets">Failing midlets (on a Java Micro Edition device)</a></li>
@@ -67,14 +92,14 @@
<li><a href="#classcastexception">ClassCastException: class not an enum</a></li><li><a href="#classcastexception">IllegalArgumentException: class not an enum type</a></li>
<li><a href="#arraystoreexception">ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy</a></li>
<li><a href="#compilererror">CompilerError: duplicate addition</a></li>
-<li><a href="#classformaterror">ClassFormatError: repetitive field name/signature</a></li>
+<li><a href="#classformaterror1">ClassFormatError: repetitive field name/signature</a></li>
+<li><a href="#classformaterror2">ClassFormatError: Invalid index in LocalVariableTable in class file</a></li>
<li><a href="#nosuchmethoderror">NoSuchMethodError or AbstractMethodError</a></li>
<li><a href="#verifyerror">VerifyError</a></li>
</ul>
-<a name="processing"> </a>
-<h2>Problems while processing</h2>
+<h2><a name="processing">Problems while processing</a></h2>
ProGuard may print out some notes and non-fatal warnings:
@@ -118,6 +143,17 @@
API. You can switch off these notes by specifying the <a
href="usage.html#dontnote"><code>-dontnote</code></a> option.</dd>
+<dt><a name="classmembers"><b>Note: the configuration doesn't specify which class members to keep for class '...'</b></a></dt>
+
+<dd>Your configuration contains
+ a <code>-keepclassmembers/-keepclasseswithmembers</code> option to
+ preserve fields or methods in the given class, but it doesn't specify
+ which fields or methods. This way, the option simply won't have any
+ effect. You probably want to specify one or more fields or methods, as
+ usual between curly braces. You can specify all fields or methods with a
+ wildcard "<code>*;</code>". You can switch off these notes by specifying
+ the <a href="usage.html#dontnote"><code>-dontnote</code></a> option.</dd>
+
<dt><a name="duplicateclass"><b>Note: duplicate definition of program/library class</b></a></dt>
<dd>Your program jars or library jars contain multiple definitions of the
@@ -152,22 +188,43 @@
the Java run-time library. For specifying libraries, use
the <a href="usage.html#libraryjars"><code>-libraryjars</code></a> option.
<p>
- If the class that is reported as missing is a non-public library class,
- you should specify the <a
- href="usage.html#dontskipnonpubliclibraryclasses"><code>-dontskipnonpubliclibraryclasses</code></a>
- option. Common examples are the classes
- <code>javax.swing.TransferHandler$HasGetTransferHandler</code> and
- <code>java.util.zip.ZipConstants</code>, which are used as interfaces in
- some public classes, even though they are only package visible. This
- option is not set by default for reasons of efficiency. Setting it increases
- the processing time a bit, but it won't hurt the output in any way.
+ For example, if ProGuard complains that it can't find a
+ <code>javax.crypto</code> class, you probably still have to specify
+ <code>jce.jar</code>, next to the more common <code>rt.jar</code>.
<p>
If you're missing a library and you're absolutely sure it isn't used
anyway, you can try your luck with the <a
href="usage.html#ignorewarnings"><code>-ignorewarnings</code></a> option,
or even the <a href="usage.html#dontwarn"><code>-dontwarn</code></a>
option. Only use these options if you really know what you're doing
- though.</dd>
+ though.
+ <p>
+ For example, if you're developing for Android, and ProGuard complains that
+ it can't find a <code>java.awt</code> class, then some library that you
+ are using is referring to <code>java.awt</code>. This is a bit shady, since
+ Android doesn't have this package at all, but if your application works
+ anyway, you can let ProGuard accept it with "<code>-dontwarn
+ java.awt.**</code>".</dd>
+
+<dt><a name="superclass"><b>Error: Can't find any super classes of ... (not even immediate super class ...)</b><br/><b>Error: Can't find common super class of ... and ...</b></a></dt>
+
+<dd>It seems like you tried to avoid the warnings from the previous paragraph
+ by specifying
+ <a href="usage.html#ignorewarnings"><code>-ignorewarnings</code></a>
+ or <a href="usage.html#dontwarn"><code>-dontwarn</code></a>, but it didn't
+ work out. ProGuard's optimization step and preverification step really
+ need the missing classes to make sense of the code. Preferably, you would
+ solve the problem by adding the missing library, as discussed. If you're
+ sure the class that references the missing class isn't used either, you
+ could also try filtering it out from the input, by adding a filter to the
+ corresponding <a href="usage.html#injars"><code>-injars</code></a> option:
+ "<code>-injars
+ myapplication.jar(!somepackage/SomeUnusedClass.class)</code>". Hopefully,
+ you can access the configuration of your build process for such a
+ modification. As a final solution, you could switch off optimization
+ (<a href="usage.html#dontoptimize"><code>-dontoptimize</code></a>) and
+ preverification
+ (<a href="usage.html#dontpreverify"><code>-dontpreverify</code></a>).</dd>
<dt><a name="unresolvedclassmember"><b>Warning: can't find referenced field/method</b></a></dt>
@@ -177,19 +234,10 @@
source file was removed. Try removing all class files, recompiling them,
zipping them up, and running ProGuard again.
<p>
- If the class member that is reported as missing is actually implemented in
- a non-public library class, you should specify the
- <a href="usage.html#dontskipnonpubliclibraryclasses"><code>-dontskipnonpubliclibraryclasses</code></a> option. A common example is
- the method <code>setLength(int)</code> in the public class
- <code>java.lang.StringBuilder</code>. This method is actually defined in
- the package visible superclass
- <code>java.lang.AbstractStringBuilder</code>, which ProGuard ignores by
- default.
- <p>
If your program classes reside in the same packages as library classes,
- and refer to their package visible class members, then you should specify
- the <a
- href="usage.html#dontskipnonpubliclibraryclassmembers"><code>-dontskipnonpubliclibraryclassmembers</code></a>
+ and refer to their package visible class members, then you should also
+ specify the
+ <a href="usage.html#dontskipnonpubliclibraryclassmembers"><code>-dontskipnonpubliclibraryclassmembers</code></a>
option.</dd>
<dt><a name="unresolvedenclosingmethod"><b>Warning: can't find enclosing class/method</b></a></dt>
@@ -210,7 +258,11 @@
classes always remain unchanged. It is therefore impossible to adapt
references from library classes to program classes, for instance if the
program classes are renamed. You should define a clean separation between
- program code and library code, and try again.</dd>
+ program code (specified with <a
+ href="usage.html#injars"><code>-injars</code></a>) and library code
+ (specified with <a
+ href="usage.html#libraryjars"><code>-libraryjars</code></a>), and try
+ again.</dd>
<dt><a name="unexpectedclass"><b>Warning: class file ... unexpectedly contains class ...</b></a></dt>
@@ -257,6 +309,13 @@
option in the initial obfuscation step, in order to reduce the risk of
conflicts.</dd>
+<dt><a name="unsupportedclassversion"><b>Error: Unsupported class version number</b></a></dt>
+
+<dd>You are trying to process class files compiled for a recent version of
+ Java that your copy of ProGuard doesn't support yet. You should check if
+ there is a more recent release
+ <a href="http://proguard.sourceforge.net/downloads.html">on-line</a>.</dd>
+
<dt><a name="keep"><b>Error: You have to specify '-keep' options</b></a></dt>
<dd>You either forgot to specify <a
@@ -266,7 +325,6 @@
these. Without the proper seed specifications, ProGuard would shrink,
optimize, or obfuscate all class files away.</dd>
-
<dt><a name="filename"><b>Error: Expecting class path separator ';' before 'Files\Java\</b>...<b>'</b> (in Windows)</a></dt>
<dd>If the path of your run-time jar contains spaces, like in "Program Files",
@@ -282,6 +340,16 @@
the path <code><java.home>/lib/rt.jar</code> by
<code><java.home>/../Classes/classes.jar</code>.</dd>
+<dt><a name="startinggui"><b>Internal problem starting the ProGuard GUI (Cannot write XdndAware property)</b> (in Linux)</a></dt>
+
+<dd>In Linux, at least with Java 6, the GUI may not start properly, due to
+ <a href="http://bugs.sun.com/view_bug.do?bug_id=7027598">Sun
+ Bug #7027598</a>. The work-around at this time is to specify the JVM
+ option <code>-DsuppressSwingDropSupport=true</code> when running the
+ GUI.</dd>
+
+<dd>
+
</dl>
<p>
@@ -304,7 +372,7 @@
size of the Java virtual machine (with the usual <code>-Xss</code> option)
should help too. In practice however, the <code>-Xss</code> setting
doesn't have any effect on the main thread, due to <a
- href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4362291">Sun Bug
+ href="http://bugs.sun.com/view_bug.do?bug_id=4362291">Sun Bug
#4362291</a>. As a result, this solution will only work when running
ProGuard in a different thread, e.g. from its GUI.</dd>
@@ -326,8 +394,7 @@
</dl>
<p>
-<a name="afterprocessing"> </a>
-<h2>Unexpected observations after processing</h2>
+<h2><a name="afterprocessing">Unexpected observations after processing</a></h2>
If ProGuard seems to run fine, but your processed code doesn't look right,
there might be a couple of reasons:
@@ -363,7 +430,13 @@
<p>
If you are using marker interfaces to keep other classes, the marker
interfaces themselves are probably being removed in the shrinking step.
- You should therefore always explicitly keep any marker interfaces.</dd>
+ You should therefore always explicitly keep any marker interfaces, with
+ an option like "<code>-keep interface MyMarkerInterface</code>".
+ <p>
+ Similarly, if you are keeping classes based on annotations, you may have to
+ avoid that the annotation classes themselves are removed in the shrinking
+ step. You can explicitly keep all annotation classes in your program code
+ with an option like "<code>-keep @interface *</code>".<dd>
<dt><a name="notobfuscated"><b>Variable names not being obfuscated</b></a></dt>
@@ -377,8 +450,37 @@
</dl>
-<a name="preverifying"> </a>
-<h2>Problems while preverifying for Java Micro Edition</h2>
+<h2><a name="dalvik">Problems while converting to Android Dalvik bytecode</a></h2>
+
+If ProGuard seems to run fine, but the dx tool in the Android SDK subsequently
+fails with an error:
+
+<dl>
+<dt><a name="simexception"><b>SimException: local variable type mismatch</b></a></dt>
+
+<dd>This error indicates that ProGuard's optimization step has not been able
+ to maintain the correct debug information about local variables. This can
+ happen if some code is optimized radically. Possible work-arounds: let the
+ java compiler not produce debug information (<code>-g:none</code>), or let
+ ProGuard's obfuscation step remove the debug information again
+ (by <i>not</i> keeping the attributes <code>LocalVariableTable</code>
+ and <code>LocalVariableTypeTable</code>
+ with <a href="usage.html#keepattributes"><code>-keepattributes</code></a>),
+ or otherwise just disable optimization
+ (<a href="usage.html#dontoptimize"><code>-dontoptimize</code></a>).</dd>
+
+<dt><a name="conversionerror"><b>Conversion to Dalvik format failed with error 1</b></a></dt>
+
+<dd>This error may have various causes, but if dx is tripping over some code
+ processed by ProGuard, you should make sure that you are using the latest
+ version of ProGuard. You can just copy the ProGuard jars
+ to <code>android-sdk/tools/proguard/lib</code>. If that doesn't help,
+ please report the problem, preferably with the simplest example that still
+ brings out the error.</dd>
+
+</dl>
+
+<h2><a name="preverifying">Problems while preverifying for Java Micro Edition</a></h2>
If ProGuard seems to run fine, but the external preverifier subsequently
produces errors, it's usually for a single reason:
@@ -409,8 +511,7 @@
ProGuard will preverify the class files for Java Micro Edition.
<p>
-<a name="runtime"> </a>
-<h2>Problems at run-time</h2>
+<h2><a name="runtime">Problems at run-time</a></h2>
If ProGuard runs fine, but your processed application doesn't work, there
might be several reasons:
@@ -443,10 +544,15 @@
<dd>Your code is probably calling something like
<code>myClass.getMethod</code>, trying to find some method dynamically.
- Since ProGuard isn't detecting this (yet), you have to keep the missing
- method in using the appropriate <a
+ Since ProGuard can't always detect this automatically, you have to keep
+ the missing method in using the appropriate <a
href="usage.html#keep"><code>-keep</code></a> option, e.g. "<code>-keep
- class mypackage.MyClass { void myMethod(); }</code>".</dd>
+ class mypackage.MyClass { void myMethod(); }</code>".
+ <p>
+ More specifically, if the method reported as missing is
+ <code>values</code> or <code>valueOf</code>, you probably have to keep
+ some methods related to <a
+ href="examples.html#enumerations">enumerations</a>.</dd>
<dt><a name="missingresourceexception"><b>MissingResourceException</b> or <b>NullPointerException</b></a></dt>
@@ -460,7 +566,18 @@
<p>
Furthermore, directory entries in jar files aren't copied, unless you
specify the option <a
- href="usage.html#keepdirectories"><code>-keepdirectories</code></a>.</dd>
+ href="usage.html#keepdirectories"><code>-keepdirectories</code></a>.
+ Note that Sun advises against calling <code>Class.getResource()</code> for
+ directories (<a href="http://bugs.sun.com/view_bug.do?bug_id=4761949">Sun
+ Bug #4761949</a>).</dd>
+
+<dt><a name="disappearingannotations"><b>Disappearing annotations</b></a></dt>
+
+<dd>By default, the obfuscation step removes all annotations. If your
+ application relies on annotations to function properly, you should
+ explicitly keep them with
+ <code><a href="usage.html#keepattributes">-keepattributes</a>
+ *Annotation*</code>.</dd>
<dt><a name="invalidjarfile"><b>Invalid or corrupt jarfile</b></a></dt>
@@ -474,6 +591,17 @@
manifest file is the one that is copied (the first manifest file that is
encountered), and that the main class is kept in your configuration,</dd>
+<dt><a name="invalidjarindexexception"><b>InvalidJarIndexException: Invalid index</b></a></dt>
+
+<dd>At least one of your processed jar files contains an index file
+ <code>META-INF/INDEX.LIST</code>, listing all class files in the jar.
+ ProGuard by default copies files like these unchanged. ProGuard may however
+ remove or rename classes, thus invalidating the file. You should filter the
+ index file out of the input
+ (<code>-injars in.jar(!META-INF/INDEX.LIST)</code>) or update the file
+ after having applied ProGuard (<code>jar -i out.jar</code>).
+ </dd>
+
<dt><a name="invalidclassexception2"><b>InvalidClassException</b>, <b>class loading error</b>, or <b>verification error</b> (in Java Micro Edition)</a></dt>
<dd>If you get such an error in Java Micro Edition, you may have forgotten to
@@ -526,7 +654,7 @@
<dd>You may have forgotten to sign your program jar <i>after</i> having
processed it with ProGuard.</dd>
-<dt><a name="classcastexception"><b>ClassCastException: class not an enum</b>, or <br><b>IllegalArgumentException: class not an enum type</b></a></dt>
+<dt><a name="classcastexception"><b>ClassCastException: class not an enum</b>, or <br /><b>IllegalArgumentException: class not an enum type</b></a></dt>
<dd>You should make sure you're preserving the special methods of enumeration
types, which the run-time environment calls by introspection. The required
@@ -548,7 +676,7 @@
<code>sun.tools.java.MethodSet.add</code> in Sun's JDK 1.2.2, which is
used for (dynamic) compilation. You should then avoid this option.</dd>
-<dt><a name="classformaterror"><b>ClassFormatError: repetitive field name/signature</b></a></dt>
+<dt><a name="classformaterror1"><b>ClassFormatError: repetitive field name/signature</b></a></dt>
<dd>You are probably processing some code that has been obfuscated before with
the <a
@@ -556,6 +684,14 @@
option. You should then use the same option again in the second processing
round.</dd>
+<dt><a name="classformaterror2"><b>ClassFormatError: Invalid index in LocalVariableTable in class file</b></a></dt>
+
+<dd>If you are keeping the <code>LocalVariableTable</code> or
+ <code>LocalVariableTypeTable</code> attributes, ProGuard's optimizing step
+ is sometimes unable to update them consistently. You should then let the
+ obfuscation step remove these attributes or disable the optimization
+ step.</dd>
+
<dt><a name="nosuchmethoderror"><b>NoSuchMethodError</b> or <b>AbstractMethodError</b></a></dt>
<dd>You should make sure you're not writing your output class files to a
@@ -583,10 +719,11 @@
</dl>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/usage.html b/docs/manual/usage.html
index 8be8d60..d84810e 100644
--- a/docs/manual/usage.html
+++ b/docs/manual/usage.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Usage</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -15,55 +26,53 @@
<code><b>java -jar proguard.jar </b></code><i>options</i> ...
</p>
You can find the ProGuard jar in the <code>lib</code> directory of the
-ProGuard distribution. Options can also be put in one or more configuration
-files. Typically, you'll put most options in a configuration file (say,
-<code>myconfig.pro</code>), and just call:
+ProGuard distribution. Alternatively, the <code>bin</code> directory contains
+some short Linux and Windows scripts containing this command. Typically, you'll
+put most options in a configuration file (say, <code>myconfig.pro</code>), and
+just call:
<p class="code">
<code><b>java -jar proguard.jar @myconfig.pro</b></code>
</p>
-You can combine command line options and options from configuration files, for
+You can combine command line options and options from configuration files. For
instance:
<p class="code">
<code><b>java -jar proguard.jar @myconfig.pro -verbose</b></code>
</p>
<p>
-In a configuration file, a <code><b>#</b></code> sign and all remaining
-characters on that line are ignored, allowing you to add comments.
+You can add comments in a configuration file, starting with a
+<code><b>#</b></code> character and continuing until the end of the line.
<p>
-Extra whitespace between words and delimiters is ignored. To specify file
-names with spaces or special characters, words can be quoted with single or
-double quotes. Note that the quotes may need to be escaped when used on the
-command line, to avoid them being gobbled by the shell.
+Extra whitespace between words and delimiters is ignored. File names with
+spaces or special characters should be quoted with single or double quotes.
<p>
Options can be grouped arbitrarily in arguments on the command line and in
-lines in configuration files. This means that you can quote any arbitrary
-section of command line options, to avoid shell expansion of special
-characters, for instance.
+lines in configuration files. This means that you can quote arbitrary sections
+of command line options, to avoid shell expansion of special characters, for
+instance.
<p>
-The order of the options is generally irrelevant. They can be abbreviated to
-their first unique characters.
+The order of the options is generally irrelevant. For quick experiments, you
+can abbreviate them to their first unique characters.
<p>
The sections below provide more details:
<ul>
-<li><a href="#iooptions">Input/Output Options</a>
-<li><a href="#keepoptions">Keep Options</a>
-<li><a href="#shrinkingoptions">Shrinking Options</a>
-<li><a href="#optimizationoptions">Optimization Options</a>
-<li><a href="#obfuscationoptions">Obfuscation Options</a>
-<li><a href="#preverificationoptions">Preverification Options</a>
-<li><a href="#generaloptions">General Options</a>
-<li><a href="#classpath">Class Paths</a>
-<li><a href="#filename">File Names</a>
-<li><a href="#filefilters">File Filters</a>
-<li><a href="#filters">Filters</a>
-<li><a href="#keepoverview">Overview of <code>Keep</code> Options</a>
-<li><a href="#keepoptionmodifiers">Keep Option Modifiers</a>
-<li><a href="#classspecification">Class Specifications</a>
+<li><a href="#iooptions">Input/Output Options</a></li>
+<li><a href="#keepoptions">Keep Options</a></li>
+<li><a href="#shrinkingoptions">Shrinking Options</a></li>
+<li><a href="#optimizationoptions">Optimization Options</a></li>
+<li><a href="#obfuscationoptions">Obfuscation Options</a></li>
+<li><a href="#preverificationoptions">Preverification Options</a></li>
+<li><a href="#generaloptions">General Options</a></li>
+<li><a href="#classpath">Class Paths</a></li>
+<li><a href="#filename">File Names</a></li>
+<li><a href="#filefilters">File Filters</a></li>
+<li><a href="#filters">Filters</a></li>
+<li><a href="#keepoverview">Overview of <code>Keep</code> Options</a></li>
+<li><a href="#keepoptionmodifiers">Keep Option Modifiers</a></li>
+<li><a href="#classspecification">Class Specifications</a></li>
</ul>
-<a name="iooptions"> </a>
-<h2>Input/Output Options</h2>
+<h2><a name="iooptions">Input/Output Options</a></h2>
<dl>
<dt><a name="at"><code><b>@</b></code></a><a href="#filename"><i>filename</i></a></dt>
@@ -135,24 +144,28 @@
href="examples.html#midlet">JME midlets</a>, just by specifying the
appropriate run-time jar.</dd>
+<dt><a name="skipnonpubliclibraryclasses"><code><b>-skipnonpubliclibraryclasses</b></code></a></dt>
+
+<dd>Specifies to skip non-public classes while reading library jars, to speed
+ up processing and reduce memory usage of ProGuard. By default, ProGuard
+ reads non-public and public library classes alike. However, non-public
+ classes are often not relevant, if they don't affect the actual program
+ code in the input jars. Ignoring them then speeds up ProGuard, without
+ affecting the output. Unfortunately, some libraries, including recent JSE
+ run-time libraries, contain non-public library classes that are extended
+ by public library classes. You then can't use this option. ProGuard will
+ print out warnings if it can't find classes due to this option being
+ set.</dd>
+
<dt><a name="dontskipnonpubliclibraryclasses"><code><b>-dontskipnonpubliclibraryclasses</b></code></a></dt>
-<dd>Specifies not to ignore non-public library classes. By default, non-public
- library classes are skipped while parsing library jars. The classes are
- typically not relevant during processing, since they don't affect the
- actual program code in the input jars. Ignoring them reduces memory usage
- and processing time. Occasionally, a badly designed library may contain a
- non-public library class that is extended/implemented by a public library
- class. If the latter library class in turn is extended/implemented by a
- program class, ProGuard will complain that it can't find the non-public
- library class, which it had ignored during parsing. This option will
- overcome that problem, at the cost of greater memory usage and longer
- processing time.</dd>
+<dd>Specifies not to ignore non-public library classes. As of version 4.5, this
+ is the default setting.</dd>
<dt><a name="dontskipnonpubliclibraryclassmembers"><code><b>-dontskipnonpubliclibraryclassmembers</b></code></a></dt>
<dd>Specifies not to ignore package visible library class members (fields and
- methods). By default, these class members are skipped while parsing
+ methods). By default, ProGuard skips these class members while parsing
library classes, as program classes will generally not refer to them.
Sometimes however, program classes reside in the same packages as library
classes, and they do refer to their package visible class members. In
@@ -174,11 +187,11 @@
<dd>Specifies the version number to be set in the processed class files. The
version number can be one of <code>1.0</code>, <code>1.1</code>,
<code>1.2</code>, <code>1.3</code>, <code>1.4</code>, <code>1.5</code> (or
- just <code>5</code>), or <code>1.6</code> (or just <code>6</code>). By
- default, the version numbers of the class files are left unchanged. For
- example, you may want to <a href="examples.html#upgrade">upgrade class
- files to Java 6</a>, by changing their version numbers and having them
- preverified.</dd>
+ just <code>5</code>), <code>1.6</code> (or just <code>6</code>), or
+ <code>1.7</code> (or just <code>7</code>). By default, the version numbers
+ of the class files are left unchanged. For example, you may want to
+ <a href="examples.html#upgrade">upgrade class files to Java 6</a>, by
+ changing their version numbers and having them preverified.</dd>
<dt><a name="forceprocessing"><code><b>-forceprocessing</b></code></a></dt>
@@ -189,8 +202,7 @@
</dl>
<p>
-<a name="keepoptions"> </a>
-<h2>Keep Options</h2>
+<h2><a name="keepoptions">Keep Options</a></h2>
<dl>
<dt><a name="keep"><code><b>-keep</b></code></a>
@@ -245,11 +257,11 @@
<p>
Specifies class members whose names are to be preserved, if they aren't
removed in the shrinking phase. For example, you may want to preserve the
- name of the synthetic <code>class$</code> methods when <a
- href="examples.html#library">processing a library</a>, so obfuscators can
- detect it again when processing an application that uses the processed
- library (although ProGuard itself doesn't need this). Only applicable when
- obfuscating.</dd>
+ name of the synthetic <code>class$</code> methods
+ when <a href="examples.html#library">processing a library</a> compiled by
+ JDK 1.2 or older, so obfuscators can detect it again when processing an
+ application that uses the processed library (although ProGuard itself
+ doesn't need this). Only applicable when obfuscating.</dd>
<dt><a name="keepclasseswithmembernames"><code><b>-keepclasseswithmembernames</b></code></a>
<a href="#classspecification"><i>class_specification</i></a></dt>
@@ -280,8 +292,7 @@
</dl>
<p>
-<a name="shrinkingoptions"> </a>
-<h2>Shrinking Options</h2>
+<h2><a name="shrinkingoptions">Shrinking Options</a></h2>
<dl>
<dt><a name="dontshrink"><code><b>-dontshrink</b></code></a></dt>
@@ -319,8 +330,7 @@
</dl>
<p>
-<a name="optimizationoptions"> </a>
-<h2>Optimization Options</h2>
+<h2><a name="optimizationoptions">Optimization Options</a></h2>
<dl>
<dt><a name="dontoptimize"><code><b>-dontoptimize</b></code></a></dt>
@@ -401,14 +411,13 @@
<ul>
<li>Sun's JRE 1.3 may throw an <code>InternalError</code> when
encountering more than 256 <i>Miranda</i> methods (interface methods
- without implementations) in a class.
+ without implementations) in a class.</li>
</ul></dd>
</dl>
<p>
-<a name="obfuscationoptions"> </a>
-<h2>Obfuscation Options</h2>
+<h2><a name="obfuscationoptions">Obfuscation Options</a></h2>
<dl>
<dt><a name="dontobfuscate"><code><b>-dontobfuscate</b></code></a></dt>
@@ -443,7 +452,8 @@
piece of code. In such cases, you should consider whether you also need
the option <a
href="#useuniqueclassmembernames"><code>-useuniqueclassmembernames</code></a>.
- Only applicable when obfuscating.</dd>
+ Only a single mapping file is allowed. Only applicable when
+ obfuscating.</dd>
<dt><a name="obfuscationdictionary"><code><b>-obfuscationdictionary</b></code></a>
<a href="#filename"><i>filename</i></a></dt>
@@ -506,13 +516,13 @@
<ul>
<li>Sun's JDK 1.2.2 <code>javac</code> compiler produces an exception when
compiling with such a library (cfr. <a href=
- "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4216736">Bug
- #4216736</a>). You probably shouldn't use this option for processing
- libraries.
+ "http://bugs.sun.com/view_bug.do?bug_id=4216736">Bug #4216736</a>).
+ You probably shouldn't use this option for processing libraries.</li>
<li>Sun's JRE 1.4 and later fail to serialize objects with overloaded
- primitive fields.
+ primitive fields.</li>
<li>Sun's JRE 1.5 <code>pack200</code> tool reportedly has problems with
- overloaded class members.
+ overloaded class members.</li>
+ <li>Google's Dalvik VM can't handle overloaded static fields.</li>
</ul></dd>
<dt><a name="useuniqueclassmembernames"><code><b>-useuniqueclassmembernames</b></code></a></dt>
@@ -608,12 +618,24 @@
name can be specified as well, referring to the source name part of this
attribute. For example, you should at least keep the
<code>Exceptions</code>, <code>InnerClasses</code>, and
- <code>Signature</code> attributes when <a
- href="examples.html#library">processing a library</a>. As another example,
- you should keep the <code>SourceFile</code> and
- <code>LineNumberTable</code> attributes for <a
- href="examples.html#stacktrace">producing useful obfuscated stack
- traces</a>. Only applicable when obfuscating.</dd>
+ <code>Signature</code> attributes
+ when <a href="examples.html#library">processing a library</a>. You should
+ also keep the <code>SourceFile</code> and
+ <code>LineNumberTable</code> attributes
+ for <a href="examples.html#stacktrace">producing useful obfuscated stack
+ traces</a>. Finally, you may want
+ to <a href="examples.html#annotations">keep annotations</a> if your code
+ depends on them. Only applicable when obfuscating.</dd>
+
+<dt><a name="keepparameternames"><code><b>-keepparameternames</b></code></a></dt>
+
+<dd>Specifies to keep the parameter names and types of methods that are kept.
+ This option actually keeps trimmed versions of the debugging attributes
+ <code>LocalVariableTable</code> and
+ <code>LocalVariableTypeTable</code>. It can be useful when
+ <a href="examples.html#library">processing a library</a>. Some IDEs can
+ use the information to assist developers who use the library, for example
+ with tool tips or autocompletion. Only applicable when obfuscating.</dd>
<dt><a name="renamesourcefileattribute"><code><b>-renamesourcefileattribute</b></code></a>
[<i>string</i>]</dt>
@@ -665,8 +687,7 @@
</dl>
<p>
-<a name="preverificationoptions"> </a>
-<h2>Preverification Options</h2>
+<h2><a name="preverificationoptions">Preverification Options</a></h2>
<dl>
<dt><a name="dontpreverify"><code><b>-dontpreverify</b></code></a></dt>
@@ -690,8 +711,7 @@
</dl>
<p>
-<a name="generaloptions"> </a>
-<h2>General Options</h2>
+<h2><a name="generaloptions">General Options</a></h2>
<dl>
<dt><a name="verbose"><code><b>-verbose</b></code></a></dt>
@@ -749,8 +769,7 @@
</dl>
<p>
-<a name="classpath"> </a>
-<h2>Class Paths</h2>
+<h2><a name="classpath">Class Paths</a></h2>
ProGuard accepts a generalization of class paths to specify input files and
output files. A class path consists of entries, separated by the traditional
@@ -759,12 +778,12 @@
<p>
Each input entry can be:
<ul>
-<li>A class file or resource file.
-<li>A jar file, containing any of the above,
-<li>A war file, containing any of the above,
-<li>An ear file, containing any of the above,
-<li>A zip file, containing any of the above,
-<li>A directory (structure), containing any of the above.
+<li>A class file or resource file,</li>
+<li>A jar file, containing any of the above,</li>
+<li>A war file, containing any of the above,</li>
+<li>An ear file, containing any of the above,</li>
+<li>A zip file, containing any of the above,</li>
+<li>A directory (structure), containing any of the above.</li>
</ul>
<p>
The paths of directly specified class files and resource files is ignored, so
@@ -776,11 +795,11 @@
Each output entry can be:
<ul>
<li>A jar file, in which all processed class files and resource files will be
- collected.
-<li>A war file, in which any and all of the above will be collected,
-<li>An ear file, in which any and all of the above will be collected,
-<li>A zip file, in which any and all of the above will be collected,
-<li>A directory, in which any and all of the above will be collected.
+ collected.</li>
+<li>A war file, in which any and all of the above will be collected,</li>
+<li>An ear file, in which any and all of the above will be collected,</li>
+<li>A zip file, in which any and all of the above will be collected,</li>
+<li>A directory, in which any and all of the above will be collected.</li>
</ul>
<p>
When writing output entries, ProGuard will generally package the results in a
@@ -801,12 +820,12 @@
href="#filefilters">file filters</a> between parentheses, separated by
semi-colons:
<ul>
-<li>A filter for all zip names that are encountered,
-<li>A filter for all ear names that are encountered,
-<li>A filter for all war names that are encountered,
-<li>A filter for all jar names that are encountered,
+<li>A filter for all zip names that are encountered,</li>
+<li>A filter for all ear names that are encountered,</li>
+<li>A filter for all war names that are encountered,</li>
+<li>A filter for all jar names that are encountered,</li>
<li>A filter for all class file names and resource file names that are
- encountered.
+ encountered.</li>
</ul>
<p>
If fewer than 5 filters are specified, they are assumed to be the latter
@@ -840,16 +859,15 @@
for <a href="examples.html#filtering">filtering input and output</a>.
<p>
-<a name="filename"> </a>
-<h2>File Names</h2>
+<h2><a name="filename">File Names</a></h2>
ProGuard accepts absolute paths and relative paths for the various file names
and directory names. A relative path is interpreted as follows:
<ul>
-<li>relative to the base directory, if set, or otherwise
+<li>relative to the base directory, if set, or otherwise</li>
<li>relative to the configuration file in which it is specified, if any, or
- otherwise
-<li>relative to the working directory.
+ otherwise</li>
+<li>relative to the working directory.</li>
</ul>
<p>
The names can contain Java system properties delimited by '<b><</b>' and
@@ -872,8 +890,7 @@
"my program.jar":"/your directory/your program.jar"'</code>.
<p>
-<a name="filefilters"> </a>
-<h2>File Filters</h2>
+<h2><a name="filefilters">File Filters</a></h2>
Like general <a href="#filters">filters</a>, a file filter is a
comma-separated list of file names that can contain wildcards. Only files with
@@ -905,8 +922,7 @@
The Examples section provides a few more examples for <a
href="examples.html#filtering">filtering input and output</a>.
-<a name="filters"> </a>
-<h2>Filters</h2>
+<h2><a name="filters">Filters</a></h2>
ProGuard offers options with filters for many different aspects of the
configuration: names of files, directories, classes, packages, attributes,
@@ -944,8 +960,7 @@
<code>bar</code>, except <code>foobar</code>.
<p>
-<a name="keepoverview"> </a>
-<h2>Overview of <code>Keep</code> Options</h2>
+<h2><a name="keepoverview">Overview of <code>Keep</code> Options</a></h2>
The various <code>-keep</code> options for shrinking and obfuscation may seem
a bit confusing at first, but there's actually a pattern behind them. The
@@ -991,7 +1006,7 @@
<p>
<table>
<tr><td valign="top">
-<img src="attention.gif" width="64" height="64"alt="attention">
+<img src="attention.gif" width="64" height="64"alt="attention" />
</td><td>
Always remember:
<ul>
@@ -1005,8 +1020,7 @@
</table>
<p>
-<a name="keepoptionmodifiers"> </a>
-<h2>Keep Option Modifiers</h2>
+<h2><a name="keepoptionmodifiers">Keep Option Modifiers</a></h2>
<dl>
<dt><a name="allowshrinking"><code><b>allowshrinking</b></code></a></dt>
@@ -1035,8 +1049,7 @@
</dl>
<p>
-<a name="classspecification"> </a>
-<h2>Class Specifications</h2>
+<h2><a name="classspecification">Class Specifications</a></h2>
A class specification is a template of classes and class members (fields and
methods). It is used in the various <code>-keep</code> options and in the
@@ -1071,15 +1084,15 @@
the intended meaning, but white-space is irrelevant in actual configuration
files.
<p>
-<ul>
+<ul class="spacious">
<li>The <code><b>class</b></code> keyword refers to any interface or class.
The <code><b>interface</b></code> keyword restricts matches to interface
classes. The <code><b>enum</b></code> keyword restricts matches to
enumeration classes. Preceding the <code><b>interface</b></code> or
<code><b>enum</b></code> keywords by a <code><b>!</b></code> restricts
- matches to classes that are not interfaces or enumerations, respectively.
- <p>
+ matches to classes that are not interfaces or enumerations,
+ respectively.</li>
<li>Every <i>classname</i> must be fully qualified, e.g.
<code>java.lang.String</code>. Class names may be specified as regular
@@ -1120,22 +1133,19 @@
should be used with moderation.
<p>
For convenience and for backward compatibility, the class name
- <code><b>*</b></code> refers to any class, irrespective of its package.
- <p>
+ <code><b>*</b></code> refers to any class, irrespective of its package.</li>
<li>The <code><b>extends</b></code> and <code><b>implements</b></code>
specifications are typically used to restrict classes with wildcards. They
are currently equivalent, specifying that only classes extending or
implementing the given class qualify. Note that the given class itself is
not included in this set. If required, it should be specified in a
- separate option.
- <p>
+ separate option.</li>
<li>The <code><b>@</b></code> specifications can be used to restrict classes
and class members to the ones that are annotated with the specified
annotation types. An <i>annotationtype</i> is specified just like a
- <i>classname</i>.
- <p>
+ <i>classname</i>.</li>
<li>Fields and methods are specified much like in Java, except that method
argument lists don't contain argument names (just like in other tools
@@ -1198,13 +1208,11 @@
<code>***</code> wildcards will match array types of any dimension. For
example, "<code>** get*()</code>" matches "<code>java.lang.Object
getObject()</code>", but not "<code>float getFloat()</code>", nor
- "<code>java.lang.Object[] getObjects()</code>".
- <p>
+ "<code>java.lang.Object[] getObjects()</code>".</li>
<li>Constructors can also be specified using their short class names (without
package) or using their full class names. As in the Java language, the
- constructor specification has an argument list, but no return type.
- <p>
+ constructor specification has an argument list, but no return type.</li>
<li>The class access modifiers and class member access modifiers are typically
used to restrict wildcarded classes and class members. They specify that
@@ -1218,14 +1226,18 @@
which case at least one of them has to be set (e.g. at least
<code>public</code>
<i>or</i> <code>protected</code>).
+ <p>
+ ProGuard supports the additional modifiers <code><b>synthetic</b></code>,
+ <code><b>bridge</b></code>, and <code><b>varargs</b></code>, which may be
+ set by compilers.</li>
</ul>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/manual/wtk.html b/docs/manual/wtk.html
index b8c70b5..196b9ca 100644
--- a/docs/manual/wtk.html
+++ b/docs/manual/wtk.html
@@ -1,16 +1,27 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard JME Wireless Toolkit Integration</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("../index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
<h2>JME Wireless Toolkit Integration</h2>
-<b>ProGuard</b> can be seamlessly integrated in Sun's Wireless Toolkit (WTK)
+<b>ProGuard</b> can be seamlessly integrated in Oracle's Wireless Toolkit (WTK)
for Java Micro Edition (JME).
<p>
@@ -49,10 +60,11 @@
you can adapt the configuration file <code>proguard/wtk/default.pro</code>
that's inside the <code>proguard.jar</code>.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="../index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/quality.html b/docs/quality.html
index 29889e3..a8bbf05 100644
--- a/docs/quality.html
+++ b/docs/quality.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Quality</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -31,14 +42,15 @@
<p>
In addition, <b>ProGuard</b> is tested against a constantly growing test suite
-(more than 500 tests at this time of writing). These small programs contain a
+(more than 900 tests at this time of writing). These small programs contain a
wide range of common and uncommon constructs, in order to detect any regression
problems as soon as possible.
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/results.html b/docs/results.html
index 480cd4f..ca833ac 100644
--- a/docs/results.html
+++ b/docs/results.html
@@ -1,10 +1,22 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Results</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
+<title>ProGuard Results</title>
</head>
<body>
@@ -31,7 +43,7 @@
</tr>
<tr>
-<td><a target="other" href="http://java.sun.com/j2me/">Worm</a>, a sample midlet from Sun's JME</td>
+<td><a target="other" href="http://www.oracle.com/technetwork/java/javame/">Worm</a>, a sample midlet from Oracle's JME</td>
<td align="center">10.3 K</td>
<td align="center">9.8 K</td>
<td align="center">9.6 K</td>
@@ -75,7 +87,7 @@
</tr>
<tr>
-<td><a target="other" href="http://java.sun.com/javase/6/">the run-time classes</a> from Sun's Java 6</td>
+<td><a target="other" href="http://java.sun.com/javase/6/">the run-time classes</a> from Oracle's Java 6</td>
<td align="center">53 M</td>
<td align="center">23 M</td>
<td align="center">22 M</td>
@@ -86,7 +98,7 @@
</tr>
<tr>
-<td><a target="other" href="http://jakarta.apache.org/tomcat/index.html">Tomcat</a>, the Apache servlet container</td>
+<td><a target="other" href="http://tomcat.apache.org/">Tomcat</a>, the Apache servlet container</td>
<td align="center">1.1 M</td>
<td align="center">466 K</td>
<td align="center">426 K</td>
@@ -97,7 +109,7 @@
</tr>
<tr>
-<td><a target="other" href="http://www.kclee.com/clemens/java/javancss/">JavaNCSS</a>, a Java source metrics tool</td>
+<td><a target="other" href="http://javancss.codehaus.org/">JavaNCSS</a>, a Java source metrics tool</td>
<td align="center">632 K</td>
<td align="center">242 K</td>
<td align="center">212 K</td>
@@ -121,7 +133,8 @@
</table>
<p>
Results were measured with ProGuard 4.0 on a 2.6 GHz Pentium 4 with 512 MB
-of memory, using Sun JDK 1.5.0 in Fedora Core 3 Linux.
+of memory, using Sun JDK 1.5.0 in Fedora Core 3 Linux. All of this technology
+and software has evolved since, but the gist of the results remains the same.
<p>
The program sizes include companion libraries. The shrinking step produces the
best results for programs that use only small parts of their libraries. The
@@ -145,10 +158,12 @@
Memory usage (the amount of physical memory used by ProGuard while processing)
is governed by the basic java virtual machine and by the total size of the
library jars and program jars.
-<hr>
+
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/saikoalogo.png b/docs/saikoalogo.png
new file mode 100644
index 0000000..5b34172
--- /dev/null
+++ b/docs/saikoalogo.png
Binary files differ
diff --git a/docs/sanawarelogo.png b/docs/sanawarelogo.png
deleted file mode 100644
index bf7218b..0000000
--- a/docs/sanawarelogo.png
+++ /dev/null
Binary files differ
diff --git a/docs/screenshots.html b/docs/screenshots.html
index 8718839..64805a9 100644
--- a/docs/screenshots.html
+++ b/docs/screenshots.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Screenshots</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -13,7 +24,7 @@
<table><tr><td>
<a href="screenshot_gui1.gif" target="other">
<img src="screenshots_gui_small.gif" width="320" height="223" align="right"
- alt="GUI screenshot" usemap="#guimap"></a>
+ alt="GUI screenshot" usemap="#guimap" /></a>
<map id="guimap" name="guimap">
<area shape="rect" coords="2,7,46,16" alt="ProGuard" href="screenshot_gui1.gif" target="other">
@@ -36,21 +47,21 @@
<tr><td>
<a href="screenshot_console.gif" target="other">
<img src="screenshot_console_small.gif" width="320" height="268" align="left"
- alt="Console screenshot"></a>
+ alt="Console screenshot" /></a>
Of course, real developers don't need all this point-and-click fluff. They
-write a short configuration file using their favorite text editor and invoke
+write short configuration files using their favorite text editors and invoke
<b>ProGuard</b> from the command-line.
<p>
You can click on the image to see the full-size version.
</td></tr></table>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
</html>
diff --git a/docs/sections.html b/docs/sections.html
index d955d33..622277a 100644
--- a/docs/sections.html
+++ b/docs/sections.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -37,26 +37,28 @@
document.write(document.location.hostname == "proguard.sourceforge.net" ?
"http://sourceforge.net/sflogo.php?group_id=54750&type=1" :
"sflogo.png");
-document.write("\" width=\"88\" height=\"31\" alt=\"SourceForge\">");
-if (document.location.hostname == "proguard.sourceforge.net") {
- document.write("<script type=\"text/javascript\" src=\"http://sourceforge.net/apps/piwik/proguard/piwik.js\"></scri"+"pt>");
- document.write("<script type=\"text/javascript\">piwik_log(\"\", 1, \"http://sourceforge.net/apps/piwik/proguard/piwik.php\");</scri"+"pt>");
-}
+document.write("\" width=\"88\" height=\"31\" alt=\"SourceForge\" />");
//-->
</script>
<noscript>
-<img src="sflogo.png" width="88" height="31" alt="SourceForge">
+<img src="sflogo.png" width="88" height="31" alt="SourceForge" />
</noscript>
</a>
<p>
-<a href="http://www.luciad.com/" target="other">
-<img src="luciadlogo.png" width="88" height="24" alt="Luciad"></a>
-<p>
-<a href="http://www.javadocking.com/" target="other">
-<img src="sanawarelogo.png" width="88" height="24" alt="Sanaware"></a>
+<a href="http://www.saikoa.com/" target="_top">
+<img src="saikoalogo.png" width="88" height="19" alt="Saikoa" /></a>
</center>
+<script type="text/javascript">
+base = "http://sourceforge.net/apps/piwik/proguard/";
+if (document.location.hostname == "proguard.sourceforge.net")
+ document.write(unescape("%3Cscript src='"+base+"piwik.js' type='text/javascript'%3E%3C/script%3E"));
+</script><script type="text/javascript">
+if (document.location.hostname == "proguard.sourceforge.net")
+ piwik_log('', 1, base+"piwik.php");
+</script>
+
</body>
</html>
diff --git a/docs/style.css b/docs/style.css
index c9798db..dd8418d 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -52,6 +52,11 @@
padding: 8px;
}
+ul.spacious li
+{
+ padding: 8px;
+}
+
a
{
text-decoration: none;
@@ -62,13 +67,21 @@
border: none;
}
+a.button {
+ color: #000000;
+ text-decoration: none;
+ background: #E0E0E0;
+ border: 1px outset #FFFFFF;
+ float: right;
+}
+
/* Settings for the introductory paragraph. */
p.intro
{
background: #EEEEFF;
padding: 10px;
- border: solid #000000 1px
+ border: 1px solid #000000;
}
/* Settings for the title frame. */
diff --git a/docs/testimonials.html b/docs/testimonials.html
index 6971617..d37ddcd 100644
--- a/docs/testimonials.html
+++ b/docs/testimonials.html
@@ -1,10 +1,21 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta http-equiv="content-style-type" content="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<title>ProGuard Testimonials</title>
+<script type="text/javascript" language="JavaScript">
+<!--
+if (window.self==window.top)
+ window.top.location.replace("index.html#"+window.location.pathname+window.location.hash);
+else {
+ var hash="#"+window.location.pathname.replace(window.top.location.pathname.replace("index.html", ""), "");
+ if (window.top.location.hash!=hash)
+ window.top.location.hash=hash;
+}
+//-->
+</script>
</head>
<body>
@@ -14,11 +25,11 @@
<p>
<b>ProGuard</b> is probably the most popular java shrinker, optimizer, and
obfuscator world-wide. It is being used by developers at companies and
-organizations like Sun, IBM, HP, Siemens, Nokia, Google, and NATO. It is the
-default tool in many development environments like Sun's Wireless Toolkit,
-Netbeans, EclipseME, and more. Although the quotes below probably don't
-represent official views of any kind, encouragements like these do keep me
-happy.
+organizations like IBM, HP, Siemens, Nokia, Google, and NATO. It is the
+default tool in many development environments like Oracle's Wireless Toolkit,
+Netbeans, EclipseME, Google's Android SDK, and more. Although the quotes below
+probably don't represent official views of any kind, encouragements like these
+do keep me happy.
<p>
<center><table class="note">
@@ -26,9 +37,9 @@
ProGuard is <b>the</b> ultimate java obfuscator!
</cite></p>
<p class="author">P.S, IBM</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -38,9 +49,9 @@
ProGuard is pure quality - powerful and trouble-free.
</cite></p>
<p class="author">M.B., Statestep</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -50,9 +61,9 @@
It is the simplest and most robust obfuscator we have ever used.
</cite></p>
<p class="author">I.I., Hewlett-Packard</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -62,9 +73,9 @@
ProGuard rules. Much easier to use than the commercial alternatives.
</cite></p>
<p class="author">B.G., Quiotix Corp.</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -77,9 +88,9 @@
and accurate shrinker of them all.
</cite></p>
<p class="author">D.J., Joot</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -93,9 +104,9 @@
development toolbox.
</cite></p>
<p class="author">J.K., Sun</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
<p>
@@ -106,16 +117,16 @@
You could've been rich.
</cite></p>
<p class="author">My mother</p></td>
-<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
-<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
-<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100" /></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8" /></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8" /></td>
</tr></table></center>
-<p>
-<hr>
+<hr />
+<noscript><div><a target="_top" href="index.html" class="button">Show menu</a></div></noscript>
<address>
-Copyright © 2002-2009
-<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+Copyright © 2002-2011
+<a target="other" href="http://www.lafortune.eu/">Eric Lafortune</a>.
</address>
</body>
diff --git a/docs/title.html b/docs/title.html
index 33171b5..50838b1 100644
--- a/docs/title.html
+++ b/docs/title.html
@@ -1,4 +1,4 @@
-<!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
@@ -9,8 +9,8 @@
<body class="title">
<div class="title">
-<h1><img src="title.gif" width="154" height="29" alt="ProGuard"></h1>
-<div>Version 4.4</div>
+<h1><img src="title.gif" width="154" height="29" alt="ProGuard" /></h1>
+<div>Version 4.7</div>
</div>
</body>
diff --git a/examples/android.pro b/examples/android.pro
new file mode 100644
index 0000000..a502a2b
--- /dev/null
+++ b/examples/android.pro
@@ -0,0 +1,149 @@
+#
+# This ProGuard configuration file illustrates how to process Android
+# applications.
+# Usage:
+# java -jar proguard.jar @android.pro
+#
+# If you're using the Android SDK (version 2.3 or higher), the android tool
+# already creates a file like this in your project, called proguard.cfg.
+# It should contain the settings of this file, minus the input and output paths
+# (-injars, -outjars, -libraryjars, -printmapping, and -printseeds).
+# The generated Ant build file automatically sets these paths.
+
+# Specify the input jars, output jars, and library jars.
+# Note that ProGuard works with Java bytecode (.class),
+# before the dex compiler converts it into Dalvik code (.dex).
+
+-injars bin/classes
+-injars libs
+-outjars bin/classes-processed.jar
+
+-libraryjars /usr/local/android-sdk/platforms/android-9/android.jar
+#-libraryjars /usr/local/android-sdk/add-ons/google_apis-7_r01/libs/maps.jar
+# ...
+
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on.
+
+-printmapping bin/classes-processed.map
+
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds bin/classes-processed.seeds
+
+# Preverification is irrelevant for the dex compiler and the Dalvik VM.
+
+-dontpreverify
+
+# Reduce the size of the output some more.
+
+-repackageclasses ''
+-allowaccessmodification
+
+# Switch off some optimizations that trip older versions of the Dalvik VM.
+
+-optimizations !code/simplification/arithmetic
+
+# Keep a fixed source file attribute and all line number tables to get line
+# numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
+
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
+
+# RemoteViews might need annotations.
+
+-keepattributes *Annotation*
+
+# Preserve all fundamental application classes.
+
+-keep public class * extends android.app.Activity
+-keep public class * extends android.app.Application
+-keep public class * extends android.app.Service
+-keep public class * extends android.content.BroadcastReceiver
+-keep public class * extends android.content.ContentProvider
+
+# Preserve all View implementations, their special context constructors, and
+# their setters.
+
+-keep public class * extends android.view.View {
+ public <init>(android.content.Context);
+ public <init>(android.content.Context, android.util.AttributeSet);
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+ public void set*(...);
+}
+
+# Preserve all classes that have special context constructors, and the
+# constructors themselves.
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+}
+
+# Preserve all classes that have special context constructors, and the
+# constructors themselves.
+
+-keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+}
+
+# Preserve the special fields of all Parcelable implementations.
+
+-keepclassmembers class * implements android.os.Parcelable {
+ static android.os.Parcelable$Creator CREATOR;
+}
+
+# Preserve static fields of inner classes of R classes that might be accessed
+# through introspection.
+
+-keepclassmembers class **.R$* {
+ public static <fields>;
+}
+
+# Preserve the required interface from the License Verification Library
+# (but don't nag the developer if the library is not used at all).
+
+-keep public interface com.android.vending.licensing.ILicensingService
+
+-dontnote com.android.vending.licensing.ILicensingService
+
+# The Android Compatibility library references some classes that may not be
+# present in all versions of the API, but we know that's ok.
+
+-dontwarn android.support.**
+
+# Preserve all native method names and the names of their classes.
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+# Preserve the special static methods that are required in all enumeration
+# classes.
+
+-keepclassmembers class * extends java.lang.Enum {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+# Explicitly preserve all serialization members. The Serializable interface
+# is only a marker interface, so it wouldn't save them.
+# You can comment this out if your application doesn't use serialization.
+# If your code contains serializable classes that have to be backward
+# compatible, please refer to the manual.
+
+-keepclassmembers class * implements java.io.Serializable {
+ static final long serialVersionUID;
+ static final java.io.ObjectStreamField[] serialPersistentFields;
+ private void writeObject(java.io.ObjectOutputStream);
+ private void readObject(java.io.ObjectInputStream);
+ java.lang.Object writeReplace();
+ java.lang.Object readResolve();
+}
+
+# Your application may contain more items that need to be preserved;
+# typically classes that are dynamically created using Class.forName:
+
+# -keep public class mypackage.MyClass
+# -keep public interface mypackage.MyInterface
+# -keep public class * implements mypackage.MyInterface
diff --git a/examples/annotations/examples.pro b/examples/annotations/examples.pro
index 270092a..3a47183 100644
--- a/examples/annotations/examples.pro
+++ b/examples/annotations/examples.pro
@@ -8,8 +8,7 @@
# Specify the input, output, and library jars.
# This is assuming the code has been compiled in the examples directory.
-#-injars examples(*.class)
--injars classes(*.class)
+-injars examples(*.class)
-outjars out
-libraryjars <java.home>/lib/rt.jar
diff --git a/examples/annotations/lib/annotations.jar b/examples/annotations/lib/annotations.jar
index 967d604..36f6356 100644
--- a/examples/annotations/lib/annotations.jar
+++ b/examples/annotations/lib/annotations.jar
Binary files differ
diff --git a/examples/ant/android-8.xml b/examples/ant/android-8.xml
new file mode 100644
index 0000000..3a4316b
--- /dev/null
+++ b/examples/ant/android-8.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="MyAndroidApp" default="help">
+
+<!-- The local.properties file is created and updated by the 'android'
+ tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The build.properties file can be created by you and is never touched
+ by the 'android' tool. This is the place to change some of the
+ default property values used by the Ant rules.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="build.properties" />
+
+ <!-- The default.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <property file="default.properties" />
+
+ <!-- Custom Android task to deal with the project target, and import the
+ proper rules.
+ This requires ant 1.6.0 or above. -->
+ <path id="android.antlibs">
+ <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
+ <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
+ <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
+ </path>
+
+ <taskdef name="setup"
+ classname="com.android.ant.SetupTask"
+ classpathref="android.antlibs" />
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ [This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir}]
+ <target name="-post-compile">
+ </target>
+-->
+
+
+ <!-- Execute the Android Setup task that will setup some properties
+ specific to the target, and import the build rules files.
+
+ The rules file is imported from
+ <SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <setup> task.
+ - customize it to your needs.
+ - Customize the whole script.
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, *after* the <setup> task
+ - disable the import of the rules by changing the setup task
+ below to <setup import="false" />.
+ - customize to your needs.
+ -->
+
+ <setup />
+
+ <!-- Define a place for the optimized classes. -->
+ <property name="out.proguard.absolute.jar"
+ location="${out.absolute.dir}/classes-processed.jar" />
+
+ <!-- Define a obfuscation mapping file. -->
+ <property name="out.proguard.absolute.map"
+ location="${out.absolute.dir}/classes-processed.map" />
+
+ <!-- Redefine the dex help macro, so it converts the optimized classes.. -->
+ <macrodef name="dex-helper">
+ <element name="external-libs" optional="yes" />
+ <element name="extra-parameters" optional="yes" />
+ <sequential>
+ <echo>Converting optimized files into ${intermediate.dex.file}...</echo>
+ <apply executable="${dx}" failonerror="true" parallel="true">
+ <arg value="--dex" />
+ <arg value="--output=${intermediate.dex.file}" />
+ <extra-parameters />
+ <arg line="${verbose.option}" />
+ <fileset file="${out.proguard.absolute.jar}" />
+ <external-libs />
+ </apply>
+ </sequential>
+ </macrodef>
+
+ <!-- Define the optimization target. -->
+ <taskdef resource="proguard/ant/task.properties"
+ classpath="/home/eric/ProGuard/releases/proguard4.5.1/lib/proguard.jar" />
+
+ <target name="-post-compile">
+ <echo>Optimizing compiled files and libraries into ${out.proguard.absolute.jar}...</echo>
+ <proguard printmapping="${out.proguard.absolute.map}">
+ <injar path="${out.classes.absolute.dir}" />
+ <injar path="${external.libs.absolute.dir}" />
+ <outjar path="${out.proguard.absolute.jar}" />
+ <libraryjar refid="android.target.classpath" />
+
+ -dontpreverify
+ -repackageclasses ''
+ -allowaccessmodification
+ -optimizations !code/simplification/arithmetic
+
+ <!--
+ -renamesourcefileattribute SourceFile
+ -keepattributes SourceFile,LineNumberTable
+ -->
+
+ -keepattributes *Annotation*
+
+ -keep public class * extends android.app.Activity
+ -keep public class * extends android.app.Application
+ -keep public class * extends android.app.Service
+ -keep public class * extends android.content.BroadcastReceiver
+ -keep public class * extends android.content.ContentProvider
+
+ -keep public class * extends android.view.View {
+ public <init>(android.content.Context);
+ public <init>(android.content.Context, android.util.AttributeSet);
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+ public void set*(...);
+ }
+
+ -keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet);
+ }
+
+ -keepclasseswithmembers class * {
+ public <init>(android.content.Context, android.util.AttributeSet, int);
+ }
+
+ -keepclassmembers class * implements android.os.Parcelable {
+ static android.os.Parcelable$Creator CREATOR;
+ }
+
+ -keepclassmembers class **.R$* {
+ public static <fields>;
+ }
+
+ -keep public interface com.android.vending.licensing.ILicensingService
+ -dontnote com.android.vending.licensing.ILicensingService
+
+ -keepclasseswithmembernames class * {
+ native <methods>;
+ }
+
+ -keepclassmembers class * extends java.lang.Enum {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+ }
+ </proguard>
+ </target>
+
+</project>
diff --git a/examples/ant/applets.xml b/examples/ant/applets.xml
index a55b1c3..4d0cb38 100644
--- a/examples/ant/applets.xml
+++ b/examples/ant/applets.xml
@@ -7,7 +7,9 @@
<taskdef resource="proguard/ant/task.properties"
classpath="lib/proguard.jar" />
- <proguard printseeds="on">
+ <proguard printseeds="on"
+ printmapping="out.map"
+ renamesourcefileattribute="SourceFile">
<!-- Specify the input jars, output jars, and library jars. -->
@@ -16,14 +18,19 @@
<libraryjar file="${java.home}/lib/rt.jar" />
- <!-- Preserve all public applets. -->
-
- <keep access="public" extends="java.applet.Applet" />
+ <!-- Optionally preserve line numbers in the obfuscated stack traces.
+ <keepattribute name="LineNumberTable">
+ <keepattribute name="SourceFile">
+ -->
<!-- Preserve all annotations. -->
<keepattribute name="*Annotation*" />
+ <!-- Preserve all public applets. -->
+
+ <keep access="public" extends="java.applet.Applet" />
+
<!-- Preserve all native method names and the names of their classes. -->
<keepclasseswithmembernames>
diff --git a/examples/ant/applications1.xml b/examples/ant/applications1.xml
index 7a3d473..6df5789 100644
--- a/examples/ant/applications1.xml
+++ b/examples/ant/applications1.xml
@@ -1,6 +1,6 @@
<!-- This Ant build file illustrates how to process applications,
by including a ProGuard-style configuration file.
- Usage: ant -f applications.xml -->
+ Usage: ant -f applications1.xml -->
<project name="Applications" default="obfuscate" basedir="../..">
diff --git a/examples/ant/applications2.xml b/examples/ant/applications2.xml
index 2e28f01..681a894 100644
--- a/examples/ant/applications2.xml
+++ b/examples/ant/applications2.xml
@@ -1,6 +1,6 @@
<!-- This Ant build file illustrates how to process applications,
by including ProGuard-style configuration options.
- Usage: ant -f applications.xml -->
+ Usage: ant -f applications2.xml -->
<project name="Applications" default="obfuscate" basedir="../..">
@@ -21,16 +21,22 @@
<!-- -libraryjars jai_core.jar -->
<!-- ... -->
+ <!-- Save the obfuscation mapping to a file, and preserve line numbers. -->
+
+ -printmapping out.map
+ -renamesourcefileattribute SourceFile
+ -keepattributes SourceFile,LineNumberTable
+
+ <!-- Preserve all annotations. -->
+
+ -keepattributes *Annotation*
+
<!-- Preserve all public applications. -->
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
- <!-- Preserve all annotations. -->
-
- -keepattributes *Annotation*
-
<!-- Preserve all native method names and the names of their classes. -->
-keepclasseswithmembernames class * {
diff --git a/examples/ant/applications3.xml b/examples/ant/applications3.xml
index d5501e0..e42eb39 100644
--- a/examples/ant/applications3.xml
+++ b/examples/ant/applications3.xml
@@ -1,6 +1,6 @@
<!-- This Ant build file illustrates how to process applications,
using a full-blown XML configuration.
- Usage: ant -f applications.xml -->
+ Usage: ant -f applications3.xml -->
<project name="Applications" default="obfuscate" basedir="../..">
@@ -8,7 +8,9 @@
<taskdef resource="proguard/ant/task.properties"
classpath="lib/proguard.jar" />
- <proguard printseeds="on">
+ <proguard printseeds="on"
+ printmapping="out.map"
+ renamesourcefileattribute="SourceFile">
<!-- Specify the input jars, output jars, and library jars. -->
@@ -21,6 +23,14 @@
<!-- libraryjar file="jai_core.jar" / -->
<!-- ... / -->
+ <!-- Preserve line numbers in the obfuscated stack traces. -->
+
+ <keepattribute name="LineNumberTable" />
+ <keepattribute name="SourceFile" />
+
+ <!-- Preserve all annotations. -->
+
+ <keepattribute name="*Annotation*" />
<!-- Preserve all public applications. -->
@@ -31,10 +41,6 @@
parameters="java.lang.String[]" />
</keepclasseswithmembers>
- <!-- Preserve all annotations. -->
-
- <keepattribute name="*Annotation*" />
-
<!-- Preserve all native method names and the names of their classes. -->
<keepclasseswithmembernames>
diff --git a/examples/ant/midlets.xml b/examples/ant/midlets.xml
index b17d036..223d0da 100644
--- a/examples/ant/midlets.xml
+++ b/examples/ant/midlets.xml
@@ -8,13 +8,15 @@
classpath="lib/proguard.jar" />
<proguard microedition="on"
+ printseeds="on"
+ printmapping="out.map"
overloadaggressively="on"
repackageclasses=""
allowaccessmodification="on"
- printseeds="on">
+ renamesourcefileattribute="SourceFile">
<!-- On Windows, you can't use mixed case class names,
- for the sake of the preverify tool.
+ should you still want to use the preverify tool.
usemixedcaseclassnames="false">
-->
@@ -23,8 +25,13 @@
<injar file="in.jar" />
<outjar file="out.jar" />
- <libraryjar file="/usr/local/java/wtk2.1/lib/midpapi20.jar" />
- <libraryjar file="/usr/local/java/wtk2.1/lib/cldcapi11.jar" />
+ <libraryjar file="/usr/local/java/wtk2.5.2/lib/midpapi20.jar" />
+ <libraryjar file="/usr/local/java/wtk2.5.2/lib/cldcapi11.jar" />
+
+ <!-- Optionally preserve line numbers in the obfuscated stack traces.
+ <keepattribute name="LineNumberTable">
+ <keepattribute name="SourceFile">
+ -->
<!-- Preserve all public midlets. -->
diff --git a/examples/ant/proguard.xml b/examples/ant/proguard.xml
index 315e628..f10764d 100644
--- a/examples/ant/proguard.xml
+++ b/examples/ant/proguard.xml
@@ -9,10 +9,10 @@
<taskdef resource="proguard/ant/task.properties"
classpath="lib/proguard.jar" />
- <proguard skipnonpubliclibraryclasses="off"
- printmapping="proguard.map"
+ <proguard printmapping="proguard.map"
overloadaggressively="on"
- repackageclasses="">
+ repackageclasses=""
+ renamesourcefileattribute="SourceFile">
<!-- Specify the input jars, output jars, and library jars. -->
@@ -23,8 +23,8 @@
<outjar file="examples/ant/proguard_out.jar" />
<libraryjar file="${java.home}/lib/rt.jar" />
- <libraryjar file="/usr/local/java/ant1.7.0/lib/ant.jar" />
- <libraryjar file="/usr/local/java/wtk2.1/wtklib/kenv.zip" />
+ <libraryjar file="/usr/local/java/ant/lib/ant.jar" />
+ <libraryjar file="/usr/local/java/wtk2.5.2/wtklib/kenv.zip" />
<!-- Adapt the resource file names, based on the corresponding obfuscated
class names. -->
@@ -32,6 +32,11 @@
<adaptresourcefilenames filter="**.properties,**.gif,**.jpg" />
<adaptresourcefilecontents filter="proguard/ant/task.properties" />
+ <!-- Optionally preserve line numbers in the obfuscated stack traces.
+ <keepattribute name="LineNumberTable">
+ <keepattribute name="SourceFile">
+ -->
+
<!-- The main seeds: ProGuard and its companion tool ReTrace. -->
<keep access="public" name="proguard.ProGuard">
diff --git a/examples/ant/servlets.xml b/examples/ant/servlets.xml
index 83af0f2..51bcaad 100644
--- a/examples/ant/servlets.xml
+++ b/examples/ant/servlets.xml
@@ -7,7 +7,9 @@
<taskdef resource="proguard/ant/task.properties"
classpath="lib/proguard.jar" />
- <proguard printseeds="on">
+ <proguard printseeds="on"
+ printmapping="proguard.map"
+ renamesourcefileattribute="SourceFile">
<!-- Specify the input jars, output jars, and library jars. -->
@@ -16,14 +18,19 @@
<libraryjar file="${java.home}/lib/rt.jar" />
- <!-- Keep all public servlets. -->
-
- <keep access="public" implements="javax.servlet.Servlet" />
+ <!-- Optionally preserve line numbers in the obfuscated stack traces.
+ <keepattribute name="LineNumberTable">
+ <keepattribute name="SourceFile">
+ -->
<!-- Preserve all annotations. -->
<keepattribute name="*Annotation*" />
+ <!-- Keep all public servlets. -->
+
+ <keep access="public" implements="javax.servlet.Servlet" />
+
<!-- Preserve all native method names and the names of their classes. -->
<keepclasseswithmembernames>
diff --git a/examples/applets.pro b/examples/applets.pro
index ee90db0..c5affc1 100644
--- a/examples/applets.pro
+++ b/examples/applets.pro
@@ -11,18 +11,27 @@
-libraryjars <java.home>/lib/rt.jar
-# Preserve all public applets.
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on. Keep a fixed source file attribute and all line number
+# tables to get line numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
--keep public class * extends java.applet.Applet
-
-# Print out a list of what we're preserving.
-
--printseeds
+-printmapping out.map
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
# Preserve all annotations.
-keepattributes *Annotation*
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds out.seeds
+
+# Preserve all public applets.
+
+-keep public class * extends java.applet.Applet
+
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
diff --git a/examples/applications.pro b/examples/applications.pro
index 29d8e43..f718088 100644
--- a/examples/applications.pro
+++ b/examples/applications.pro
@@ -15,20 +15,29 @@
#-libraryjars jai_core.jar
#...
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on. Keep a fixed source file attribute and all line number
+# tables to get line numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
+
+-printmapping out.map
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
+
+# Preserve all annotations.
+
+-keepattributes *Annotation*
+
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds out.seeds
+
# Preserve all public applications.
-keepclasseswithmembers public class * {
public static void main(java.lang.String[]);
}
-# Print out a list of what we're preserving.
-
--printseeds
-
-# Preserve all annotations.
-
--keepattributes *Annotation*
-
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
diff --git a/examples/dictionaries/shakespeare.txt b/examples/dictionaries/shakespeare.txt
old mode 100755
new mode 100644
diff --git a/examples/library.pro b/examples/library.pro
index 37be47e..b812082 100644
--- a/examples/library.pro
+++ b/examples/library.pro
@@ -15,10 +15,11 @@
# Save the obfuscation mapping to a file, so we can de-obfuscate any stack
# traces later on. Keep a fixed source file attribute and all line number
-# tables to actually get these stack traces.
+# tables to get line numbers in the stack traces.
# You can comment this out if you're not interested in stack traces.
-printmapping out.map
+-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
SourceFile,LineNumberTable,EnclosingMethod
diff --git a/examples/midlets.pro b/examples/midlets.pro
index bffc38e..1383980 100644
--- a/examples/midlets.pro
+++ b/examples/midlets.pro
@@ -9,8 +9,8 @@
-injars in.jar
-outjars out.jar
--libraryjars /usr/local/java/wtk2.1/lib/midpapi20.jar
--libraryjars /usr/local/java/wtk2.1/lib/cldcapi11.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/midpapi20.jar
+-libraryjars /usr/local/java/wtk2.5.2/lib/cldcapi11.jar
# Preverify the code suitably for Java Micro Edition.
@@ -34,14 +34,25 @@
#
# -dontusemixedcaseclassnames
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on.
+
+-printmapping out.map
+
+# You can keep a fixed source file attribute and all line number tables to
+# get stack traces with line numbers.
+
+#-renamesourcefileattribute SourceFile
+#-keepattributes SourceFile,LineNumberTable
+
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds out.seeds
+
# Preserve all public midlets.
-keep public class * extends javax.microedition.midlet.MIDlet
-# Print out a list of what we're preserving.
-
--printseeds
-
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
diff --git a/examples/proguard.pro b/examples/proguard.pro
index c48b87e..3b0a926 100644
--- a/examples/proguard.pro
+++ b/examples/proguard.pro
@@ -53,5 +53,5 @@
# If you want to preserve the WTK obfuscation plug-in, you'll have to specify
# the kenv.zip file.
-#-libraryjars /usr/local/java/wtk2.1/wtklib/kenv.zip
+#-libraryjars /usr/local/java/wtk2.5.2/wtklib/kenv.zip
#-keep public class proguard.wtk.ProGuardObfuscator
diff --git a/examples/proguardall.pro b/examples/proguardall.pro
index 8dc042e..da9c2b3 100644
--- a/examples/proguardall.pro
+++ b/examples/proguardall.pro
@@ -17,8 +17,8 @@
# You may have to adapt the paths below.
-libraryjars <java.home>/lib/rt.jar
--libraryjars /usr/local/java/ant1.5.0/lib/ant.jar
--libraryjars /usr/local/java/wtk2.1/wtklib/kenv.zip
+-libraryjars /usr/local/java/ant/lib/ant.jar
+-libraryjars /usr/local/java/wtk2.5.2/wtklib/kenv.zip
# Allow methods with the same signature, except for the return type,
# to get the same obfuscation name.
diff --git a/examples/proguardgui.pro b/examples/proguardgui.pro
index 2cb83ed..f14ce14 100644
--- a/examples/proguardgui.pro
+++ b/examples/proguardgui.pro
@@ -16,11 +16,6 @@
-libraryjars <java.home>/lib/rt.jar
-# In recent JREs, some public Swing classes depend on package visible classes,
-# so don't skip these package visible classes while parsing the library jar.
-
--dontskipnonpubliclibraryclasses
-
# If we wanted to reuse the previously obfuscated proguard_out.jar, we could
# perform incremental obfuscation based on its mapping file, and only keep the
# additional GUI files instead of all files.
diff --git a/examples/scala.pro b/examples/scala.pro
new file mode 100644
index 0000000..658fc77
--- /dev/null
+++ b/examples/scala.pro
@@ -0,0 +1,132 @@
+#
+# This ProGuard configuration file illustrates how to process Scala
+# applications, including the Scala runtime.
+# Usage:
+# java -jar proguard.jar @scala.pro
+#
+
+# Specify the input jars, output jars, and library jars.
+
+-injars in.jar
+-injars /usr/local/java/scala-2.9.1/lib/scala-library.jar
+#-injars /usr/local/java/scala-2.9.1/lib/scala-compiler.jar(!META-INF/MANIFEST.MF)
+#-injars /usr/local/java/scala-2.9.1/lib/jline.jar(!META-INF/MANIFEST.MF)
+-outjars out.jar
+
+-libraryjars <java.home>/lib/rt.jar
+#-libraryjars /usr/local/java/ant/lib/ant.jar
+#...
+
+# Ignore some compiler artefacts.
+
+-dontwarn scala.**
+
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on. Keep a fixed source file attribute and all line number
+# tables to get line numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
+
+-printmapping out.map
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
+
+# Preserve all annotations.
+
+-keepattributes *Annotation*
+
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds out.seeds
+
+# Preserve all public applications.
+
+-keepclasseswithmembers public class * {
+ public static void main(java.lang.String[]);
+}
+
+# Preserve some classes and class members that are accessed by means of
+# introspection.
+
+-keep class * implements org.xml.sax.EntityResolver
+
+-keepclassmembers class * {
+ ** MODULE$;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinPool {
+ long eventCount;
+ int workerCounts;
+ int runControl;
+ scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode syncStack;
+ scala.concurrent.forkjoin.ForkJoinPool$WaitQueueNode spareStack;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinWorkerThread {
+ int base;
+ int sp;
+ int runState;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.ForkJoinTask {
+ int status;
+}
+
+-keepclassmembernames class scala.concurrent.forkjoin.LinkedTransferQueue {
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference head;
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference tail;
+ scala.concurrent.forkjoin.LinkedTransferQueue$PaddedAtomicReference cleanMe;
+}
+
+# Preserve some classes and class members that are accessed by means of
+# introspection in the Scala compiler library, if it is processed as well.
+
+#-keep class * implements jline.Completor
+#-keep class * implements jline.Terminal
+
+#-keep class scala.tools.nsc.Global
+
+#-keepclasseswithmembers class * {
+# <init>(scala.tools.nsc.Global);
+#}
+
+#-keepclassmembers class * {
+# *** scala_repl_value();
+# *** scala_repl_result();
+#}
+
+# Preserve all native method names and the names of their classes.
+
+-keepclasseswithmembernames class * {
+ native <methods>;
+}
+
+# Preserve the special static methods that are required in all enumeration
+# classes.
+
+-keepclassmembers class * extends java.lang.Enum {
+ public static **[] values();
+ public static ** valueOf(java.lang.String);
+}
+
+# Explicitly preserve all serialization members. The Serializable interface
+# is only a marker interface, so it wouldn't save them.
+# You can comment this out if your application doesn't use serialization.
+# If your code contains serializable classes that have to be backward
+# compatible, please refer to the manual.
+
+-keepclassmembers class * implements java.io.Serializable {
+ static final long serialVersionUID;
+ static final java.io.ObjectStreamField[] serialPersistentFields;
+ private void writeObject(java.io.ObjectOutputStream);
+ private void readObject(java.io.ObjectInputStream);
+ java.lang.Object writeReplace();
+ java.lang.Object readResolve();
+}
+
+# Your application may contain more items that need to be preserved;
+# typically classes that are dynamically created using Class.forName:
+
+# -keep public class mypackage.MyClass
+# -keep public interface mypackage.MyInterface
+# -keep public class * implements mypackage.MyInterface
+
diff --git a/examples/servlets.pro b/examples/servlets.pro
index fdc36b0..b42b2e4 100644
--- a/examples/servlets.pro
+++ b/examples/servlets.pro
@@ -12,18 +12,27 @@
-libraryjars <java.home>/lib/rt.jar
-libraryjars /usr/local/java/servlet/servlet.jar
-# Preserve all public servlets.
+# Save the obfuscation mapping to a file, so you can de-obfuscate any stack
+# traces later on. Keep a fixed source file attribute and all line number
+# tables to get line numbers in the stack traces.
+# You can comment this out if you're not interested in stack traces.
--keep public class * implements javax.servlet.Servlet
-
-# Print out a list of what we're preserving.
-
--printseeds
+-printmapping out.map
+-renamesourcefileattribute SourceFile
+-keepattributes SourceFile,LineNumberTable
# Preserve all annotations.
-keepattributes *Annotation*
+# You can print out the seeds that are matching the keep options below.
+
+#-printseeds out.seeds
+
+# Preserve all public servlets.
+
+-keep public class * implements javax.servlet.Servlet
+
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
diff --git a/lib/proguard.jar b/lib/proguard.jar
index 3a9aebc..56d68ba 100644
--- a/lib/proguard.jar
+++ b/lib/proguard.jar
Binary files differ
diff --git a/lib/proguardgui.jar b/lib/proguardgui.jar
index 5866856..5cf8f81 100644
--- a/lib/proguardgui.jar
+++ b/lib/proguardgui.jar
Binary files differ
diff --git a/lib/retrace.jar b/lib/retrace.jar
index 8e42e5a..a872adb 100644
--- a/lib/retrace.jar
+++ b/lib/retrace.jar
Binary files differ
diff --git a/src/proguard/ArgumentWordReader.java b/src/proguard/ArgumentWordReader.java
index 89f3824..eb0e642 100644
--- a/src/proguard/ArgumentWordReader.java
+++ b/src/proguard/ArgumentWordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -32,7 +32,8 @@
public class ArgumentWordReader extends WordReader
{
private final String[] arguments;
- private int index = 0;
+
+ private int index = 0;
// /**
@@ -86,7 +87,7 @@
{
while (true)
{
- String word = reader.nextWord();
+ String word = reader.nextWord(false);
if (word == null)
System.exit(-1);
diff --git a/src/proguard/ClassPath.java b/src/proguard/ClassPath.java
index f4eeaad..6851a84 100644
--- a/src/proguard/ClassPath.java
+++ b/src/proguard/ClassPath.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ClassPathEntry.java b/src/proguard/ClassPathEntry.java
index 28483be..17f1f54 100644
--- a/src/proguard/ClassPathEntry.java
+++ b/src/proguard/ClassPathEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -20,6 +20,8 @@
*/
package proguard;
+import proguard.util.ListUtil;
+
import java.io.*;
import java.util.List;
@@ -44,7 +46,7 @@
/**
- * Creates a new ClassPathEntry with the given name and type.
+ * Creates a new ClassPathEntry with the given file and output flag.
*/
public ClassPathEntry(File file, boolean isOutput)
{
@@ -69,81 +71,212 @@
}
+ /**
+ * Returns the file.
+ */
public File getFile()
{
return file;
}
+ /**
+ * Sets the file.
+ */
public void setFile(File file)
{
this.file = file;
}
+ /**
+ * Returns whether this data entry is an output entry.
+ */
public boolean isOutput()
{
return output;
}
+ /**
+ * Specifies whether this data entry is an output entry.
+ */
public void setOutput(boolean output)
{
this.output = output;
}
+ /**
+ * Returns whether this data entry is a jar file.
+ */
+ public boolean isJar()
+ {
+ return hasExtension(".jar");
+ }
+
+
+ /**
+ * Returns whether this data entry is a war file.
+ */
+ public boolean isWar()
+ {
+ return hasExtension(".war");
+ }
+
+
+ /**
+ * Returns whether this data entry is a ear file.
+ */
+ public boolean isEar()
+ {
+ return hasExtension(".ear");
+ }
+
+
+ /**
+ * Returns whether this data entry is a zip file.
+ */
+ public boolean isZip()
+ {
+ return hasExtension(".zip");
+ }
+
+
+ /**
+ * Returns whether this data entry has the given extension.
+ */
+ private boolean hasExtension(String extension)
+ {
+ return endsWithIgnoreCase(file.getPath(), extension);
+ }
+
+
+ /**
+ * Returns whether the given string ends with the given suffix, ignoring
+ * its case.
+ */
+ private static boolean endsWithIgnoreCase(String string, String suffix)
+ {
+ int stringLength = string.length();
+ int suffixLength = suffix.length();
+
+ return string.regionMatches(true, stringLength -
+ suffixLength, suffix, 0, suffixLength);
+ }
+
+
+ /**
+ * Returns the name filter that is applied to bottom-level files in this entry.
+ */
public List getFilter()
{
return filter;
}
+ /**
+ * Sets the name filter that is applied to bottom-level files in this entry.
+ */
public void setFilter(List filter)
{
this.filter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to jar files in this entry, if any.
+ */
public List getJarFilter()
{
return jarFilter;
}
+ /**
+ * Sets the name filter that is applied to jar files in this entry, if any.
+ */
public void setJarFilter(List filter)
{
this.jarFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to war files in this entry, if any.
+ */
public List getWarFilter()
{
return warFilter;
}
+ /**
+ * Sets the name filter that is applied to war files in this entry, if any.
+ */
public void setWarFilter(List filter)
{
this.warFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to ear files in this entry, if any.
+ */
public List getEarFilter()
{
return earFilter;
}
+ /**
+ * Sets the name filter that is applied to ear files in this entry, if any.
+ */
public void setEarFilter(List filter)
{
this.earFilter = filter == null || filter.size() == 0 ? null : filter;
}
+ /**
+ * Returns the name filter that is applied to zip files in this entry, if any.
+ */
public List getZipFilter()
{
return zipFilter;
}
+ /**
+ * Sets the name filter that is applied to zip files in this entry, if any.
+ */
public void setZipFilter(List filter)
{
this.zipFilter = filter == null || filter.size() == 0 ? null : filter;
}
+
+
+ // Implementations for Object.
+
+ public String toString()
+ {
+ String string = getName();
+
+ if (filter != null ||
+ jarFilter != null ||
+ warFilter != null ||
+ earFilter != null ||
+ zipFilter != null)
+ {
+ string +=
+ ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD +
+ (zipFilter != null ? ListUtil.commaSeparatedString(zipFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (earFilter != null ? ListUtil.commaSeparatedString(earFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (warFilter != null ? ListUtil.commaSeparatedString(warFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (jarFilter != null ? ListUtil.commaSeparatedString(jarFilter, true) : "") +
+ ConfigurationConstants.SEPARATOR_KEYWORD +
+ (filter != null ? ListUtil.commaSeparatedString(filter, true) : "") +
+ ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD;
+ }
+
+ return string;
+ }
}
diff --git a/src/proguard/ClassSpecification.java b/src/proguard/ClassSpecification.java
index a84e0c8..eb52fc3 100644
--- a/src/proguard/ClassSpecification.java
+++ b/src/proguard/ClassSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ClassSpecificationVisitorFactory.java b/src/proguard/ClassSpecificationVisitorFactory.java
index c99ab2c..042a367 100644
--- a/src/proguard/ClassSpecificationVisitorFactory.java
+++ b/src/proguard/ClassSpecificationVisitorFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -493,7 +493,8 @@
private static boolean containsWildCards(String string)
{
return string != null &&
- (string.indexOf('*') >= 0 ||
+ (string.indexOf('!') >= 0 ||
+ string.indexOf('*') >= 0 ||
string.indexOf('?') >= 0 ||
string.indexOf('%') >= 0 ||
string.indexOf(',') >= 0 ||
diff --git a/src/proguard/Configuration.java b/src/proguard/Configuration.java
index d513e2c..2a39870 100644
--- a/src/proguard/Configuration.java
+++ b/src/proguard/Configuration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -50,7 +50,7 @@
* Specifies whether to skip non-public library classes while reading
* library jars.
*/
- public boolean skipNonPublicLibraryClasses = true;
+ public boolean skipNonPublicLibraryClasses = false;
/**
* Specifies whether to skip non-public library class members while reading
@@ -237,6 +237,13 @@
public List keepAttributes;
/**
+ * Specifies whether method parameter names and types should be kept for
+ * methods that are not obfuscated. This is achieved by keeping partial
+ * "LocalVariableTable" and "LocalVariableTypeTable" attributes.
+ */
+ public boolean keepParameterNames = false;
+
+ /**
* An optional replacement for all SourceFile attributes.
*/
public String newSourceFileAttribute;
diff --git a/src/proguard/ConfigurationConstants.java b/src/proguard/ConfigurationConstants.java
index 694e006..0da4b5d 100644
--- a/src/proguard/ConfigurationConstants.java
+++ b/src/proguard/ConfigurationConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -73,6 +73,7 @@
public static final String REPACKAGE_CLASSES_OPTION = "-repackageclasses";
public static final String DEFAULT_PACKAGE_OPTION = "-defaultpackage";
public static final String KEEP_ATTRIBUTES_OPTION = "-keepattributes";
+ public static final String KEEP_PARAMETER_NAMES_OPTION = "-keepparameternames";
public static final String RENAME_SOURCE_FILE_ATTRIBUTE_OPTION = "-renamesourcefileattribute";
public static final String ADAPT_CLASS_STRINGS_OPTION = "-adaptclassstrings";
public static final String ADAPT_RESOURCE_FILE_NAMES_OPTION = "-adaptresourcefilenames";
@@ -87,6 +88,7 @@
public static final String IGNORE_WARNINGS_OPTION = "-ignorewarnings";
public static final String PRINT_CONFIGURATION_OPTION = "-printconfiguration";
public static final String DUMP_OPTION = "-dump";
+ public static final String SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION = "-skipnonpubliclibraryclasses";
public static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION = "-dontskipnonpubliclibraryclasses";
public static final String DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION = "-dontskipnonpubliclibraryclassmembers";
public static final String TARGET_OPTION = "-target";
diff --git a/src/proguard/ConfigurationParser.java b/src/proguard/ConfigurationParser.java
index e01809e..0a6e296 100644
--- a/src/proguard/ConfigurationParser.java
+++ b/src/proguard/ConfigurationParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -58,9 +58,21 @@
public ConfigurationParser(String[] args,
File baseDir) throws IOException
{
- reader = new ArgumentWordReader(args, baseDir);
+ this(new ArgumentWordReader(args, baseDir));
+ }
- readNextWord();
+
+ /**
+ * Creates a new ConfigurationParser for the given lines,
+ * with the given base directory.
+ */
+ public ConfigurationParser(String lines,
+ String description,
+ File baseDir) throws IOException
+ {
+ this(new LineWordReader(new LineNumberReader(new StringReader(lines)),
+ description,
+ baseDir));
}
@@ -69,9 +81,7 @@
*/
public ConfigurationParser(File file) throws IOException
{
- reader = new FileWordReader(file);
-
- readNextWord();
+ this(new FileWordReader(file));
}
@@ -80,7 +90,16 @@
*/
public ConfigurationParser(URL url) throws IOException
{
- reader = new FileWordReader(url);
+ this(new FileWordReader(url));
+ }
+
+
+ /**
+ * Creates a new ConfigurationParser for the given word reader.
+ */
+ public ConfigurationParser(WordReader reader) throws IOException
+ {
+ this.reader = reader;
readNextWord();
}
@@ -110,6 +129,7 @@
else if (ConfigurationConstants.OUTJARS_OPTION .startsWith(nextWord)) configuration.programJars = parseClassPathArgument(configuration.programJars, true);
else if (ConfigurationConstants.LIBRARYJARS_OPTION .startsWith(nextWord)) configuration.libraryJars = parseClassPathArgument(configuration.libraryJars, false);
else if (ConfigurationConstants.RESOURCEJARS_OPTION .startsWith(nextWord)) throw new ParseException("The '-resourcejars' option is no longer supported. Please use the '-injars' option for all input");
+ else if (ConfigurationConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(true);
else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION .startsWith(nextWord)) configuration.skipNonPublicLibraryClasses = parseNoArgument(false);
else if (ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION.startsWith(nextWord)) configuration.skipNonPublicLibraryClassMembers = parseNoArgument(false);
else if (ConfigurationConstants.TARGET_OPTION .startsWith(nextWord)) configuration.targetClassVersion = parseClassVersion();
@@ -124,7 +144,7 @@
else if (ConfigurationConstants.PRINT_SEEDS_OPTION .startsWith(nextWord)) configuration.printSeeds = parseOptionalFile();
// After '-keep'.
- else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, false, true, false, false, configuration.keepDirectories);
+ else if (ConfigurationConstants.KEEP_DIRECTORIES_OPTION .startsWith(nextWord)) configuration.keepDirectories = parseCommaSeparatedList("directory name", true, true, false, true, false, true, false, false, configuration.keepDirectories);
else if (ConfigurationConstants.DONT_SHRINK_OPTION .startsWith(nextWord)) configuration.shrink = parseNoArgument(false);
else if (ConfigurationConstants.PRINT_USAGE_OPTION .startsWith(nextWord)) configuration.printUsage = parseOptionalFile();
@@ -132,7 +152,7 @@
else if (ConfigurationConstants.DONT_OPTIMIZE_OPTION .startsWith(nextWord)) configuration.optimize = parseNoArgument(false);
else if (ConfigurationConstants.OPTIMIZATION_PASSES .startsWith(nextWord)) configuration.optimizationPasses = parseIntegerArgument();
- else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, configuration.optimizations);
+ else if (ConfigurationConstants.OPTIMIZATIONS .startsWith(nextWord)) configuration.optimizations = parseCommaSeparatedList("optimization name", true, false, false, false, false, false, false, false, configuration.optimizations);
else if (ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION .startsWith(nextWord)) configuration.assumeNoSideEffects = parseClassSpecificationArguments(configuration.assumeNoSideEffects);
else if (ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION .startsWith(nextWord)) configuration.allowAccessModification = parseNoArgument(true);
else if (ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.mergeInterfacesAggressively = parseNoArgument(true);
@@ -146,22 +166,23 @@
else if (ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION .startsWith(nextWord)) configuration.overloadAggressively = parseNoArgument(true);
else if (ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION .startsWith(nextWord)) configuration.useUniqueClassMemberNames = parseNoArgument(true);
else if (ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION .startsWith(nextWord)) configuration.useMixedCaseClassNames = parseNoArgument(false);
- else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, true, false, true, false, configuration.keepPackageNames);
+ else if (ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION .startsWith(nextWord)) configuration.keepPackageNames = parseCommaSeparatedList("package name", true, true, false, false, true, false, true, false, configuration.keepPackageNames);
else if (ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION .startsWith(nextWord)) configuration.flattenPackageHierarchy = ClassUtil.internalClassName(parseOptionalArgument());
else if (ConfigurationConstants.REPACKAGE_CLASSES_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument());
else if (ConfigurationConstants.DEFAULT_PACKAGE_OPTION .startsWith(nextWord)) configuration.repackageClasses = ClassUtil.internalClassName(parseOptionalArgument());
- else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, true, false, false, false, configuration.keepAttributes);
+ else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION .startsWith(nextWord)) configuration.keepAttributes = parseCommaSeparatedList("attribute name", true, true, false, false, true, false, false, false, configuration.keepAttributes);
+ else if (ConfigurationConstants.KEEP_PARAMETER_NAMES_OPTION .startsWith(nextWord)) configuration.keepParameterNames = parseNoArgument(true);
else if (ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION .startsWith(nextWord)) configuration.newSourceFileAttribute = parseOptionalArgument();
- else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.adaptClassStrings);
- else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileNames);
- else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, false, false, false, false, configuration.adaptResourceFileContents);
+ else if (ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION .startsWith(nextWord)) configuration.adaptClassStrings = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.adaptClassStrings);
+ else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION .startsWith(nextWord)) configuration.adaptResourceFileNames = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileNames);
+ else if (ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION .startsWith(nextWord)) configuration.adaptResourceFileContents = parseCommaSeparatedList("resource file name", true, true, false, true, false, false, false, false, configuration.adaptResourceFileContents);
else if (ConfigurationConstants.DONT_PREVERIFY_OPTION .startsWith(nextWord)) configuration.preverify = parseNoArgument(false);
else if (ConfigurationConstants.MICRO_EDITION_OPTION .startsWith(nextWord)) configuration.microEdition = parseNoArgument(true);
else if (ConfigurationConstants.VERBOSE_OPTION .startsWith(nextWord)) configuration.verbose = parseNoArgument(true);
- else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.note);
- else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, true, false, true, false, configuration.warn);
+ else if (ConfigurationConstants.DONT_NOTE_OPTION .startsWith(nextWord)) configuration.note = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.note);
+ else if (ConfigurationConstants.DONT_WARN_OPTION .startsWith(nextWord)) configuration.warn = parseCommaSeparatedList("class name", true, true, false, false, true, false, true, false, configuration.warn);
else if (ConfigurationConstants.IGNORE_WARNINGS_OPTION .startsWith(nextWord)) configuration.ignoreWarnings = parseNoArgument(true);
else if (ConfigurationConstants.PRINT_CONFIGURATION_OPTION .startsWith(nextWord)) configuration.printConfiguration = parseOptionalFile();
else if (ConfigurationConstants.DUMP_OPTION .startsWith(nextWord)) configuration.dump = parseOptionalFile();
@@ -190,7 +211,7 @@
private long parseIncludeArgument(long lastModified) throws ParseException, IOException
{
// Read the configuation file name.
- readNextWord("configuration file name");
+ readNextWord("configuration file name", true, false);
File file = file(nextWord);
reader.includeWordReader(new FileWordReader(file));
@@ -204,7 +225,7 @@
private void parseBaseDirectoryArgument() throws ParseException, IOException
{
// Read the base directory name.
- readNextWord("base directory name");
+ readNextWord("base directory name", true, false);
reader.setBaseDir(file(nextWord));
@@ -225,7 +246,7 @@
while (true)
{
// Read the next jar name.
- readNextWord("jar or directory name");
+ readNextWord("jar or directory name", true, false);
// Create a new class path entry.
ClassPathEntry entry = new ClassPathEntry(file(nextWord), isOutput);
@@ -245,7 +266,7 @@
{
// Read the filter.
filters[counter++] =
- parseCommaSeparatedList("filter", true, false, true, false, true, false, false, null);
+ parseCommaSeparatedList("filter", true, false, true, true, false, true, false, false, null);
}
while (counter < filters.length &&
ConfigurationConstants.SEPARATOR_KEYWORD.equals(nextWord));
@@ -343,7 +364,7 @@
throws ParseException, IOException
{
// Read the obligatory file name.
- readNextWord("file name");
+ readNextWord("file name", true, false);
// Make sure the file is properly resolved.
File file = file(nextWord);
@@ -358,7 +379,7 @@
throws ParseException, IOException
{
// Read the optional file name.
- readNextWord();
+ readNextWord(true);
// Didn't the user specify a file name?
if (configurationEnd())
@@ -386,11 +407,11 @@
return "";
}
- String fileName = nextWord;
+ String argument = nextWord;
readNextWord();
- return fileName;
+ return argument;
}
@@ -431,7 +452,8 @@
{
readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
"', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
if (!ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord))
{
@@ -491,7 +513,8 @@
// Read and add the class configuration.
readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
"', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
classSpecifications.add(parseClassSpecificationArguments());
@@ -512,30 +535,21 @@
// Parse the class annotations and access modifiers until the class keyword.
while (!ConfigurationConstants.CLASS_KEYWORD.equals(nextWord))
{
- // Parse the annotation type, if any.
-// if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord))
-// {
-// annotationType =
-// ClassUtil.internalType(
-// ListUtil.commaSeparatedString(
-// parseCommaSeparatedList("annotation type",
-// true, false, false, true, false, null)));
-//
-// continue;
-// }
-
// Strip the negating sign, if any.
- String strippedWord = nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD) ?
+ boolean negated =
+ nextWord.startsWith(ConfigurationConstants.NEGATOR_KEYWORD);
+
+ String strippedWord = negated ?
nextWord.substring(1) :
nextWord;
// Parse the class access modifiers.
- // TODO: Distinguish annotation from annotation modifier.
int accessFlag =
strippedWord.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) ? ClassConstants.INTERNAL_ACC_INTERFACE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ANNOTATION) ? ClassConstants.INTERNAL_ACC_ANNOTATTION :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) ? ClassConstants.INTERNAL_ACC_ENUM :
unknownAccessFlag();
@@ -543,9 +557,11 @@
// Is it an annotation modifier?
if (accessFlag == ClassConstants.INTERNAL_ACC_ANNOTATTION)
{
- // Is the next word actually an annotation type?
- readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'", false);
+ // Already read the next word.
+ readNextWord("annotation type or keyword '" + ClassConstants.EXTERNAL_ACC_INTERFACE + "'",
+ false, false);
+ // Is the next word actually an annotation type?
if (!nextWord.equals(ClassConstants.EXTERNAL_ACC_INTERFACE) &&
!nextWord.equals(ClassConstants.EXTERNAL_ACC_ENUM) &&
!nextWord.equals(ConfigurationConstants.CLASS_KEYWORD))
@@ -554,13 +570,17 @@
annotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- false, false, false, true, false, false, true, null));
+ false, false, false, false, true, false, false, true, null), false);
+ // Continue parsing the access modifier that we just read
+ // in the next cycle.
continue;
}
+
+ // Otherwise just handle the annotation modifier.
}
- if (strippedWord.equals(nextWord))
+ if (!negated)
{
requiredSetClassAccessFlags |= accessFlag;
}
@@ -569,7 +589,6 @@
requiredUnsetClassAccessFlags |= accessFlag;
}
-
if ((requiredSetClassAccessFlags &
requiredUnsetClassAccessFlags) != 0)
{
@@ -585,16 +604,21 @@
break;
}
- readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
- "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
- "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'", true);
+ // Should we read the next word?
+ if (accessFlag != ClassConstants.INTERNAL_ACC_ANNOTATTION)
+ {
+ readNextWord("keyword '" + ConfigurationConstants.CLASS_KEYWORD +
+ "', '" + ClassConstants.EXTERNAL_ACC_INTERFACE +
+ "', or '" + ClassConstants.EXTERNAL_ACC_ENUM + "'",
+ false, true);
+ }
}
// Parse the class name part.
String externalClassName =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("class name or interface name",
- true, false, false, true, false, false, false, null));
+ true, false, false, false, true, false, false, false, null), false);
// For backward compatibility, allow a single "*" wildcard to match any
// class.
@@ -612,7 +636,7 @@
if (ConfigurationConstants.IMPLEMENTS_KEYWORD.equals(nextWord) ||
ConfigurationConstants.EXTENDS_KEYWORD.equals(nextWord))
{
- readNextWord("class name or interface name", true);
+ readNextWord("class name or interface name", false, true);
// Parse the annotation type, if any.
if (ConfigurationConstants.ANNOTATION_KEYWORD.equals(nextWord))
@@ -620,13 +644,13 @@
extendsAnnotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- true, false, false, true, false, false, true, null));
+ true, false, false, false, true, false, false, true, null), false);
}
String externalExtendsClassName =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("class name or interface name",
- false, false, false, true, false, false, false, null));
+ false, false, false, false, true, false, false, false, null), false);
extendsClassName = ConfigurationConstants.ANY_CLASS_KEYWORD.equals(externalExtendsClassName) ?
null :
@@ -659,7 +683,8 @@
while (true)
{
readNextWord("class member description" +
- " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'", true);
+ " or closing '" + ConfigurationConstants.CLOSE_KEYWORD + "'",
+ false, true);
if (nextWord.equals(ConfigurationConstants.CLOSE_KEYWORD))
{
@@ -697,8 +722,7 @@
annotationType =
ListUtil.commaSeparatedString(
parseCommaSeparatedList("annotation type",
- true, false, false, true, false, false, true, null));
-
+ true, false, false, false, true, false, false, true, null), false);
continue;
}
@@ -716,9 +740,12 @@
strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED) ? ClassConstants.INTERNAL_ACC_SYNCHRONIZED :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_VOLATILE) ? ClassConstants.INTERNAL_ACC_VOLATILE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_TRANSIENT) ? ClassConstants.INTERNAL_ACC_TRANSIENT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_BRIDGE) ? ClassConstants.INTERNAL_ACC_BRIDGE :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_VARARGS) ? ClassConstants.INTERNAL_ACC_VARARGS :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_NATIVE) ? ClassConstants.INTERNAL_ACC_NATIVE :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
strippedWord.equals(ClassConstants.EXTERNAL_ACC_STRICT) ? ClassConstants.INTERNAL_ACC_STRICT :
+ strippedWord.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
0;
if (accessFlag == 0)
{
@@ -875,7 +902,7 @@
// Parse the method arguments.
String descriptor =
ClassUtil.internalMethodDescriptor(type,
- parseCommaSeparatedList("argument", true, true, true, true, false, false, false, null));
+ parseCommaSeparatedList("argument", true, true, true, false, true, false, false, false, null));
if (!ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD.equals(nextWord))
{
@@ -921,6 +948,7 @@
boolean readFirstWord,
boolean allowEmptyList,
boolean expectClosingParenthesis,
+ boolean isFileName,
boolean checkJavaIdentifiers,
boolean replaceSystemProperties,
boolean replaceExternalClassNames,
@@ -938,12 +966,12 @@
if (expectClosingParenthesis || !allowEmptyList)
{
// Read the first list entry.
- readNextWord(expectedDescription);
+ readNextWord(expectedDescription, isFileName, false);
}
else
{
// Read the first list entry, if there is any.
- readNextWord();
+ readNextWord(isFileName);
// Check if the list is empty.
if (configurationEnd() ||
@@ -1005,7 +1033,7 @@
}
// Read the next list entry.
- readNextWord(expectedDescription);
+ readNextWord(expectedDescription, isFileName, false);
}
return list;
@@ -1035,16 +1063,6 @@
file = new File(reader.getBaseDir(), fileName);
}
- // Try to get a canonical representation.
- try
- {
- file = file.getCanonicalFile();
- }
- catch (IOException ex)
- {
- // Just keep the original representation.
- }
-
return file;
}
@@ -1096,7 +1114,7 @@
private void readNextWord(String expectedDescription)
throws ParseException, IOException
{
- readNextWord(expectedDescription, false);
+ readNextWord(expectedDescription, false, false);
}
@@ -1105,10 +1123,11 @@
* throwing an exception if there is no next word.
*/
private void readNextWord(String expectedDescription,
+ boolean isFileName,
boolean expectingAtCharacter)
throws ParseException, IOException
{
- readNextWord();
+ readNextWord(isFileName);
if (configurationEnd(expectingAtCharacter))
{
throw new ParseException("Expecting " + expectedDescription +
@@ -1122,7 +1141,16 @@
*/
private void readNextWord() throws IOException
{
- nextWord = reader.nextWord();
+ readNextWord(false);
+ }
+
+
+ /**
+ * Reads the next word of the configuration in the 'nextWord' field.
+ */
+ private void readNextWord(boolean isFileName) throws IOException
+ {
+ nextWord = reader.nextWord(isFileName);
}
diff --git a/src/proguard/ConfigurationWriter.java b/src/proguard/ConfigurationWriter.java
index 5d112d6..cd83515 100644
--- a/src/proguard/ConfigurationWriter.java
+++ b/src/proguard/ConfigurationWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -25,7 +25,7 @@
import proguard.util.ListUtil;
import java.io.*;
-import java.util.List;
+import java.util.*;
/**
@@ -44,7 +44,7 @@
private final PrintWriter writer;
- private File baseDir;
+ private File baseDir;
/**
@@ -105,7 +105,7 @@
writer.println();
// Write the other options.
- writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION, !configuration.skipNonPublicLibraryClasses);
+ writeOption(ConfigurationConstants.SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION, configuration.skipNonPublicLibraryClasses);
writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION, !configuration.skipNonPublicLibraryClassMembers);
writeOption(ConfigurationConstants.KEEP_DIRECTORIES_OPTION, configuration.keepDirectories);
writeOption(ConfigurationConstants.TARGET_OPTION, ClassUtil.externalClassVersion(configuration.targetClassVersion));
@@ -115,7 +115,7 @@
writeOption(ConfigurationConstants.PRINT_USAGE_OPTION, configuration.printUsage);
writeOption(ConfigurationConstants.DONT_OPTIMIZE_OPTION, !configuration.optimize);
- writeOption(ConfigurationConstants.OPTIMIZATIONS, configuration.optimize ? ListUtil.commaSeparatedString(configuration.optimizations) : null);
+ writeOption(ConfigurationConstants.OPTIMIZATIONS, configuration.optimizations);
writeOption(ConfigurationConstants.OPTIMIZATION_PASSES, configuration.optimizationPasses);
writeOption(ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION, configuration.allowAccessModification);
writeOption(ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION, configuration.mergeInterfacesAggressively);
@@ -133,6 +133,7 @@
writeOption(ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION, configuration.flattenPackageHierarchy, true);
writeOption(ConfigurationConstants.REPACKAGE_CLASSES_OPTION, configuration.repackageClasses, true);
writeOption(ConfigurationConstants.KEEP_ATTRIBUTES_OPTION, configuration.keepAttributes);
+ writeOption(ConfigurationConstants.KEEP_PARAMETER_NAMES_OPTION, configuration.keepParameterNames);
writeOption(ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION, configuration.newSourceFileAttribute);
writeOption(ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION, configuration.adaptClassStrings, true);
writeOption(ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION, configuration.adaptResourceFileNames);
@@ -218,15 +219,7 @@
writer.print(ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD);
}
- for (int index = 0; index < filter.size(); index++)
- {
- if (index > 0)
- {
- writer.print(ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD);
- }
-
- writer.print(quotedString((String)filter.get(index)));
- }
+ writer.print(ListUtil.commaSeparatedString(filter, true));
filtered = true;
}
@@ -273,16 +266,14 @@
}
else
{
- String argumentString = ListUtil.commaSeparatedString(arguments);
-
if (replaceInternalClassNames)
{
- argumentString = ClassUtil.externalClassName(argumentString);
+ arguments = externalClassNames(arguments);
}
writer.print(optionName);
writer.print(' ');
- writer.println(quotedString(argumentString));
+ writer.println(ListUtil.commaSeparatedString(arguments, true));
}
}
}
@@ -585,6 +576,23 @@
/**
+ * Returns a list with external versions of the given list of internal
+ * class names.
+ */
+ private List externalClassNames(List internalClassNames)
+ {
+ List externalClassNames = new ArrayList(internalClassNames.size());
+
+ for (int index = 0; index < internalClassNames.size(); index++)
+ {
+ externalClassNames.add(ClassUtil.externalClassName((String)internalClassNames.get(index)));
+ }
+
+ return externalClassNames;
+ }
+
+
+ /**
* Returns a relative file name of the given file, if possible.
* The file name is also quoted, if necessary.
*/
diff --git a/src/proguard/DataEntryReaderFactory.java b/src/proguard/DataEntryReaderFactory.java
index a9724b5..5b9c711 100644
--- a/src/proguard/DataEntryReaderFactory.java
+++ b/src/proguard/DataEntryReaderFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -48,11 +48,10 @@
ClassPathEntry classPathEntry,
DataEntryReader reader)
{
- String entryName = classPathEntry.getName();
- boolean isJar = endsWithIgnoreCase(entryName, ".jar");
- boolean isWar = endsWithIgnoreCase(entryName, ".war");
- boolean isEar = endsWithIgnoreCase(entryName, ".ear");
- boolean isZip = endsWithIgnoreCase(entryName, ".zip");
+ boolean isJar = classPathEntry.isJar();
+ boolean isWar = classPathEntry.isWar();
+ boolean isEar = classPathEntry.isEar();
+ boolean isZip = classPathEntry.isZip();
List filter = classPathEntry.getFilter();
List jarFilter = classPathEntry.getJarFilter();
@@ -139,17 +138,4 @@
reader);
}
}
-
-
- /**
- * Returns whether the given string ends with the given suffix, ignoring its
- * case.
- */
- private static boolean endsWithIgnoreCase(String string, String suffix)
- {
- int stringLength = string.length();
- int suffixLength = suffix.length();
-
- return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength);
- }
}
diff --git a/src/proguard/DataEntryWriterFactory.java b/src/proguard/DataEntryWriterFactory.java
index 9fbc6d0..0da890b 100644
--- a/src/proguard/DataEntryWriterFactory.java
+++ b/src/proguard/DataEntryWriterFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -65,11 +65,10 @@
private static DataEntryWriter createClassPathEntryWriter(ClassPathEntry classPathEntry,
DataEntryWriter alternativeWriter)
{
- String entryName = classPathEntry.getName();
- boolean isJar = endsWithIgnoreCase(entryName, ".jar");
- boolean isWar = endsWithIgnoreCase(entryName, ".war");
- boolean isEar = endsWithIgnoreCase(entryName, ".ear");
- boolean isZip = endsWithIgnoreCase(entryName, ".zip");
+ boolean isJar = classPathEntry.isJar();
+ boolean isWar = classPathEntry.isWar();
+ boolean isEar = classPathEntry.isEar();
+ boolean isZip = classPathEntry.isZip();
List filter = classPathEntry.getFilter();
List jarFilter = classPathEntry.getJarFilter();
@@ -83,7 +82,7 @@
isEar ? "ear" :
isZip ? "zip" :
"directory") +
- " [" + entryName + "]" +
+ " [" + classPathEntry.getName() + "]" +
(filter != null ||
jarFilter != null ||
warFilter != null ||
@@ -148,17 +147,4 @@
filteredJarWriter,
isJar ? jarWriter : writer);
}
-
-
- /**
- * Returns whether the given string ends with the given suffix, ignoring its
- * case.
- */
- private static boolean endsWithIgnoreCase(String string, String suffix)
- {
- int stringLength = string.length();
- int suffixLength = suffix.length();
-
- return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength);
- }
}
diff --git a/src/proguard/DescriptorKeepChecker.java b/src/proguard/DescriptorKeepChecker.java
index 1dfaf1a..7849693 100644
--- a/src/proguard/DescriptorKeepChecker.java
+++ b/src/proguard/DescriptorKeepChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -23,7 +23,7 @@
import proguard.classfile.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
-import proguard.optimize.KeepMarker;
+import proguard.optimize.*;
import java.util.List;
@@ -64,7 +64,7 @@
/**
* Checks the classes mentioned in the given keep specifications, printing
- * notes if necessary. Returns the number of notes printed.
+ * notes if necessary.
*/
public void checkClassSpecifications(List keepSpecifications)
{
@@ -85,8 +85,11 @@
programClassPool.accept(classPoolvisitor);
libraryClassPool.accept(classPoolvisitor);
- // Print out notes about argument types that are not being kept.
- programClassPool.classesAccept(new AllMemberVisitor(this));
+ // Print out notes about argument types that are not being kept in
+ // class members that are being kept.
+ programClassPool.classesAccept(
+ new AllMemberVisitor(
+ new KeptMemberFilter(this)));
}
@@ -94,39 +97,42 @@
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- if (KeepMarker.isKept(programField))
- {
- referencingClass = programClass;
- referencingMember = programField;
- isField = true;
-
- // Don't check the type, because it is not required for introspection.
- //programField.referencedClassesAccept(this);
- }
+ //referencingClass = programClass;
+ //referencingMember = programField;
+ //isField = true;
+ //
+ // Don't check the type, because it is not required for introspection.
+ //programField.referencedClassesAccept(this);
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if (KeepMarker.isKept(programMethod))
+ referencingClass = programClass;
+ referencingMember = programMethod;
+ isField = false;
+
+ // Don't check the return type, because it is not required for
+ // introspection (e.g. the return type of the special Enum methods).
+ //programMethod.referencedClassesAccept(this);
+
+ Clazz[] referencedClasses = programMethod.referencedClasses;
+ if (referencedClasses != null)
{
- referencingClass = programClass;
- referencingMember = programMethod;
- isField = false;
+ int count = referencedClasses.length;
- // Don't check the return type, because it is not required for
- // introspection (e.g. the return type of the special Enum methods).
- //programMethod.referencedClassesAccept(this);
-
- Clazz[] referencedClasses = programMethod.referencedClasses;
- if (referencedClasses != null)
+ // Adapt the count if the return type is a class type (not so
+ // pretty; assuming test just checks for final ';').
+ if (ClassUtil.isInternalClassType(programMethod.getDescriptor(programClass)))
{
- for (int index = 0; index < referencedClasses.length-1; index++)
+ count--;
+ }
+
+ for (int index = 0; index < count; index++)
+ {
+ if (referencedClasses[index] != null)
{
- if (referencedClasses[index] != null)
- {
- referencedClasses[index].accept(this);
- }
+ referencedClasses[index].accept(this);
}
}
}
diff --git a/src/proguard/DuplicateClassPrinter.java b/src/proguard/DuplicateClassPrinter.java
index 21b6aa0..9ade21b 100644
--- a/src/proguard/DuplicateClassPrinter.java
+++ b/src/proguard/DuplicateClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/FileWordReader.java b/src/proguard/FileWordReader.java
index fb9fa50..e0325b7 100644
--- a/src/proguard/FileWordReader.java
+++ b/src/proguard/FileWordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,23 +29,17 @@
*
* @author Eric Lafortune
*/
-public class FileWordReader extends WordReader
+public class FileWordReader extends LineWordReader
{
- private final String name;
- private LineNumberReader reader;
-
-
/**
* Creates a new FileWordReader for the given file.
*/
public FileWordReader(File file) throws IOException
{
- super(file.getParentFile());
-
- this.name = file.getPath();
- this.reader = new LineNumberReader(
- new BufferedReader(
- new FileReader(file)));
+ super(new LineNumberReader(new BufferedReader(new FileReader(file))),
+ "file '" + file.getPath() + "'",
+ file.getParentFile()
+ );
}
@@ -54,36 +48,8 @@
*/
public FileWordReader(URL url) throws IOException
{
- super(null);
-
- this.name = url.toString();
- this.reader = new LineNumberReader(
- new BufferedReader(
- new InputStreamReader(url.openStream())));
- }
-
-
- // Implementations for WordReader.
-
- protected String nextLine() throws IOException
- {
- return reader.readLine();
- }
-
-
- protected String lineLocationDescription()
- {
- return "line " + reader.getLineNumber() + " of file '" + name + "'";
- }
-
-
- public void close() throws IOException
- {
- super.close();
-
- if (reader != null)
- {
- reader.close();
- }
+ super(new LineNumberReader(new BufferedReader(new InputStreamReader(url.openStream()))),
+ "file '" + url.toString() + "'",
+ null);
}
}
diff --git a/src/proguard/FullyQualifiedClassNameChecker.java b/src/proguard/FullyQualifiedClassNameChecker.java
index 06949b5..7534fb4 100644
--- a/src/proguard/FullyQualifiedClassNameChecker.java
+++ b/src/proguard/FullyQualifiedClassNameChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -42,7 +42,7 @@
/**
- * Creates a new DescriptorKeepChecker.
+ * Creates a new FullyQualifiedClassNameChecker.
*/
public FullyQualifiedClassNameChecker(ClassPool programClassPool,
ClassPool libraryClassPool,
@@ -56,7 +56,7 @@
/**
* Checks the classes mentioned in the given class specifications, printing
- * notes if necessary. Returns the number of notes printed.
+ * notes if necessary.
*/
public void checkClassSpecifications(List classSpecifications)
{
@@ -173,7 +173,8 @@
private static boolean containsWildCards(String string)
{
return string != null &&
- (string.indexOf('*') >= 0 ||
+ (string.indexOf('!') >= 0 ||
+ string.indexOf('*') >= 0 ||
string.indexOf('?') >= 0 ||
string.indexOf(',') >= 0 ||
string.indexOf("///") >= 0);
diff --git a/src/proguard/GPL.java b/src/proguard/GPL.java
index 272a837..9327b8b 100644
--- a/src/proguard/GPL.java
+++ b/src/proguard/GPL.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -48,9 +48,10 @@
{
String uniquePackageNames = uniquePackageNames(unknownPackageNames);
- System.out.println("ProGuard is released under the GNU General Public License. The authors of all");
- System.out.println("programs or plugins that link to it ("+uniquePackageNames+"...) therefore");
- System.out.println("must ensure that these programs carry the GNU General Public License as well.");
+ System.out.println("ProGuard is released under the GNU General Public License. You therefore");
+ System.out.println("must ensure that programs that link to it ("+uniquePackageNames+"...)");
+ System.out.println("carry the GNU General Public License as well. Alternatively, you can");
+ System.out.println("apply for an exception with the author of ProGuard.");
}
}
@@ -165,9 +166,14 @@
packageName.startsWith("org.apache.tools.maven") ||
packageName.startsWith("org.eclipse") ||
packageName.startsWith("org.netbeans") ||
+ packageName.startsWith("com.android") ||
packageName.startsWith("com.sun.kvem") ||
packageName.startsWith("net.certiv.proguarddt") ||
+ packageName.startsWith("scala") ||
+ packageName.startsWith("sbt") ||
+ packageName.startsWith("xsbt") ||
packageName.startsWith("eclipseme") ||
+ packageName.startsWith("com.neomades") ||
packageName.startsWith("jg.j2me") ||
packageName.startsWith("jg.common") ||
packageName.startsWith("jg.buildengine");
diff --git a/src/proguard/Initializer.java b/src/proguard/Initializer.java
index 41cf971..dc17b00 100644
--- a/src/proguard/Initializer.java
+++ b/src/proguard/Initializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -60,6 +60,11 @@
{
int originalLibraryClassPoolSize = libraryClassPool.size();
+ // Perform a basic check on the keep options in the configuration.
+ WarningPrinter keepClassMemberNotePrinter = new WarningPrinter(System.out, configuration.note);
+
+ new KeepClassMemberChecker(keepClassMemberNotePrinter).checkClassSpecifications(configuration.keep);
+
// Construct a reduced library class pool with only those library
// classes whose hierarchies are referenced by the program classes.
// We can't do this if we later have to come up with the obfuscated
@@ -275,8 +280,12 @@
{
System.err.println("Warning: there were " + classReferenceWarningCount +
" unresolved references to classes or interfaces.");
- System.err.println(" You may need to specify additional library jars (using '-libraryjars'),");
- System.err.println(" or perhaps the '-dontskipnonpubliclibraryclasses' option.");
+ System.err.println(" You may need to specify additional library jars (using '-libraryjars').");
+
+ if (configuration.skipNonPublicLibraryClasses)
+ {
+ System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'.");
+ }
}
int dependencyWarningCount = dependencyWarningPrinter.getWarningCount();
@@ -295,9 +304,13 @@
" unresolved references to program class members.");
System.err.println(" Your input classes appear to be inconsistent.");
System.err.println(" You may need to recompile them and try again.");
- System.err.println(" Alternatively, you may have to specify the options ");
- System.err.println(" '-dontskipnonpubliclibraryclasses' and/or");
+ System.err.println(" Alternatively, you may have to specify the option ");
System.err.println(" '-dontskipnonpubliclibraryclassmembers'.");
+
+ if (configuration.skipNonPublicLibraryClasses)
+ {
+ System.err.println(" You may also have to remove the option '-skipnonpubliclibraryclasses'.");
+ }
}
if ((classReferenceWarningCount > 0 ||
diff --git a/src/proguard/InputReader.java b/src/proguard/InputReader.java
index c088324..9ee1314 100644
--- a/src/proguard/InputReader.java
+++ b/src/proguard/InputReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -227,7 +227,7 @@
}
catch (IOException ex)
{
- throw new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")");
+ throw (IOException)new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")").initCause(ex);
}
}
}
diff --git a/src/proguard/KeepClassMemberChecker.java b/src/proguard/KeepClassMemberChecker.java
new file mode 100644
index 0000000..a6546d9
--- /dev/null
+++ b/src/proguard/KeepClassMemberChecker.java
@@ -0,0 +1,87 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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;
+
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+import java.util.List;
+
+/**
+ * This class checks if the user has forgotten to specify class members in
+ * some keep options in the configuration.
+ *
+ * @author Eric Lafortune
+ */
+public class KeepClassMemberChecker
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ private final WarningPrinter notePrinter;
+
+
+ /**
+ * Creates a new KeepClassMemberChecker.
+ */
+ public KeepClassMemberChecker(WarningPrinter notePrinter)
+ {
+ this.notePrinter = notePrinter;
+ }
+
+
+ /**
+ * Checks if the given class specifications try to keep class members
+ * without actually specifying any, printing notes if necessary. Returns
+ * the number of notes printed.
+ */
+ public void checkClassSpecifications(List keepClassSpecifications)
+ {
+ if (keepClassSpecifications != null)
+ {
+ for (int index = 0; index < keepClassSpecifications.size(); index++)
+ {
+ KeepClassSpecification keepClassSpecification =
+ (KeepClassSpecification)keepClassSpecifications.get(index);
+
+ if (!keepClassSpecification.markClasses &&
+ (keepClassSpecification.fieldSpecifications == null ||
+ keepClassSpecification.fieldSpecifications.size() == 0) &&
+ (keepClassSpecification.methodSpecifications == null ||
+ keepClassSpecification.methodSpecifications.size() == 0))
+ {
+ String className = keepClassSpecification.className;
+ if (className == null)
+ {
+ className = keepClassSpecification.extendsClassName;
+ }
+
+ if (className != null &&
+ notePrinter.accepts(className))
+ {
+ notePrinter.print(className,
+ "Note: the configuration doesn't specify which class members to keep for class '" +
+ ClassUtil.externalClassName(className) + "'");
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/proguard/KeepClassSpecification.java b/src/proguard/KeepClassSpecification.java
index 29c0d3c..c30538a 100644
--- a/src/proguard/KeepClassSpecification.java
+++ b/src/proguard/KeepClassSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/LineWordReader.java b/src/proguard/LineWordReader.java
new file mode 100644
index 0000000..b8c9126
--- /dev/null
+++ b/src/proguard/LineWordReader.java
@@ -0,0 +1,74 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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;
+
+import java.io.*;
+
+
+/**
+ * A <code>WordReader</code> that returns words from a line number reader.
+ *
+ * @author Eric Lafortune
+ */
+public class LineWordReader extends WordReader
+{
+ private final LineNumberReader reader;
+ private final String description;
+
+
+ /**
+ * Creates a new LineWordReader for the given input.
+ */
+ public LineWordReader(LineNumberReader lineNumberReader,
+ String description,
+ File baseDir) throws IOException
+ {
+ super(baseDir);
+
+ this.reader = lineNumberReader;
+ this.description = description;
+ }
+
+
+ // Implementations for WordReader.
+
+ protected String nextLine() throws IOException
+ {
+ return reader.readLine();
+ }
+
+
+ protected String lineLocationDescription()
+ {
+ return "line " + reader.getLineNumber() + " of " + description;
+ }
+
+
+ public void close() throws IOException
+ {
+ super.close();
+
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+}
diff --git a/src/proguard/MemberSpecification.java b/src/proguard/MemberSpecification.java
index 1cfa962..025f3b8 100644
--- a/src/proguard/MemberSpecification.java
+++ b/src/proguard/MemberSpecification.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/OutputWriter.java b/src/proguard/OutputWriter.java
index 10c18fb..39dd1ad 100644
--- a/src/proguard/OutputWriter.java
+++ b/src/proguard/OutputWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -63,13 +63,12 @@
"] must be specified after an input jar, or it will be empty.");
}
- // Perform some checks on the output jars.
+ // Check if the first of two subsequent the output jars has a filter.
for (int index = 0; index < programJars.size() - 1; index++)
{
ClassPathEntry entry = programJars.get(index);
if (entry.isOutput())
{
- // Check if all but the last output jars have filters.
if (entry.getFilter() == null &&
entry.getJarFilter() == null &&
entry.getWarFilter() == null &&
@@ -78,10 +77,17 @@
programJars.get(index + 1).isOutput())
{
throw new IOException("The output jar [" + entry.getName() +
- "] must have a filter, or all subsequent jars will be empty.");
+ "] must have a filter, or all subsequent output jars will be empty.");
}
+ }
+ }
- // Check if the output jar name is different from the input jar names.
+ // Check if the output jar names are different from the input jar names.
+ for (int outIndex = 0; outIndex < programJars.size() - 1; outIndex++)
+ {
+ ClassPathEntry entry = programJars.get(outIndex);
+ if (entry.isOutput())
+ {
for (int inIndex = 0; inIndex < programJars.size(); inIndex++)
{
ClassPathEntry otherEntry = programJars.get(inIndex);
@@ -96,6 +102,40 @@
}
}
+ // Check for potential problems with mixed-case class names on
+ // case-insensitive file systems.
+ if (configuration.obfuscate &&
+ configuration.useMixedCaseClassNames &&
+ configuration.classObfuscationDictionary == null &&
+ (configuration.note == null ||
+ !configuration.note.isEmpty()))
+ {
+ String os = System.getProperty("os.name").toLowerCase();
+ if (os.startsWith("windows") ||
+ os.startsWith("mac os"))
+ {
+ // Go over all program class path entries.
+ for (int index = 0; index < programJars.size(); index++)
+ {
+ // Is it an output directory?
+ ClassPathEntry entry = programJars.get(index);
+ if (entry.isOutput() &&
+ !entry.isJar() &&
+ !entry.isWar() &&
+ !entry.isEar() &&
+ !entry.isZip())
+ {
+ System.out.println("Note: you're writing the processed class files to a directory [" + entry.getName() +"].");
+ System.out.println(" This will likely cause problems with obfuscated mixed-case class names.");
+ System.out.println(" You should consider writing the output to a jar file, or otherwise");
+ System.out.println(" specify '-dontusemixedclassnames'.");
+
+ break;
+ }
+ }
+ }
+ }
+
int firstInputIndex = 0;
int lastInputIndex = 0;
@@ -166,7 +206,7 @@
{
resourceRewriter =
new NameFilter(configuration.adaptResourceFileContents,
- new NameFilter("META-INF/**",
+ new NameFilter("META-INF/MANIFEST.MF,META-INF/*.SF",
new ManifestRewriter(programClassPool, writer),
new DataEntryRewriter(programClassPool, writer)),
resourceRewriter);
@@ -221,7 +261,7 @@
}
catch (IOException ex)
{
- throw new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")");
+ throw (IOException)new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")").initCause(ex);
}
}
@@ -232,25 +272,25 @@
*/
private static Map createPackagePrefixMap(ClassPool classPool)
{
- Map PackagePrefixMap = new HashMap();
+ Map packagePrefixMap = new HashMap();
Iterator iterator = classPool.classNames();
while (iterator.hasNext())
{
String className = (String)iterator.next();
- String PackagePrefix = ClassUtil.internalPackagePrefix(className);
+ String packagePrefix = ClassUtil.internalPackagePrefix(className);
- String mappedNewPackagePrefix = (String)PackagePrefixMap.get(PackagePrefix);
+ String mappedNewPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
if (mappedNewPackagePrefix == null ||
- !mappedNewPackagePrefix.equals(PackagePrefix))
+ !mappedNewPackagePrefix.equals(packagePrefix))
{
String newClassName = classPool.getClass(className).getName();
String newPackagePrefix = ClassUtil.internalPackagePrefix(newClassName);
- PackagePrefixMap.put(PackagePrefix, newPackagePrefix);
+ packagePrefixMap.put(packagePrefix, newPackagePrefix);
}
}
- return PackagePrefixMap;
+ return packagePrefixMap;
}
}
diff --git a/src/proguard/ParseException.java b/src/proguard/ParseException.java
index 9294200..2f3af01 100644
--- a/src/proguard/ParseException.java
+++ b/src/proguard/ParseException.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ProGuard.java b/src/proguard/ProGuard.java
index 8c30e10..913207a 100644
--- a/src/proguard/ProGuard.java
+++ b/src/proguard/ProGuard.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -24,7 +24,7 @@
import proguard.classfile.editor.ClassElementSorter;
import proguard.classfile.visitor.*;
import proguard.obfuscate.Obfuscator;
-import proguard.optimize.Optimizer;
+import proguard.optimize.*;
import proguard.preverify.*;
import proguard.shrink.Shrinker;
@@ -37,7 +37,7 @@
*/
public class ProGuard
{
- public static final String VERSION = "ProGuard, version 4.4";
+ public static final String VERSION = "ProGuard, version 4.7";
private final Configuration configuration;
private ClassPool programClassPool = new ClassPool();
@@ -77,7 +77,8 @@
readInput();
- if (configuration.shrink ||
+ if (configuration.printSeeds != null ||
+ configuration.shrink ||
configuration.optimize ||
configuration.obfuscate ||
configuration.preverify)
@@ -236,30 +237,10 @@
System.out.println("Printing kept classes, fields, and methods...");
}
- // Check if we have at least some keep commands.
- if (configuration.keep == null)
- {
- throw new IOException("You have to specify '-keep' options for the shrinking step.");
- }
-
PrintStream ps = createPrintStream(configuration.printSeeds);
try
{
- // Create a visitor for printing out the seeds. We're printing out
- // the program elements that are preserved against shrinking,
- // optimization, or obfuscation.
- SimpleClassPrinter printer = new SimpleClassPrinter(false, ps);
- ClassPoolVisitor classPoolvisitor =
- ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
- new ProgramClassFilter(printer),
- new ProgramMemberFilter(printer),
- true,
- true,
- true);
-
- // Print out the seeds.
- programClassPool.accept(classPoolvisitor);
- libraryClassPool.accept(classPoolvisitor);
+ new SeedPrinter(ps).write(configuration, programClassPool, libraryClassPool);
}
finally
{
@@ -445,14 +426,26 @@
/**
- * Returns the absolute file name for the given file, or the standard output
+ * Returns the canonical file name for the given file, or "standard output"
* if the file name is empty.
*/
private String fileName(File file)
{
- return isFile(file) ?
- file.getAbsolutePath() :
- "standard output";
+ if (isFile(file))
+ {
+ try
+ {
+ return file.getCanonicalPath();
+ }
+ catch (IOException ex)
+ {
+ return file.getPath();
+ }
+ }
+ else
+ {
+ return "standard output";
+ }
}
diff --git a/src/proguard/SeedPrinter.java b/src/proguard/SeedPrinter.java
new file mode 100644
index 0000000..aee8f60
--- /dev/null
+++ b/src/proguard/SeedPrinter.java
@@ -0,0 +1,97 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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;
+
+import proguard.classfile.ClassPool;
+import proguard.classfile.attribute.visitor.AllAttributeVisitor;
+import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.instruction.visitor.AllInstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+import proguard.optimize.*;
+import proguard.util.*;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * This class prints out the seeds specified by keep options.
+ *
+ * @author Eric Lafortune
+ */
+public class SeedPrinter
+{
+ private final PrintStream ps;
+
+
+ /**
+ * Creates a new ConfigurationWriter for the given PrintStream.
+ */
+ public SeedPrinter(PrintStream ps) throws IOException
+ {
+ this.ps = ps;
+ }
+
+
+ /**
+ * Prints out the seeds for the classes in the given program class pool.
+ * @param configuration the configuration containing the keep options.
+ * @throws IOException if an IO error occurs while writing the configuration.
+ */
+ public void write(Configuration configuration,
+ ClassPool programClassPool,
+ ClassPool libraryClassPool) throws IOException
+ {
+ // Check if we have at least some keep commands.
+ if (configuration.keep == null)
+ {
+ throw new IOException("You have to specify '-keep' options for the shrinking step.");
+ }
+
+ // Clean up any old visitor info.
+ programClassPool.classesAccept(new ClassCleaner());
+ libraryClassPool.classesAccept(new ClassCleaner());
+
+ // Create a visitor for printing out the seeds. We're printing out
+ // the program elements that are preserved against shrinking,
+ // optimization, or obfuscation.
+ KeepMarker keepMarker = new KeepMarker();
+ ClassPoolVisitor classPoolvisitor =
+ ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
+ keepMarker,
+ keepMarker,
+ true,
+ true,
+ true);
+ // Mark the seeds.
+ programClassPool.accept(classPoolvisitor);
+ libraryClassPool.accept(classPoolvisitor);
+
+ // Print out the seeds.
+ SimpleClassPrinter printer = new SimpleClassPrinter(false, ps);
+ programClassPool.classesAcceptAlphabetically(new MultiClassVisitor(
+ new ClassVisitor[]
+ {
+ new KeptClassFilter(printer),
+ new AllMemberVisitor(new KeptMemberFilter(printer))
+ }));
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/SubclassedClassFilter.java b/src/proguard/SubclassedClassFilter.java
index 27cac11..78afb7f 100644
--- a/src/proguard/SubclassedClassFilter.java
+++ b/src/proguard/SubclassedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/Targeter.java b/src/proguard/Targeter.java
index 5067205..16583bf 100644
--- a/src/proguard/Targeter.java
+++ b/src/proguard/Targeter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/UpToDateChecker.java b/src/proguard/UpToDateChecker.java
index 9fa5d16..c743af9 100644
--- a/src/proguard/UpToDateChecker.java
+++ b/src/proguard/UpToDateChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -47,107 +47,186 @@
*/
public boolean check()
{
- long inputLastModified = configuration.lastModified;
- long outputLastModified = Long.MAX_VALUE;
-
- ClassPath programJars = configuration.programJars;
- ClassPath libraryJars = configuration.libraryJars;
-
- // Check the dates of the program jars, if any.
- if (programJars != null)
+ try
{
- for (int index = 0; index < programJars.size(); index++)
- {
- // Break early, if possible.
- if (inputLastModified >= outputLastModified)
- {
- break;
- }
+ ModificationTimeChecker checker = new ModificationTimeChecker();
- // Update the input and output modification times.
- ClassPathEntry classPathEntry = programJars.get(index);
- if (classPathEntry.isOutput())
+ checker.updateInputModificationTime(configuration.lastModified);
+
+ ClassPath programJars = configuration.programJars;
+ ClassPath libraryJars = configuration.libraryJars;
+
+ // Check the dates of the program jars, if any.
+ if (programJars != null)
+ {
+ for (int index = 0; index < programJars.size(); index++)
{
- long lastModified = lastModified(classPathEntry.getFile(), true);
- if (outputLastModified > lastModified)
- {
- outputLastModified = lastModified;
- }
- }
- else
- {
- long lastModified = lastModified(classPathEntry.getFile(), false);
- if (inputLastModified < lastModified)
- {
- inputLastModified = lastModified;
- }
+ // Update the input and output modification times.
+ ClassPathEntry classPathEntry = programJars.get(index);
+
+ checker.updateModificationTime(classPathEntry.getFile(),
+ classPathEntry.isOutput());
}
}
- }
- // Check the dates of the library jars, if any.
- if (libraryJars != null)
- {
- for (int index = 0; index < libraryJars.size(); index++)
+ // Check the dates of the library jars, if any.
+ if (libraryJars != null)
{
- // Break early, if possible.
- if (inputLastModified >= outputLastModified)
+ for (int index = 0; index < libraryJars.size(); index++)
{
- break;
- }
+ // Update the input modification time.
+ ClassPathEntry classPathEntry = libraryJars.get(index);
- // Update the input modification time.
- ClassPathEntry classPathEntry = libraryJars.get(index);
- long lastModified = lastModified(classPathEntry.getFile(), false);
- if (inputLastModified < lastModified)
- {
- inputLastModified = lastModified;
+ checker.updateModificationTime(classPathEntry.getFile(),
+ false);
}
}
- }
- boolean outputUpToDate = inputLastModified < outputLastModified;
- if (outputUpToDate)
+ // Check the dates of the auxiliary input files.
+ checker.updateInputModificationTime(configuration.applyMapping);
+ checker.updateInputModificationTime(configuration.obfuscationDictionary);
+ checker.updateInputModificationTime(configuration.classObfuscationDictionary);
+ checker.updateInputModificationTime(configuration.packageObfuscationDictionary);
+
+ // Check the dates of the auxiliary output files.
+ checker.updateOutputModificationTime(configuration.printSeeds);
+ checker.updateOutputModificationTime(configuration.printUsage);
+ checker.updateOutputModificationTime(configuration.printMapping);
+ checker.updateOutputModificationTime(configuration.printConfiguration);
+ checker.updateOutputModificationTime(configuration.dump);
+ }
+ catch (IllegalStateException e)
{
- System.out.println("The output is up to date");
+ // The output is outdated.
+ return false;
}
- return outputUpToDate;
+ System.out.println("The output seems up to date");
+
+ return true;
}
/**
- * Returns the minimum or maximum modification time of the given file or
- * of the files in the given directory (recursively).
+ * This class maintains the modification times of input and output.
+ * The methods throw an IllegalStateException if the output appears
+ * outdated.
*/
- private long lastModified(File file, boolean minimum)
- {
- // Is it a directory?
- if (file.isDirectory())
+ private static class ModificationTimeChecker {
+
+ private long inputModificationTime = Long.MIN_VALUE;
+ private long outputModificationTime = Long.MAX_VALUE;
+
+
+ /**
+ * Updates the input modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateInputModificationTime(File file)
{
- // Ignore the directory's modification time; just recurse on its files.
- File[] files = file.listFiles();
-
- // Still, an empty output directory is probably a sign that it is
- // not up to date.
- long lastModified = files.length != 0 && minimum ?
- Long.MAX_VALUE : 0L;
-
- for (int index = 0; index < files.length; index++)
+ if (file != null)
{
- long fileLastModified = lastModified(files[index], minimum);
- if ((lastModified < fileLastModified) ^ minimum)
+ updateModificationTime(file, false);
+ }
+ }
+
+
+ /**
+ * Updates the input modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateOutputModificationTime(File file)
+ {
+ if (file != null && file.getName().length() > 0)
+ {
+ updateModificationTime(file, true);
+ }
+ }
+
+
+ /**
+ * Updates the specified modification time based on the given file or
+ * directory (recursively).
+ */
+ public void updateModificationTime(File file, boolean isOutput)
+ {
+ // Is it a directory?
+ if (file.isDirectory())
+ {
+ // Ignore the directory's modification time; just recurse on
+ // its files.
+ File[] files = file.listFiles();
+
+ // Still, an empty output directory is probably a sign that it
+ // is not up to date.
+ if (files.length == 0 && isOutput)
{
- lastModified = fileLastModified;
+ updateOutputModificationTime(Long.MIN_VALUE);
+ }
+
+ for (int index = 0; index < files.length; index++)
+ {
+ updateModificationTime(files[index], isOutput);
}
}
-
- return lastModified;
+ else
+ {
+ // Update with the file's modification time.
+ updateModificationTime(file.lastModified(), isOutput);
+ }
}
- else
+
+
+ /**
+ * Updates the specified modification time.
+ */
+ public void updateModificationTime(long time, boolean isOutput)
{
- // Return the file's modification time.
- return file.lastModified();
+ if (isOutput)
+ {
+ updateOutputModificationTime(time);
+ }
+ else
+ {
+ updateInputModificationTime(time);
+ }
+ }
+
+
+ /**
+ * Updates the input modification time.
+ */
+ public void updateInputModificationTime(long time)
+ {
+ if (inputModificationTime < time)
+ {
+ inputModificationTime = time;
+
+ checkModificationTimes();
+ }
+ }
+
+
+ /**
+ * Updates the output modification time.
+ */
+ public void updateOutputModificationTime(long time)
+ {
+ if (outputModificationTime > time)
+ {
+ outputModificationTime = time;
+
+ checkModificationTimes();
+ }
+ }
+
+
+ private void checkModificationTimes()
+ {
+ if (inputModificationTime > outputModificationTime)
+ {
+ throw new IllegalStateException("The output is outdated");
+ }
}
}
}
diff --git a/src/proguard/WordReader.java b/src/proguard/WordReader.java
index d73505a..4e7a511 100644
--- a/src/proguard/WordReader.java
+++ b/src/proguard/WordReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -105,9 +105,11 @@
* Reads a word from this WordReader, or from one of its active included
* WordReader objects.
*
+ * @param isFileName return a complete line (or argument), if the word
+ * isn't an option (it doesn't start with '-').
* @return the read word.
*/
- public String nextWord() throws IOException
+ public String nextWord(boolean isFileName) throws IOException
{
currentWord = null;
@@ -115,7 +117,7 @@
if (includeWordReader != null)
{
// Does the included word reader still produce a word?
- currentWord = includeWordReader.nextWord();
+ currentWord = includeWordReader.nextWord(isFileName);
if (currentWord != null)
{
// Return it if so.
@@ -129,12 +131,22 @@
// Get a word from this reader.
- // Skip leading whitespace.
- while (currentLine != null &&
- currentIndex < currentLineLength &&
- Character.isWhitespace(currentLine.charAt(currentIndex)))
+ // Skip any whitespace and comments left on the current line.
+ if (currentLine != null)
{
- currentIndex++;
+ // Skip any leading whitespace.
+ while (currentIndex < currentLineLength &&
+ Character.isWhitespace(currentLine.charAt(currentIndex)))
+ {
+ currentIndex++;
+ }
+
+ // Skip any comments.
+ if (currentIndex < currentLineLength &&
+ isComment(currentLine.charAt(currentIndex)))
+ {
+ currentIndex = currentLineLength;
+ }
}
// Make sure we have a non-blank line.
@@ -146,30 +158,29 @@
return null;
}
- // Trim off any comments.
- int comments_start = currentLine.indexOf(COMMENT_CHARACTER);
- if (comments_start >= 0)
- {
- currentLineLength = comments_start;
+ currentLineLength = currentLine.length();
- // Remember the comments.
- String comment = currentLine.substring(comments_start + 1);
- currentComments = currentComments == null ?
- comment :
- currentComments + '\n' + comment;
- }
- else
- {
- currentLineLength = currentLine.length();
- }
-
- // Skip leading whitespace.
+ // Skip any leading whitespace.
currentIndex = 0;
while (currentIndex < currentLineLength &&
Character.isWhitespace(currentLine.charAt(currentIndex)))
{
currentIndex++;
}
+
+ // Remember any leading comments.
+ if (currentIndex < currentLineLength &&
+ isComment(currentLine.charAt(currentIndex)))
+ {
+ // Remember the comments.
+ String comment = currentLine.substring(currentIndex + 1);
+ currentComments = currentComments == null ?
+ comment :
+ currentComments + '\n' + comment;
+
+ // Skip the comments.
+ currentIndex = currentLineLength;
+ }
}
// Find the word starting at the current index.
@@ -178,12 +189,7 @@
char startChar = currentLine.charAt(startIndex);
- if (isDelimiter(startChar))
- {
- // The next word is a single delimiting character.
- endIndex = ++currentIndex;
- }
- else if (isQuote(startChar))
+ if (isQuote(startChar))
{
// The next word is starting with a quote character.
// Skip the opening quote.
@@ -205,6 +211,39 @@
endIndex = currentIndex++;
}
+ else if (isFileName &&
+ !isOption(startChar))
+ {
+ // The next word is a (possibly optional) file name.
+ // Find the end of the line, the first path separator, the first
+ // option, or the first comment.
+ while (currentIndex < currentLineLength)
+ {
+ char currentCharacter = currentLine.charAt(currentIndex);
+ if (isFileDelimiter(currentCharacter) ||
+ (isOption(currentCharacter) ||
+ isComment(currentCharacter)) &&
+ Character.isWhitespace(currentLine.charAt(currentIndex-1))) {
+ break;
+ }
+
+ currentIndex++;
+ }
+
+ endIndex = currentIndex;
+
+ // Trim any trailing whitespace.
+ while (endIndex > startIndex &&
+ Character.isWhitespace(currentLine.charAt(endIndex-1)))
+ {
+ endIndex--;
+ }
+ }
+ else if (isDelimiter(startChar))
+ {
+ // The next word is a single delimiting character.
+ endIndex = ++currentIndex;
+ }
else
{
// The next word is a simple character string.
@@ -213,9 +252,9 @@
while (currentIndex < currentLineLength)
{
char currentCharacter = currentLine.charAt(currentIndex);
- if (isDelimiter(currentCharacter) ||
- Character.isWhitespace(currentCharacter))
- {
+ if (isDelimiter(currentCharacter) ||
+ Character.isWhitespace(currentCharacter) ||
+ isComment(currentCharacter)) {
break;
}
@@ -305,6 +344,18 @@
// Small utility methods.
+ private boolean isOption(char character)
+ {
+ return character == '-';
+ }
+
+
+ private boolean isComment(char character)
+ {
+ return character == COMMENT_CHARACTER;
+ }
+
+
private boolean isDelimiter(char character)
{
return character == '@' ||
@@ -318,6 +369,16 @@
}
+ private boolean isFileDelimiter(char character)
+ {
+ return character == '(' ||
+ character == ')' ||
+ character == ',' ||
+ character == ';' ||
+ character == File.pathSeparatorChar;
+ }
+
+
private boolean isQuote(char character)
{
return character == '\'' ||
diff --git a/src/proguard/ant/ClassPathElement.java b/src/proguard/ant/ClassPathElement.java
index b5c2df4..53084d3 100644
--- a/src/proguard/ant/ClassPathElement.java
+++ b/src/proguard/ant/ClassPathElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ant/ClassSpecificationElement.java b/src/proguard/ant/ClassSpecificationElement.java
index f4ea2ff..81b0c1b 100644
--- a/src/proguard/ant/ClassSpecificationElement.java
+++ b/src/proguard/ant/ClassSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -222,6 +222,7 @@
strippedToken.equals(ClassConstants.EXTERNAL_ACC_PUBLIC) ? ClassConstants.INTERNAL_ACC_PUBLIC :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_FINAL) ? ClassConstants.INTERNAL_ACC_FINAL :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ANNOTATION) ? ClassConstants.INTERNAL_ACC_ANNOTATTION :
0;
diff --git a/src/proguard/ant/ConfigurationElement.java b/src/proguard/ant/ConfigurationElement.java
index 76e9418..f283b8d 100644
--- a/src/proguard/ant/ConfigurationElement.java
+++ b/src/proguard/ant/ConfigurationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ant/ConfigurationTask.java b/src/proguard/ant/ConfigurationTask.java
index 0d2f04f..6c4d48a 100644
--- a/src/proguard/ant/ConfigurationTask.java
+++ b/src/proguard/ant/ConfigurationTask.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -293,7 +293,8 @@
{
String arg = getProject().replaceProperties(text);
- ConfigurationParser parser = new ConfigurationParser(new String[] { arg },
+ ConfigurationParser parser = new ConfigurationParser(arg,
+ "embedded configuration",
getProject().getBaseDir());
try
diff --git a/src/proguard/ant/FilterElement.java b/src/proguard/ant/FilterElement.java
index d792c5d..1174bd5 100644
--- a/src/proguard/ant/FilterElement.java
+++ b/src/proguard/ant/FilterElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ant/KeepSpecificationElement.java b/src/proguard/ant/KeepSpecificationElement.java
index e36b744..2ac61e8 100644
--- a/src/proguard/ant/KeepSpecificationElement.java
+++ b/src/proguard/ant/KeepSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/ant/MemberSpecificationElement.java b/src/proguard/ant/MemberSpecificationElement.java
index d4bb4a9..789cc5e 100644
--- a/src/proguard/ant/MemberSpecificationElement.java
+++ b/src/proguard/ant/MemberSpecificationElement.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -195,9 +195,12 @@
strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED) ? ClassConstants.INTERNAL_ACC_SYNCHRONIZED :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_VOLATILE) ? ClassConstants.INTERNAL_ACC_VOLATILE :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_TRANSIENT) ? ClassConstants.INTERNAL_ACC_TRANSIENT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_BRIDGE) ? ClassConstants.INTERNAL_ACC_BRIDGE :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_VARARGS) ? ClassConstants.INTERNAL_ACC_VARARGS :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_NATIVE) ? ClassConstants.INTERNAL_ACC_NATIVE :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_ABSTRACT) ? ClassConstants.INTERNAL_ACC_ABSTRACT :
strippedToken.equals(ClassConstants.EXTERNAL_ACC_STRICT) ? ClassConstants.INTERNAL_ACC_STRICT :
+ strippedToken.equals(ClassConstants.EXTERNAL_ACC_SYNTHETIC) ? ClassConstants.INTERNAL_ACC_SYNTHETIC :
0;
if (accessFlag == 0)
diff --git a/src/proguard/ant/ProGuardTask.java b/src/proguard/ant/ProGuardTask.java
index b7fc361..982c2dd 100644
--- a/src/proguard/ant/ProGuardTask.java
+++ b/src/proguard/ant/ProGuardTask.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -215,6 +215,12 @@
}
+ public void setKeepparameternames(boolean keepParameterNames)
+ {
+ configuration.keepParameterNames = keepParameterNames;
+ }
+
+
public void setRenamesourcefileattribute(String newSourceFileAttribute)
{
configuration.newSourceFileAttribute = newSourceFileAttribute;
@@ -241,13 +247,39 @@
public void setNote(boolean note)
{
- configuration.note = note ? null : new ArrayList();
+ if (note)
+ {
+ // Switch on notes if they were completely disabled.
+ if (configuration.note != null &&
+ configuration.note.isEmpty())
+ {
+ configuration.note = null;
+ }
+ }
+ else
+ {
+ // Switch off notes.
+ configuration.note = new ArrayList();
+ }
}
public void setWarn(boolean warn)
{
- configuration.warn = warn ? null : new ArrayList();
+ if (warn)
+ {
+ // Switch on warnings if they were completely disabled.
+ if (configuration.warn != null &&
+ configuration.warn.isEmpty())
+ {
+ configuration.warn = null;
+ }
+ }
+ else
+ {
+ // Switch off warnings.
+ configuration.warn = new ArrayList();
+ }
}
diff --git a/src/proguard/classfile/ClassConstants.java b/src/proguard/classfile/ClassConstants.java
index 3b243e0..081305b 100644
--- a/src/proguard/classfile/ClassConstants.java
+++ b/src/proguard/classfile/ClassConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -43,6 +43,8 @@
public static final int INTERNAL_CLASS_VERSION_1_5_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_6_MAJOR = 50;
public static final int INTERNAL_CLASS_VERSION_1_6_MINOR = 0;
+ public static final int INTERNAL_CLASS_VERSION_1_7_MAJOR = 51;
+ public static final int INTERNAL_CLASS_VERSION_1_7_MINOR = 0;
public static final int INTERNAL_CLASS_VERSION_1_0 = (INTERNAL_CLASS_VERSION_1_0_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_0_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_2 = (INTERNAL_CLASS_VERSION_1_2_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_2_MINOR;
@@ -50,6 +52,7 @@
public static final int INTERNAL_CLASS_VERSION_1_4 = (INTERNAL_CLASS_VERSION_1_4_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_4_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_5 = (INTERNAL_CLASS_VERSION_1_5_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_5_MINOR;
public static final int INTERNAL_CLASS_VERSION_1_6 = (INTERNAL_CLASS_VERSION_1_6_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_6_MINOR;
+ public static final int INTERNAL_CLASS_VERSION_1_7 = (INTERNAL_CLASS_VERSION_1_7_MAJOR << 16) | INTERNAL_CLASS_VERSION_1_7_MINOR;
public static final String EXTERNAL_CLASS_VERSION_1_0 = "1.0";
public static final String EXTERNAL_CLASS_VERSION_1_1 = "1.1";
@@ -58,8 +61,10 @@
public static final String EXTERNAL_CLASS_VERSION_1_4 = "1.4";
public static final String EXTERNAL_CLASS_VERSION_1_5 = "1.5";
public static final String EXTERNAL_CLASS_VERSION_1_6 = "1.6";
+ public static final String EXTERNAL_CLASS_VERSION_1_7 = "1.7";
public static final String EXTERNAL_CLASS_VERSION_1_5_ALIAS = "5";
public static final String EXTERNAL_CLASS_VERSION_1_6_ALIAS = "6";
+ public static final String EXTERNAL_CLASS_VERSION_1_7_ALIAS = "7";
public static final int INTERNAL_ACC_PUBLIC = 0x0001;
public static final int INTERNAL_ACC_PRIVATE = 0x0002;
@@ -119,10 +124,13 @@
public static final String EXTERNAL_ACC_SYNCHRONIZED = "synchronized";
public static final String EXTERNAL_ACC_VOLATILE = "volatile";
public static final String EXTERNAL_ACC_TRANSIENT = "transient";
+ public static final String EXTERNAL_ACC_BRIDGE = "bridge";
+ public static final String EXTERNAL_ACC_VARARGS = "varargs";
public static final String EXTERNAL_ACC_NATIVE = "native";
public static final String EXTERNAL_ACC_INTERFACE = "interface";
public static final String EXTERNAL_ACC_ABSTRACT = "abstract";
public static final String EXTERNAL_ACC_STRICT = "strictfp";
+ public static final String EXTERNAL_ACC_SYNTHETIC = "synthetic";
public static final String EXTERNAL_ACC_ANNOTATION = "@";
public static final String EXTERNAL_ACC_ENUM = "enum";
@@ -137,7 +145,21 @@
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
+ public static final int CONSTANT_MethodHandle = 15;
+ public static final int CONSTANT_MethodType = 16;
+ public static final int CONSTANT_InvokeDynamic = 18;
+ public static final int REF_getField = 1;
+ public static final int REF_getStatic = 2;
+ public static final int REF_putField = 3;
+ public static final int REF_putStatic = 4;
+ public static final int REF_invokeVirtual = 5;
+ public static final int REF_invokeStatic = 6;
+ public static final int REF_invokeSpecial = 7;
+ public static final int REF_newInvokeSpecial = 8;
+ public static final int REF_invokeInterface = 9;
+
+ public static final String ATTR_BootstrapMethods = "BootstrapMethods";
public static final String ATTR_SourceFile = "SourceFile";
public static final String ATTR_SourceDir = "SourceDir";
public static final String ATTR_InnerClasses = "InnerClasses";
@@ -179,32 +201,48 @@
public static final char INTERNAL_METHOD_ARGUMENTS_OPEN = '(';
public static final char INTERNAL_METHOD_ARGUMENTS_CLOSE = ')';
- public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/";
- public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object";
- public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;";
- public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable";
- public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable";
- public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class";
- public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String";
- public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable";
+ public static final String INTERNAL_PACKAGE_JAVA_LANG = "java/lang/";
+ public static final String INTERNAL_NAME_JAVA_LANG_OBJECT = "java/lang/Object";
+ public static final String INTERNAL_TYPE_JAVA_LANG_OBJECT = "Ljava/lang/Object;";
+ public static final String INTERNAL_NAME_JAVA_LANG_CLONEABLE = "java/lang/Cloneable";
+ public static final String INTERNAL_NAME_JAVA_LANG_THROWABLE = "java/lang/Throwable";
+ public static final String INTERNAL_NAME_JAVA_LANG_CLASS = "java/lang/Class";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING = "java/lang/String";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUFFER = "java/lang/StringBuffer";
+ public static final String INTERNAL_NAME_JAVA_LANG_STRING_BUILDER = "java/lang/StringBuilder";
+ public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE = "java/lang/invoke/MethodHandle";
+ public static final String INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE = "java/lang/invoke/MethodType";
+ public static final String INTERNAL_NAME_JAVA_IO_SERIALIZABLE = "java/io/Serializable";
+
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicIntegerFieldUpdater";
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicLongFieldUpdater";
+ public static final String INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER = "java/util/concurrent/atomic/AtomicReferenceFieldUpdater";
public static final String INTERNAL_METHOD_NAME_INIT = "<init>";
public static final String INTERNAL_METHOD_TYPE_INIT = "()V";
public static final String INTERNAL_METHOD_NAME_CLINIT = "<clinit>";
public static final String INTERNAL_METHOD_TYPE_CLINIT = "()V";
- public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName";
- public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
- public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod";
- public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_FOR_NAME = "forName";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_FOR_NAME = "(Ljava/lang/String;)Ljava/lang/Class;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_COMPONENT_TYPE = "getComponentType";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_COMPONENT_TYPE = "()Ljava/lang/Class;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_FIELD = "getField";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_FIELD = "getDeclaredField";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD = "(Ljava/lang/String;)Ljava/lang/reflect/Field;";
+ public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR = "getConstructor";
+ public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;";
+ public static final String INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR = "getDeclaredConstructor";
+ public static final String INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR = "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_METHOD = "getMethod";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_CLASS_GET_DECLARED_METHOD = "getDeclaredMethod";
+ public static final String INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD = "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;";
+ public static final String INTERNAL_METHOD_NAME_NEW_UPDATER = "newUpdater";
+ public static final String INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicIntegerFieldUpdater;";
+ public static final String INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER = "(Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicLongFieldUpdater;";
+ public static final String INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER = "(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;)Ljava/util/concurrent/atomic/AtomicReferenceFieldUpdater;";
public static final String INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC = "class$";
public static final String INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC = "(Ljava/lang/String;)Ljava/lang/Class;";
@@ -214,6 +252,29 @@
public static final String INTERNAL_METHOD_NAME_NEW_INSTANCE = "newInstance";
public static final String INTERNAL_METHOD_TYPE_NEW_INSTANCE = "()Ljava/lang/Object;";
+ public static final String INTERNAL_METHOD_NAME_EQUALS = "equals";
+ public static final String INTERNAL_METHOD_TYPE_EQUALS = "(Ljava/lang/Object;)Z";
+ public static final String INTERNAL_METHOD_NAME_LENGTH = "length";
+ public static final String INTERNAL_METHOD_TYPE_LENGTH = "()I";
+ public static final String INTERNAL_METHOD_NAME_APPEND = "append";
+ public static final String INTERNAL_METHOD_TYPE_STRING_VOID = "(Ljava/lang/String;)V";
+ public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER = "(Z)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER = "(C)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUFFER = "(I)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER = "(J)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER = "(F)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER = "(D)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER = "(Ljava/lang/String;)Ljava/lang/StringBuffer;";
+ public static final String INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER = "(Z)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER = "(C)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_INT_STRING_BUILDER = "(I)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER = "(J)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER = "(F)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER = "(D)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER = "(Ljava/lang/String;)Ljava/lang/StringBuilder;";
+ public static final String INTERNAL_METHOD_NAME_TOSTRING = "toString";
+ public static final String INTERNAL_METHOD_TYPE_TOSTRING = "()Ljava/lang/String;";
+
public static final char INTERNAL_TYPE_VOID = 'V';
public static final char INTERNAL_TYPE_BOOLEAN = 'Z';
public static final char INTERNAL_TYPE_BYTE = 'B';
diff --git a/src/proguard/classfile/ClassPool.java b/src/proguard/classfile/ClassPool.java
index 57728a5..c5defe8 100644
--- a/src/proguard/classfile/ClassPool.java
+++ b/src/proguard/classfile/ClassPool.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,14 +26,16 @@
import java.util.*;
/**
- * This is a set of representations of classes. They can be enumerated or
+ * This is a set of representations of classes. They can be enumerated or
* retrieved by name. They can also be accessed by means of class visitors.
*
* @author Eric Lafortune
*/
public class ClassPool
{
- private final Map classes = new HashMap();
+ // We're using a sorted tree map instead of a hash map to store the classes,
+ // in order to make the processing more deterministic.
+ private final Map classes = new TreeMap();
/**
@@ -66,11 +68,11 @@
/**
* Returns a Clazz from the class pool based on its name. Returns
* <code>null</code> if the class with the given name is not in the class
- * pool. Returns the base class if the class name is an array type.
+ * pool.
*/
public Clazz getClass(String className)
{
- return (Clazz)classes.get(ClassUtil.internalClassNameFromClassType(className));
+ return (Clazz)classes.get(className);
}
@@ -122,8 +124,11 @@
*/
public void classesAcceptAlphabetically(ClassVisitor classVisitor)
{
- TreeMap sortedClasses = new TreeMap(classes);
- Iterator iterator = sortedClasses.values().iterator();
+ // We're already using a tree map.
+ //TreeMap sortedClasses = new TreeMap(classes);
+ //Iterator iterator = sortedClasses.values().iterator();
+
+ Iterator iterator = classes.values().iterator();
while (iterator.hasNext())
{
Clazz clazz = (Clazz)iterator.next();
diff --git a/src/proguard/classfile/Clazz.java b/src/proguard/classfile/Clazz.java
index da37d9a..3dfdcd0 100644
--- a/src/proguard/classfile/Clazz.java
+++ b/src/proguard/classfile/Clazz.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -90,6 +90,16 @@
*/
public String getType(int constantIndex);
+ /**
+ * Returns the name of the RefConstant at the specified index.
+ */
+ public String getRefName(int constantIndex);
+
+ /**
+ * Returns the type of the RefConstant at the specified index.
+ */
+ public String getRefType(int constantIndex);
+
// Methods pertaining to related classes.
@@ -116,12 +126,26 @@
public boolean extends_(Clazz clazz);
/**
+ * Returns whether this class extends the specified class.
+ * A class is always considered to extend itself.
+ * Interfaces are considered to only extend the root Object class.
+ */
+ public boolean extends_(String className);
+
+ /**
* Returns whether this class implements the given class.
* A class is always considered to implement itself.
* Interfaces are considered to implement all their superinterfaces.
*/
public boolean extendsOrImplements(Clazz clazz);
+ /**
+ * Returns whether this class implements the specified class.
+ * A class is always considered to implement itself.
+ * Interfaces are considered to implement all their superinterfaces.
+ */
+ public boolean extendsOrImplements(String className);
+
// Methods for getting specific class members.
@@ -229,4 +253,9 @@
* Lets the given attribute info visitor visit all attributes of this class.
*/
public void attributesAccept(AttributeVisitor attributeVisitor);
+
+ /**
+ * Lets the given attribute info visitor visit the specified attribute.
+ */
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor);
}
diff --git a/src/proguard/classfile/Field.java b/src/proguard/classfile/Field.java
index ba1315a..c30321d 100644
--- a/src/proguard/classfile/Field.java
+++ b/src/proguard/classfile/Field.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/LibraryClass.java b/src/proguard/classfile/LibraryClass.java
index 0a27593..625d088 100644
--- a/src/proguard/classfile/LibraryClass.java
+++ b/src/proguard/classfile/LibraryClass.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -137,6 +137,17 @@
}
+ public String getRefName(int constantIndex)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
+ }
+
+ public String getRefType(int constantIndex)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store constant pool");
+ }
+
+
public void addSubClass(Clazz clazz)
{
if (subClasses == null)
@@ -179,6 +190,18 @@
}
+ public boolean extends_(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ return superClass != null &&
+ superClass.extends_(className);
+ }
+
+
public boolean extendsOrImplements(Clazz clazz)
{
if (this.equals(clazz))
@@ -209,6 +232,36 @@
}
+ public boolean extendsOrImplements(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ if (superClass != null &&
+ superClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+
+ if (interfaceClasses != null)
+ {
+ for (int index = 0; index < interfaceClasses.length; index++)
+ {
+ Clazz interfaceClass = interfaceClasses[index];
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
public Field findField(String name, String descriptor)
{
for (int index = 0; index < fields.length; index++)
@@ -467,6 +520,12 @@
}
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor)
+ {
+ throw new UnsupportedOperationException("Library class ["+thisClassName+"] doesn't store attributes");
+ }
+
+
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
diff --git a/src/proguard/classfile/LibraryField.java b/src/proguard/classfile/LibraryField.java
index 2908c37..e9c8469 100644
--- a/src/proguard/classfile/LibraryField.java
+++ b/src/proguard/classfile/LibraryField.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/LibraryMember.java b/src/proguard/classfile/LibraryMember.java
index 41ccb60..ef5a4d7 100644
--- a/src/proguard/classfile/LibraryMember.java
+++ b/src/proguard/classfile/LibraryMember.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/LibraryMethod.java b/src/proguard/classfile/LibraryMethod.java
index a49a5f1..cd95ea6 100644
--- a/src/proguard/classfile/LibraryMethod.java
+++ b/src/proguard/classfile/LibraryMethod.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/Member.java b/src/proguard/classfile/Member.java
index 1400b9c..2e984c2 100644
--- a/src/proguard/classfile/Member.java
+++ b/src/proguard/classfile/Member.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/Method.java b/src/proguard/classfile/Method.java
index ebcae2b..ec8f2b5 100644
--- a/src/proguard/classfile/Method.java
+++ b/src/proguard/classfile/Method.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/ProgramClass.java b/src/proguard/classfile/ProgramClass.java
index 9d0fc0c..e3caddb 100644
--- a/src/proguard/classfile/ProgramClass.java
+++ b/src/proguard/classfile/ProgramClass.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -117,8 +117,7 @@
}
catch (ClassCastException ex)
{
- new ClassPrinter().visitProgramClass(this);
- throw new ClassCastException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -130,7 +129,7 @@
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -142,7 +141,7 @@
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -154,7 +153,7 @@
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -166,7 +165,32 @@
}
catch (ClassCastException ex)
{
- throw new ClassCastException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
+ throw ((IllegalStateException)new IllegalStateException("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+
+ public String getRefName(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getName(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
+ }
+ }
+
+ public String getRefType(int constantIndex)
+ {
+ try
+ {
+ return ((RefConstant)constantPool[constantIndex]).getType(this);
+ }
+ catch (ClassCastException ex)
+ {
+ throw ((IllegalStateException)new IllegalStateException("Expected RefConstant at index ["+constantIndex+"] in class ["+getName()+"]").initCause(ex));
}
}
@@ -216,6 +240,19 @@
}
+ public boolean extends_(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ return superClass != null &&
+ superClass.extends_(className);
+ }
+
+
public boolean extendsOrImplements(Clazz clazz)
{
if (this.equals(clazz))
@@ -244,6 +281,34 @@
}
+ public boolean extendsOrImplements(String className)
+ {
+ if (getName().equals(className))
+ {
+ return true;
+ }
+
+ Clazz superClass = getSuperClass();
+ if (superClass != null &&
+ superClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+
+ for (int index = 0; index < u2interfacesCount; index++)
+ {
+ Clazz interfaceClass = getInterface(index);
+ if (interfaceClass != null &&
+ interfaceClass.extendsOrImplements(className))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
public Field findField(String name, String descriptor)
{
for (int index = 0; index < u2fieldsCount; index++)
@@ -472,6 +537,19 @@
}
+ public void attributeAccept(String name, AttributeVisitor attributeVisitor)
+ {
+ for (int index = 0; index < u2attributesCount; index++)
+ {
+ Attribute attribute = attributes[index];
+ if (attribute.getAttributeName(this).equals(name))
+ {
+ attribute.accept(this, attributeVisitor);
+ }
+ }
+ }
+
+
// Implementations for VisitorAccepter.
public Object getVisitorInfo()
diff --git a/src/proguard/classfile/ProgramField.java b/src/proguard/classfile/ProgramField.java
index 5991b00..761fe95 100644
--- a/src/proguard/classfile/ProgramField.java
+++ b/src/proguard/classfile/ProgramField.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/ProgramMember.java b/src/proguard/classfile/ProgramMember.java
index ea6f46d..86d12d9 100644
--- a/src/proguard/classfile/ProgramMember.java
+++ b/src/proguard/classfile/ProgramMember.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/ProgramMethod.java b/src/proguard/classfile/ProgramMethod.java
index 943c3d6..39e720f 100644
--- a/src/proguard/classfile/ProgramMethod.java
+++ b/src/proguard/classfile/ProgramMethod.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/VisitorAccepter.java b/src/proguard/classfile/VisitorAccepter.java
index e38f888..551d025 100644
--- a/src/proguard/classfile/VisitorAccepter.java
+++ b/src/proguard/classfile/VisitorAccepter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/Attribute.java b/src/proguard/classfile/attribute/Attribute.java
index 2e16e22..0eaafbb 100644
--- a/src/proguard/classfile/attribute/Attribute.java
+++ b/src/proguard/classfile/attribute/Attribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/BootstrapMethodInfo.java b/src/proguard/classfile/attribute/BootstrapMethodInfo.java
new file mode 100755
index 0000000..c593251
--- /dev/null
+++ b/src/proguard/classfile/attribute/BootstrapMethodInfo.java
@@ -0,0 +1,89 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * Representation of a bootstrap method.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodInfo implements VisitorAccepter
+{
+ public int u2methodHandleIndex;
+ public int u2methodArgumentCount;
+ public int[] u2methodArguments;
+
+ /**
+ * An extra field in which visitors can store information.
+ */
+ public Object visitorInfo;
+
+
+ /**
+ * Creates an uninitialized BootstrapMethodInfo.
+ */
+ public BootstrapMethodInfo()
+ {
+ }
+
+
+ /**
+ * Creates an initialized BootstrapMethodInfo.
+ */
+ public BootstrapMethodInfo(int u2methodHandleIndex,
+ int u2methodArgumentCount,
+ int[] u2methodArguments)
+ {
+ this.u2methodHandleIndex = u2methodHandleIndex;
+ this.u2methodArgumentCount = u2methodArgumentCount;
+ this.u2methodArguments = u2methodArguments;
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to the argument constants of the
+ * bootstrap method.
+ */
+ public void methodArgumentsAccept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ for (int index = 0; index < u2methodArgumentCount; index++)
+ {
+ clazz.constantPoolEntryAccept(u2methodArguments[index],
+ constantVisitor);
+ }
+ }
+
+
+ // Implementations for VisitorAccepter.
+
+ public Object getVisitorInfo()
+ {
+ return visitorInfo;
+ }
+
+ public void setVisitorInfo(Object visitorInfo)
+ {
+ this.visitorInfo = visitorInfo;
+ }
+}
diff --git a/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java
new file mode 100755
index 0000000..b8ec9bd
--- /dev/null
+++ b/src/proguard/classfile/attribute/BootstrapMethodsAttribute.java
@@ -0,0 +1,95 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Attribute represents a bootstrap methods attribute.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodsAttribute extends Attribute
+{
+ public int u2bootstrapMethodsCount;
+ public BootstrapMethodInfo[] bootstrapMethods;
+
+
+ /**
+ * Creates an uninitialized BootstrapMethodsAttribute.
+ */
+ public BootstrapMethodsAttribute()
+ {
+ }
+
+
+ /**
+ * Creates an initialized BootstrapMethodsAttribute.
+ */
+ public BootstrapMethodsAttribute(int u2attributeNameIndex,
+ int u2bootstrapMethodsCount,
+ BootstrapMethodInfo[] bootstrapMethods)
+ {
+ super(u2attributeNameIndex);
+
+ this.u2bootstrapMethodsCount = u2bootstrapMethodsCount;
+ this.bootstrapMethods = bootstrapMethods;
+ }
+
+
+ // Implementations for Attribute.
+
+ public void accept(Clazz clazz, AttributeVisitor attributeVisitor)
+ {
+ attributeVisitor.visitBootstrapMethodsAttribute(clazz, this);
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to all bootstrap method info
+ * entries.
+ */
+ public void bootstrapMethodEntriesAccept(Clazz clazz, BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ for (int index = 0; index < u2bootstrapMethodsCount; index++)
+ {
+ // We don't need double dispatching here, since there is only one
+ // type of BootstrapMethodInfo.
+ bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[index]);
+ }
+ }
+
+
+ /**
+ * Applies the given constant pool visitor to the specified bootstrap method
+ * info entry.
+ */
+ public void bootstrapMethodEntryAccept(Clazz clazz,
+ int bootstrapMethodIndex,
+ BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ // We don't need double dispatching here, since there is only one
+ // type of BootstrapMethodInfo.
+ bootstrapMethodInfoVisitor.visitBootstrapMethodInfo(clazz, bootstrapMethods[bootstrapMethodIndex]);
+ }
+}
diff --git a/src/proguard/classfile/attribute/CodeAttribute.java b/src/proguard/classfile/attribute/CodeAttribute.java
index 92ff9ea..9d5a254 100644
--- a/src/proguard/classfile/attribute/CodeAttribute.java
+++ b/src/proguard/classfile/attribute/CodeAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/ConstantValueAttribute.java b/src/proguard/classfile/attribute/ConstantValueAttribute.java
index 3ae991e..737ade0 100644
--- a/src/proguard/classfile/attribute/ConstantValueAttribute.java
+++ b/src/proguard/classfile/attribute/ConstantValueAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/DeprecatedAttribute.java b/src/proguard/classfile/attribute/DeprecatedAttribute.java
index 4180950..d440242 100644
--- a/src/proguard/classfile/attribute/DeprecatedAttribute.java
+++ b/src/proguard/classfile/attribute/DeprecatedAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
index 9275b3a..befd585 100644
--- a/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
+++ b/src/proguard/classfile/attribute/EnclosingMethodAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/ExceptionInfo.java b/src/proguard/classfile/attribute/ExceptionInfo.java
index 082efab..5f605cf 100644
--- a/src/proguard/classfile/attribute/ExceptionInfo.java
+++ b/src/proguard/classfile/attribute/ExceptionInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/ExceptionsAttribute.java b/src/proguard/classfile/attribute/ExceptionsAttribute.java
index d22c4a6..8dfd096 100644
--- a/src/proguard/classfile/attribute/ExceptionsAttribute.java
+++ b/src/proguard/classfile/attribute/ExceptionsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -69,12 +69,12 @@
* Applies the given constant pool visitor to all exception class pool info
* entries.
*/
- public void exceptionEntriesAccept(ProgramClass programClass, ConstantVisitor constantVisitor)
+ public void exceptionEntriesAccept(Clazz clazz, ConstantVisitor constantVisitor)
{
for (int index = 0; index < u2exceptionIndexTableLength; index++)
{
- programClass.constantPoolEntryAccept(u2exceptionIndexTable[index],
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2exceptionIndexTable[index],
+ constantVisitor);
}
}
}
diff --git a/src/proguard/classfile/attribute/InnerClassesAttribute.java b/src/proguard/classfile/attribute/InnerClassesAttribute.java
index 2f7e310..135c61c 100644
--- a/src/proguard/classfile/attribute/InnerClassesAttribute.java
+++ b/src/proguard/classfile/attribute/InnerClassesAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/InnerClassesInfo.java b/src/proguard/classfile/attribute/InnerClassesInfo.java
index 1bdd6c3..87f9768 100644
--- a/src/proguard/classfile/attribute/InnerClassesInfo.java
+++ b/src/proguard/classfile/attribute/InnerClassesInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -74,8 +74,7 @@
{
if (u2innerClassIndex != 0)
{
- clazz.constantPoolEntryAccept(u2innerClassIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2innerClassIndex, constantVisitor);
}
}
@@ -88,8 +87,7 @@
{
if (u2outerClassIndex != 0)
{
- clazz.constantPoolEntryAccept(u2outerClassIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2outerClassIndex, constantVisitor);
}
}
@@ -102,8 +100,7 @@
{
if (u2innerNameIndex != 0)
{
- clazz.constantPoolEntryAccept(u2innerNameIndex,
- constantVisitor);
+ clazz.constantPoolEntryAccept(u2innerNameIndex, constantVisitor);
}
}
diff --git a/src/proguard/classfile/attribute/LineNumberInfo.java b/src/proguard/classfile/attribute/LineNumberInfo.java
index f58083a..6ad7ed2 100644
--- a/src/proguard/classfile/attribute/LineNumberInfo.java
+++ b/src/proguard/classfile/attribute/LineNumberInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/LineNumberTableAttribute.java b/src/proguard/classfile/attribute/LineNumberTableAttribute.java
index 4d507d9..b9056d9 100644
--- a/src/proguard/classfile/attribute/LineNumberTableAttribute.java
+++ b/src/proguard/classfile/attribute/LineNumberTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/LocalVariableInfo.java b/src/proguard/classfile/attribute/LocalVariableInfo.java
index 4e54c22..589bb7a 100644
--- a/src/proguard/classfile/attribute/LocalVariableInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,7 +28,7 @@
*
* @author Eric Lafortune
*/
-public class LocalVariableInfo
+public class LocalVariableInfo implements Comparable
{
public int u2startPC;
public int u2length;
@@ -80,4 +80,20 @@
referencedClass.accept(classVisitor);
}
}
+
+
+ // Implementations for Comparable.
+
+ public int compareTo(Object object)
+ {
+ LocalVariableInfo other = (LocalVariableInfo)object;
+
+ return
+ this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 :
+ this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 :
+ this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 :
+ this.u2descriptorIndex < other.u2descriptorIndex ? -1 : this.u2descriptorIndex > other.u2descriptorIndex ? 1 :
+ this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 :
+ 0;
+ }
}
diff --git a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
index 9c3f115..02eae2a 100644
--- a/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
+++ b/src/proguard/classfile/attribute/LocalVariableTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
index 1b71f35..3a77e3d 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,7 +28,7 @@
*
* @author Eric Lafortune
*/
-public class LocalVariableTypeInfo
+public class LocalVariableTypeInfo implements Comparable
{
public int u2startPC;
public int u2length;
@@ -88,4 +88,20 @@
}
}
}
+
+
+ // Implementations for Comparable.
+
+ public int compareTo(Object object)
+ {
+ LocalVariableTypeInfo other = (LocalVariableTypeInfo)object;
+
+ return
+ this.u2startPC < other.u2startPC ? -1 : this.u2startPC > other.u2startPC ? 1 :
+ this.u2length < other.u2length ? -1 : this.u2length > other.u2length ? 1 :
+ this.u2index < other.u2index ? -1 : this.u2index > other.u2index ? 1 :
+ this.u2signatureIndex < other.u2signatureIndex ? -1 : this.u2signatureIndex > other.u2signatureIndex ? 1 :
+ this.u2nameIndex < other.u2nameIndex ? -1 : this.u2nameIndex > other.u2nameIndex ? 1 :
+ 0;
+ }
}
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
index fd856fe..3a2ab75 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/SignatureAttribute.java b/src/proguard/classfile/attribute/SignatureAttribute.java
index c7585fe..2b59775 100644
--- a/src/proguard/classfile/attribute/SignatureAttribute.java
+++ b/src/proguard/classfile/attribute/SignatureAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/SourceDirAttribute.java b/src/proguard/classfile/attribute/SourceDirAttribute.java
index a26e8b1..f9e4005 100644
--- a/src/proguard/classfile/attribute/SourceDirAttribute.java
+++ b/src/proguard/classfile/attribute/SourceDirAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/SourceFileAttribute.java b/src/proguard/classfile/attribute/SourceFileAttribute.java
index 24269b7..b28e139 100644
--- a/src/proguard/classfile/attribute/SourceFileAttribute.java
+++ b/src/proguard/classfile/attribute/SourceFileAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/SyntheticAttribute.java b/src/proguard/classfile/attribute/SyntheticAttribute.java
index 6ccb1b5..cbb7e30 100644
--- a/src/proguard/classfile/attribute/SyntheticAttribute.java
+++ b/src/proguard/classfile/attribute/SyntheticAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/UnknownAttribute.java b/src/proguard/classfile/attribute/UnknownAttribute.java
index 2f138bd..11f6029 100644
--- a/src/proguard/classfile/attribute/UnknownAttribute.java
+++ b/src/proguard/classfile/attribute/UnknownAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/Annotation.java b/src/proguard/classfile/attribute/annotation/Annotation.java
index 41bb8e3..248c8f3 100644
--- a/src/proguard/classfile/attribute/annotation/Annotation.java
+++ b/src/proguard/classfile/attribute/annotation/Annotation.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
index b378cd2..9ac7eae 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
index 29129d0..0cfefac 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
index 8117077..1786f15 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
index 25b8b9f..f2bf911 100644
--- a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/ClassElementValue.java b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
index ba51641..b174695 100644
--- a/src/proguard/classfile/attribute/annotation/ClassElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
index 3ebe5e5..f8bfc7f 100644
--- a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/ElementValue.java b/src/proguard/classfile/attribute/annotation/ElementValue.java
index 39f8953..415aa6a 100644
--- a/src/proguard/classfile/attribute/annotation/ElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
index d46bb7f..c6fbb52 100644
--- a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
index 3c700c8..0aca20f 100644
--- a/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/ParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
index 9c8180c..4494b4c 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
index 7e41656..5696a37 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
index 380c52e..e25d868 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
index 626fbda..722792e 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
index bce7170..4af6946 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AllAnnotationVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
index 7a1d7c6..4582728 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotatedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
index c206c16..c3e5eb0 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationToMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
index d869fd2..6068dfb 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationTypeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
index 16b2a56..b079628 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/AnnotationVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
index 112084a..0f89b06 100644
--- a/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/visitor/ElementValueVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/DoubleType.java b/src/proguard/classfile/attribute/preverification/DoubleType.java
index d574dcb..4cc614d 100644
--- a/src/proguard/classfile/attribute/preverification/DoubleType.java
+++ b/src/proguard/classfile/attribute/preverification/DoubleType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/FloatType.java b/src/proguard/classfile/attribute/preverification/FloatType.java
index 2f24720..2559d53 100644
--- a/src/proguard/classfile/attribute/preverification/FloatType.java
+++ b/src/proguard/classfile/attribute/preverification/FloatType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/FullFrame.java b/src/proguard/classfile/attribute/preverification/FullFrame.java
index adf5684..39cc7f6 100644
--- a/src/proguard/classfile/attribute/preverification/FullFrame.java
+++ b/src/proguard/classfile/attribute/preverification/FullFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/IntegerType.java b/src/proguard/classfile/attribute/preverification/IntegerType.java
index 55e3abe..3dc6382 100644
--- a/src/proguard/classfile/attribute/preverification/IntegerType.java
+++ b/src/proguard/classfile/attribute/preverification/IntegerType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
index fcc8e0a..e995346 100644
--- a/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/LessZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/LongType.java b/src/proguard/classfile/attribute/preverification/LongType.java
index 9b14dd6..a2f3eaa 100644
--- a/src/proguard/classfile/attribute/preverification/LongType.java
+++ b/src/proguard/classfile/attribute/preverification/LongType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
index 881f188..1a375f1 100644
--- a/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/MoreZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/NullType.java b/src/proguard/classfile/attribute/preverification/NullType.java
index f35cefd..4832751 100644
--- a/src/proguard/classfile/attribute/preverification/NullType.java
+++ b/src/proguard/classfile/attribute/preverification/NullType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/ObjectType.java b/src/proguard/classfile/attribute/preverification/ObjectType.java
index fbdeec7..acc45e1 100644
--- a/src/proguard/classfile/attribute/preverification/ObjectType.java
+++ b/src/proguard/classfile/attribute/preverification/ObjectType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/SameOneFrame.java b/src/proguard/classfile/attribute/preverification/SameOneFrame.java
index db6747b..7d5db73 100644
--- a/src/proguard/classfile/attribute/preverification/SameOneFrame.java
+++ b/src/proguard/classfile/attribute/preverification/SameOneFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
index 64b17f5..ffde7f5 100644
--- a/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
+++ b/src/proguard/classfile/attribute/preverification/SameZeroFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
index db53ff1..fe0e010 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/StackMapFrame.java b/src/proguard/classfile/attribute/preverification/StackMapFrame.java
index aa3e1f2..999863b 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapFrame.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapFrame.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
index 0cddf70..7a2be14 100644
--- a/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
+++ b/src/proguard/classfile/attribute/preverification/StackMapTableAttribute.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/TopType.java b/src/proguard/classfile/attribute/preverification/TopType.java
index bde8dda..27321bc 100644
--- a/src/proguard/classfile/attribute/preverification/TopType.java
+++ b/src/proguard/classfile/attribute/preverification/TopType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
index dc4654f..1a9bf83 100644
--- a/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
+++ b/src/proguard/classfile/attribute/preverification/UninitializedThisType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/UninitializedType.java b/src/proguard/classfile/attribute/preverification/UninitializedType.java
index a495f1f..4b2963c 100644
--- a/src/proguard/classfile/attribute/preverification/UninitializedType.java
+++ b/src/proguard/classfile/attribute/preverification/UninitializedType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/VerificationType.java b/src/proguard/classfile/attribute/preverification/VerificationType.java
index f33d511..720f221 100644
--- a/src/proguard/classfile/attribute/preverification/VerificationType.java
+++ b/src/proguard/classfile/attribute/preverification/VerificationType.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
index f8ef7e0..c99ee7d 100644
--- a/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
+++ b/src/proguard/classfile/attribute/preverification/VerificationTypeFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
index 7db246c..1b4ffad 100644
--- a/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
+++ b/src/proguard/classfile/attribute/preverification/visitor/StackMapFrameVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
index e9931f8..703e8c4 100644
--- a/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
+++ b/src/proguard/classfile/attribute/preverification/visitor/VerificationTypeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
index 61b0f1a..8c4555d 100644
--- a/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AllAttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java
new file mode 100644
index 0000000..fbc9189
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/AllBootstrapMethodInfoVisitor.java
@@ -0,0 +1,55 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This AttributeVisitor lets a given BootstrapMethodInfoVisitor visit all
+ * bootstrap method objects of the BootstrapMethodsAttribute objects it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class AllBootstrapMethodInfoVisitor
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor;
+
+
+ public AllBootstrapMethodInfoVisitor(BootstrapMethodInfoVisitor bootstrapMethodInfoVisitor)
+ {
+ this.bootstrapMethodInfoVisitor = bootstrapMethodInfoVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, bootstrapMethodInfoVisitor);
+ }
+}
diff --git a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
index 839e104..e502123 100644
--- a/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AllExceptionInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java
new file mode 100644
index 0000000..3e1f0a7
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/AllInnerClassesInfoVisitor.java
@@ -0,0 +1,55 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This AttributeVisitor lets a given InnerClassesInfoVisitor visit all
+ * InnerClassessInfo objects of the InnerClassesAttribute objects it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class AllInnerClassesInfoVisitor
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final InnerClassesInfoVisitor innerClassesInfoVisitor;
+
+
+ public AllInnerClassesInfoVisitor(InnerClassesInfoVisitor innerClassesInfoVisitor)
+ {
+ this.innerClassesInfoVisitor = innerClassesInfoVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ innerClassesAttribute.innerClassEntriesAccept(clazz, innerClassesInfoVisitor);
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
index aa81ce0..9906483 100644
--- a/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
+++ b/src/proguard/classfile/attribute/visitor/AttributeNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -24,7 +24,7 @@
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.preverification.*;
-import proguard.util.StringMatcher;
+import proguard.util.*;
/**
* This AttributeVisitor delegates its visits another AttributeVisitor, but
@@ -41,7 +41,21 @@
/**
- * Creates a new AttributeNameFilter.
+ * Creates a new AttributeNameFilter based on a given name.
+ * @param name the string matcher that will check the attribute
+ * names.
+ * @param attributeVisitor the <code>AttributeVisitor</code> to which
+ * visits will be delegated.
+ */
+ public AttributeNameFilter(String name,
+ AttributeVisitor attributeVisitor)
+ {
+ this(new FixedStringMatcher(name), attributeVisitor);
+ }
+
+
+ /**
+ * Creates a new AttributeNameFilter based on a given string matcher.
* @param stringMatcher the string matcher that will check the attribute
* names.
* @param attributeVisitor the <code>AttributeVisitor</code> to which
@@ -66,6 +80,15 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (accepted(clazz, bootstrapMethodsAttribute))
+ {
+ bootstrapMethodsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
if (accepted(clazz, sourceFileAttribute))
diff --git a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
index e8f226b..bb7ee34 100644
--- a/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/AttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -35,11 +35,12 @@
{
// Attributes that are attached to classes.
- public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute);
- public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute);
- public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute);
- public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute);
- public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute);
+ public void visitUnknownAttribute( Clazz clazz, UnknownAttribute unknownAttribute);
+ public void visitBootstrapMethodsAttribute( Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute);
+ public void visitSourceFileAttribute( Clazz clazz, SourceFileAttribute sourceFileAttribute);
+ public void visitSourceDirAttribute( Clazz clazz, SourceDirAttribute sourceDirAttribute);
+ public void visitInnerClassesAttribute( Clazz clazz, InnerClassesAttribute innerClassesAttribute);
+ public void visitEnclosingMethodAttribute( Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute);
// Attributes that are attached to classes, fields, and methods.
diff --git a/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
new file mode 100755
index 0000000..4828d7f
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/BootstrapMethodInfoVisitor.java
@@ -0,0 +1,40 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+
+import java.beans.MethodDescriptor;
+
+
+/**
+ * This interface specifies the methods for a visitor of
+ * <code>BootstrapMethodInfo</code> objects. Note that there is only a single
+ * implementation of <code>BootstrapMethodInfo</code>, such that this interface
+ * is not strictly necessary as a visitor.
+ *
+ * @author Eric Lafortune
+ */
+public interface BootstrapMethodInfoVisitor
+{
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo);
+}
diff --git a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
index 7c85e53..a96d4bf 100644
--- a/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/ExceptionInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
index 91267b0..8f033bf 100644
--- a/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/InnerClassesInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
index e59ed7b..32efa63 100644
--- a/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LineNumberInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
index 8647cb3..d00e184 100644
--- a/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LocalVariableInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
index 9ad38e0..7018fea 100644
--- a/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/LocalVariableTypeInfoVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
index 870ba94..4156654 100644
--- a/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
+++ b/src/proguard/classfile/attribute/visitor/MultiAttributeVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -85,6 +85,15 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ for (int index = 0; index < attributeVisitors.length; index++)
+ {
+ attributeVisitors[index].visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
for (int index = 0; index < attributeVisitors.length; index++)
diff --git a/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java
new file mode 100644
index 0000000..1b0460f
--- /dev/null
+++ b/src/proguard/classfile/attribute/visitor/NonEmptyAttributeFilter.java
@@ -0,0 +1,293 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.attribute.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.preverification.*;
+import proguard.util.StringMatcher;
+
+/**
+ * This AttributeVisitor delegates its visits another AttributeVisitor, but
+ * only when the visited attribute is not empty. For instance, a local variable
+ * table without variables is empty.
+ *
+ * @author Eric Lafortune
+ */
+public class NonEmptyAttributeFilter
+implements AttributeVisitor
+{
+ private final AttributeVisitor attributeVisitor;
+
+
+ /**
+ * Creates a new NonEmptyAttributeFilter.
+ * @param attributeVisitor the <code>AttributeVisitor</code> to which
+ * visits will be delegated.
+ */
+ public NonEmptyAttributeFilter(AttributeVisitor attributeVisitor)
+ {
+ this.attributeVisitor = attributeVisitor;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
+ {
+ unknownAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (bootstrapMethodsAttribute.u2bootstrapMethodsCount > 0)
+ {
+ bootstrapMethodsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
+ {
+ sourceFileAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
+ {
+ sourceDirAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ if (innerClassesAttribute.u2classesCount > 0)
+ {
+ innerClassesAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
+ {
+ enclosingMethodAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
+ {
+ deprecatedAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
+ {
+ syntheticAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute signatureAttribute)
+ {
+ signatureAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ constantValueAttribute.accept(clazz, field, attributeVisitor);
+ }
+
+
+ public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
+ {
+ if (exceptionsAttribute.u2exceptionIndexTableLength > 0)
+ {
+ exceptionsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ codeAttribute.accept(clazz, method, attributeVisitor);
+ }
+
+
+ public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
+ {
+ if (stackMapAttribute.u2stackMapFramesCount > 0)
+ {
+ stackMapAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
+ {
+ if (stackMapTableAttribute.u2stackMapFramesCount > 0)
+ {
+ stackMapTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
+ {
+ if (lineNumberTableAttribute.u2lineNumberTableLength > 0)
+ {
+ lineNumberTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ if (localVariableTableAttribute.u2localVariableTableLength > 0)
+ {
+ localVariableTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ if (localVariableTypeTableAttribute.u2localVariableTypeTableLength > 0)
+ {
+ localVariableTypeTableAttribute.accept(clazz, method, codeAttribute, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
+ {
+ if (runtimeVisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeVisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, field, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
+ {
+ if (runtimeInvisibleAnnotationsAttribute.u2annotationsCount > 0)
+ {
+ runtimeInvisibleAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
+ {
+ if (runtimeVisibleParameterAnnotationsAttribute.u2parametersCount > 0)
+ {
+ runtimeVisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
+ {
+ if (runtimeInvisibleParameterAnnotationsAttribute.u2parametersCount > 0)
+ {
+ runtimeInvisibleParameterAnnotationsAttribute.accept(clazz, method, attributeVisitor);
+ }
+ }
+
+
+ public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
+ {
+ annotationDefaultAttribute.accept(clazz, method, attributeVisitor);
+ }
+}
diff --git a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
index 92099f9..e392ee7 100644
--- a/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
+++ b/src/proguard/classfile/attribute/visitor/RequiredAttributeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -80,6 +80,15 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (requiredAttributeVisitor != null)
+ {
+ bootstrapMethodsAttribute.accept(clazz, requiredAttributeVisitor);
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
if (optionalAttributeVisitor != null)
diff --git a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
index 401f188..c4711d1 100644
--- a/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
+++ b/src/proguard/classfile/attribute/visitor/StackSizeComputer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -27,6 +27,8 @@
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor computes the stack sizes at all instruction offsets
* of the code attributes that it visits.
@@ -140,10 +142,7 @@
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- evaluated[index] = false;
- }
+ Arrays.fill(evaluated, 0, codeLength, false);
}
// The initial stack is always empty.
diff --git a/src/proguard/classfile/constant/ClassConstant.java b/src/proguard/classfile/constant/ClassConstant.java
index d217bf6..b9089d2 100644
--- a/src/proguard/classfile/constant/ClassConstant.java
+++ b/src/proguard/classfile/constant/ClassConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/Constant.java b/src/proguard/classfile/constant/Constant.java
index 30ce5df..ec25a67 100644
--- a/src/proguard/classfile/constant/Constant.java
+++ b/src/proguard/classfile/constant/Constant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/DoubleConstant.java b/src/proguard/classfile/constant/DoubleConstant.java
index 61779b5..08827c2 100644
--- a/src/proguard/classfile/constant/DoubleConstant.java
+++ b/src/proguard/classfile/constant/DoubleConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/FieldrefConstant.java b/src/proguard/classfile/constant/FieldrefConstant.java
index d4afce5..ddd6fb1 100644
--- a/src/proguard/classfile/constant/FieldrefConstant.java
+++ b/src/proguard/classfile/constant/FieldrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/FloatConstant.java b/src/proguard/classfile/constant/FloatConstant.java
index 578f567..e98aec2 100644
--- a/src/proguard/classfile/constant/FloatConstant.java
+++ b/src/proguard/classfile/constant/FloatConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/IntegerConstant.java b/src/proguard/classfile/constant/IntegerConstant.java
index 8a476c6..bd6afa0 100644
--- a/src/proguard/classfile/constant/IntegerConstant.java
+++ b/src/proguard/classfile/constant/IntegerConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
index ddee42f..80fe817 100644
--- a/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
+++ b/src/proguard/classfile/constant/InterfaceMethodrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/InvokeDynamicConstant.java b/src/proguard/classfile/constant/InvokeDynamicConstant.java
new file mode 100755
index 0000000..bbff88d
--- /dev/null
+++ b/src/proguard/classfile/constant/InvokeDynamicConstant.java
@@ -0,0 +1,148 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This Constant represents an invoke dynamic constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class InvokeDynamicConstant extends Constant
+{
+ public int u2bootstrapMethodAttributeIndex;
+ public int u2nameAndTypeIndex;
+
+ /**
+ * An extra field pointing to the Clazz objects referenced in the
+ * descriptor string. This field is filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer ClassReferenceInitializer}</code>.
+ * References to primitive types are ignored.
+ */
+ public Clazz[] referencedClasses;
+
+
+ /**
+ * Creates an uninitialized InvokeDynamicConstant.
+ */
+ public InvokeDynamicConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new InvokeDynamicConstant with the given bootstrap method
+ * and name-and-type indices.
+ * @param u2bootstrapMethodAttributeIndex the index of the bootstrap method
+ * entry in the bootstrap methods
+ * attribute.
+ * @param u2nameAndTypeIndex the index of the name and type
+ * entry in the constant pool.
+ * @param referencedClasses the classes referenced by the
+ * type.
+ */
+ public InvokeDynamicConstant(int u2bootstrapMethodAttributeIndex,
+ int u2nameAndTypeIndex,
+ Clazz[] referencedClasses)
+ {
+ this.u2bootstrapMethodAttributeIndex = u2bootstrapMethodAttributeIndex;
+ this.u2nameAndTypeIndex = u2nameAndTypeIndex;
+ this.referencedClasses = referencedClasses;
+ }
+
+
+ /**
+ * Returns the index of the bootstrap method in the bootstrap methods
+ * attribute of the class.
+ */
+ public int getBootstrapMethodAttributeIndex()
+ {
+ return u2bootstrapMethodAttributeIndex;
+ }
+
+ /**
+ * Returns the name-and-type index.
+ */
+ public int getNameAndTypeIndex()
+ {
+ return u2nameAndTypeIndex;
+ }
+
+ /**
+ * Returns the method name.
+ */
+ public String getName(Clazz clazz)
+ {
+ return clazz.getName(u2nameAndTypeIndex);
+ }
+
+ /**
+ * Returns the method type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getType(u2nameAndTypeIndex);
+ }
+
+
+ /**
+ * Lets the Clazz objects referenced in the descriptor string
+ * accept the given visitor.
+ */
+ public void referencedClassesAccept(ClassVisitor classVisitor)
+ {
+ if (referencedClasses != null)
+ {
+ for (int index = 0; index < referencedClasses.length; index++)
+ {
+ if (referencedClasses[index] != null)
+ {
+ referencedClasses[index].accept(classVisitor);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Lets the bootstrap method handle constant accept the given visitor.
+ */
+ public void bootstrapMethodHandleAccept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ new BootstrapMethodHandleTraveler(constantVisitor).visitInvokeDynamicConstant(clazz, this);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_InvokeDynamic;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitInvokeDynamicConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/LongConstant.java b/src/proguard/classfile/constant/LongConstant.java
index ea66e07..2d55e6a 100644
--- a/src/proguard/classfile/constant/LongConstant.java
+++ b/src/proguard/classfile/constant/LongConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/MethodHandleConstant.java b/src/proguard/classfile/constant/MethodHandleConstant.java
new file mode 100755
index 0000000..c2e068e
--- /dev/null
+++ b/src/proguard/classfile/constant/MethodHandleConstant.java
@@ -0,0 +1,124 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Constant represents a method handle constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodHandleConstant extends Constant
+{
+ public int u1referenceKind;
+ public int u2referenceIndex;
+
+
+ /**
+ * An extra field pointing to the java.lang.invoke.MethodHandle Clazz object.
+ * This field is typically filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer
+ * ClassReferenceInitializer}</code>..
+ */
+ public Clazz javaLangInvokeMethodHandleClass;
+
+
+ /**
+ * Creates an uninitialized MethodHandleConstant.
+ */
+ public MethodHandleConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new MethodHandleConstant with the given type and method ref
+ * index.
+ * @param u1referenceKind the reference kind.
+ * @param u2referenceIndex the index of the field ref constant, interface
+ * method ref constant, or method ref constant in
+ * the constant pool.
+ */
+ public MethodHandleConstant(int u1referenceKind, int u2referenceIndex)
+ {
+ this.u1referenceKind = u1referenceKind;
+ this.u2referenceIndex = u2referenceIndex;
+ }
+
+
+ /**
+ * Returns the kind of reference to which this constant is pointing.
+ * @return One of
+ * {@link ClassConstants#REF_getField },
+ * {@link ClassConstants#REF_getStatic },
+ * {@link ClassConstants#REF_putField },
+ * {@link ClassConstants#REF_putStatic },
+ * {@link ClassConstants#REF_invokeVirtual },
+ * {@link ClassConstants#REF_invokeStatic },
+ * {@link ClassConstants#REF_invokeSpecial },
+ * {@link ClassConstants#REF_newInvokeSpecial}, or
+ * {@link ClassConstants#REF_invokeInterface }.
+ */
+ public int getReferenceKind()
+ {
+ return u1referenceKind;
+ }
+
+ /**
+ * Returns the field ref, interface method ref, or method ref index.
+ */
+ public int getReferenceIndex()
+ {
+ return u2referenceIndex;
+ }
+
+
+ /**
+ * Returns the method/field name.
+ */
+ public String getName(Clazz clazz)
+ {
+ return clazz.getRefName(u2referenceIndex);
+ }
+
+ /**
+ * Returns the type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getRefType(u2referenceIndex);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_MethodHandle;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitMethodHandleConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/MethodTypeConstant.java b/src/proguard/classfile/constant/MethodTypeConstant.java
new file mode 100644
index 0000000..29f79d7
--- /dev/null
+++ b/src/proguard/classfile/constant/MethodTypeConstant.java
@@ -0,0 +1,93 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+
+/**
+ * This Constant represents a method handle constant in the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodTypeConstant extends Constant
+{
+ public int u2descriptorIndex;
+
+
+ /**
+ * An extra field pointing to the java.lang.invoke.MethodType Clazz object.
+ * This field is typically filled out by the <code>{@link
+ * proguard.classfile.util.ClassReferenceInitializer
+ * ClassReferenceInitializer}</code>..
+ */
+ public Clazz javaLangInvokeMethodTypeClass;
+
+
+ /**
+ * Creates an uninitialized MethodTypeConstant.
+ */
+ public MethodTypeConstant()
+ {
+ }
+
+
+ /**
+ * Creates a new MethodTypeConstant with the given descriptor index.
+ * @param u2descriptorIndex the index of the descriptor in the constant
+ * pool.
+ */
+ public MethodTypeConstant(int u2descriptorIndex)
+ {
+ this.u2descriptorIndex = u2descriptorIndex;
+ }
+
+
+ /**
+ * Returns the descriptor index.
+ */
+ public int getDescriptorIndex()
+ {
+ return u2descriptorIndex;
+ }
+
+
+ /**
+ * Returns the type.
+ */
+ public String getType(Clazz clazz)
+ {
+ return clazz.getString(u2descriptorIndex);
+ }
+
+
+ // Implementations for Constant.
+
+ public int getTag()
+ {
+ return ClassConstants.CONSTANT_MethodType;
+ }
+
+ public void accept(Clazz clazz, ConstantVisitor constantVisitor)
+ {
+ constantVisitor.visitMethodTypeConstant(clazz, this);
+ }
+}
diff --git a/src/proguard/classfile/constant/MethodrefConstant.java b/src/proguard/classfile/constant/MethodrefConstant.java
index 858eec9..a69c04e 100644
--- a/src/proguard/classfile/constant/MethodrefConstant.java
+++ b/src/proguard/classfile/constant/MethodrefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/NameAndTypeConstant.java b/src/proguard/classfile/constant/NameAndTypeConstant.java
index e83d2f1..f8f814a 100644
--- a/src/proguard/classfile/constant/NameAndTypeConstant.java
+++ b/src/proguard/classfile/constant/NameAndTypeConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/RefConstant.java b/src/proguard/classfile/constant/RefConstant.java
index 4e4d019..c0531f6 100644
--- a/src/proguard/classfile/constant/RefConstant.java
+++ b/src/proguard/classfile/constant/RefConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/StringConstant.java b/src/proguard/classfile/constant/StringConstant.java
index 9a8d453..923c6dd 100644
--- a/src/proguard/classfile/constant/StringConstant.java
+++ b/src/proguard/classfile/constant/StringConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/Utf8Constant.java b/src/proguard/classfile/constant/Utf8Constant.java
index ae419c9..27ef218 100644
--- a/src/proguard/classfile/constant/Utf8Constant.java
+++ b/src/proguard/classfile/constant/Utf8Constant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
index d2d3c2c..2b89657 100644
--- a/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
+++ b/src/proguard/classfile/constant/visitor/AllConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java
new file mode 100644
index 0000000..6b02b73
--- /dev/null
+++ b/src/proguard/classfile/constant/visitor/BootstrapMethodHandleTraveler.java
@@ -0,0 +1,100 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+import proguard.optimize.info.MethodOptimizationInfo;
+
+/**
+ * This ConstantVisitor and BootstrapMethodInfoVisitor travels from any invoke
+ * dynamic constants or bootstrap method info entries that it visits to their
+ * bootstrap method handle constants, and applies a given constant visitor.
+ *
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodHandleTraveler
+extends SimplifiedVisitor
+implements ConstantVisitor,
+ AttributeVisitor,
+ BootstrapMethodInfoVisitor
+{
+ private ConstantVisitor bootstrapMethodHandleVisitor;
+
+ // Field serving as a method argument.
+ int bootstrapMethodAttributeIndex;
+
+
+ /**
+ * Creates a new BootstrapMethodHandleVisitor that will delegate to the
+ * given constant visitor.
+ */
+ public BootstrapMethodHandleTraveler(ConstantVisitor bootstrapMethodHandleVisitor)
+ {
+ this.bootstrapMethodHandleVisitor = bootstrapMethodHandleVisitor;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Pass the method index.
+ bootstrapMethodAttributeIndex =
+ invokeDynamicConstant.u2bootstrapMethodAttributeIndex;
+
+ // Delegate to the bootstrap method.
+ clazz.attributesAccept(this);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Check bootstrap methods.
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ bootstrapMethodAttributeIndex,
+ this);
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Check bootstrap method.
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex,
+ bootstrapMethodHandleVisitor);
+ }
+}
diff --git a/src/proguard/classfile/constant/visitor/ConstantTagFilter.java b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java
new file mode 100644
index 0000000..bfa7149
--- /dev/null
+++ b/src/proguard/classfile/constant/visitor/ConstantTagFilter.java
@@ -0,0 +1,86 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant.visitor;
+
+import proguard.classfile.Clazz;
+import proguard.classfile.constant.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This <code>ConstantVisitor</code> delegates its visits to one or more
+ * specified types of constants.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantTagFilter
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ private final int constantTagMask;
+ private final ConstantVisitor constantVisitor;
+
+
+ /**
+ * Creates a new ConstantTagFilter.
+ * @param constantTag the type of constants for which visits will be
+ * delegated.
+ * @param constantVisitor the <code>ConstantVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ConstantTagFilter(int constantTag,
+ ConstantVisitor constantVisitor)
+ {
+ this.constantTagMask = 1 << constantTag;
+ this.constantVisitor = constantVisitor;
+ }
+
+
+ /**
+ * Creates a new ConstantTagFilter.
+ * @param constantTags the types of constants for which visits will be
+ * delegated.
+ * @param constantVisitor the <code>ConstantVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ConstantTagFilter(int[] constantTags,
+ ConstantVisitor constantVisitor)
+ {
+ int constantTagMask = 0;
+ for (int index = 0; index < constantTags.length; index++)
+ {
+ constantTagMask |= 1 << constantTags[index];
+ }
+
+ this.constantTagMask = constantTagMask;
+ this.constantVisitor = constantVisitor;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ if (((1 << constant.getTag()) & constantTagMask) != 0)
+ {
+ constant.accept(clazz, constantVisitor);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/classfile/constant/visitor/ConstantVisitor.java b/src/proguard/classfile/constant/visitor/ConstantVisitor.java
index 6cae352..2cec804 100644
--- a/src/proguard/classfile/constant/visitor/ConstantVisitor.java
+++ b/src/proguard/classfile/constant/visitor/ConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -38,9 +38,12 @@
public void visitDoubleConstant( Clazz clazz, DoubleConstant doubleConstant);
public void visitStringConstant( Clazz clazz, StringConstant stringConstant);
public void visitUtf8Constant( Clazz clazz, Utf8Constant utf8Constant);
+ public void visitInvokeDynamicConstant( Clazz clazz, InvokeDynamicConstant invokeDynamicConstant);
+ public void visitMethodHandleConstant( Clazz clazz, MethodHandleConstant methodHandleConstant);
public void visitFieldrefConstant( Clazz clazz, FieldrefConstant fieldrefConstant);
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant);
public void visitMethodrefConstant( Clazz clazz, MethodrefConstant methodrefConstant);
public void visitClassConstant( Clazz clazz, ClassConstant classConstant);
+ public void visitMethodTypeConstant( Clazz clazz, MethodTypeConstant methodTypeConstant);
public void visitNameAndTypeConstant( Clazz clazz, NameAndTypeConstant nameAndTypeConstant);
}
diff --git a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
index fbb3e52..0477631 100644
--- a/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
+++ b/src/proguard/classfile/constant/visitor/ExceptClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -44,16 +44,16 @@
/**
- * Creates a new ClassNameFilter.
+ * Creates a new ExceptClassConstantFilter.
* @param exceptClassName the name of the class that will not be visited.
* @param constantVisitor the <code>ConstantVisitor</code> to which visits
* will be delegated.
*/
- public ExceptClassConstantFilter(String exceptClassName,
- ConstantVisitor constantVisitor)
+ public ExceptClassConstantFilter(String exceptClassName,
+ ConstantVisitor constantVisitor)
{
- this.exceptClassName = exceptClassName;
- this.constantVisitor = constantVisitor;
+ this.exceptClassName = exceptClassName;
+ this.constantVisitor = constantVisitor;
}
diff --git a/src/proguard/classfile/constant/visitor/MethodrefTraveler.java b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java
new file mode 100644
index 0000000..49c0917
--- /dev/null
+++ b/src/proguard/classfile/constant/visitor/MethodrefTraveler.java
@@ -0,0 +1,60 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.constant.visitor;
+
+import proguard.classfile.Clazz;
+import proguard.classfile.attribute.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.util.SimplifiedVisitor;
+
+/**
+ * This ConstantVisitor travels from any method handle constants that it visits
+ * to their methodref constants, and applies a given constant visitor.
+ *
+ * @author Eric Lafortune
+ */
+public class MethodrefTraveler
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ private ConstantVisitor methodrefConstantVisitor;
+
+
+ /**
+ * Creates a new v that will delegate to the given constant visitor.
+ */
+ public MethodrefTraveler(ConstantVisitor methodrefConstantVisitor)
+ {
+ this.methodrefConstantVisitor = methodrefConstantVisitor;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex,
+ methodrefConstantVisitor);
+ }
+}
diff --git a/src/proguard/classfile/editor/AccessFixer.java b/src/proguard/classfile/editor/AccessFixer.java
index 7d6274e..8ff08f3 100644
--- a/src/proguard/classfile/editor/AccessFixer.java
+++ b/src/proguard/classfile/editor/AccessFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,6 +21,8 @@
package proguard.classfile.editor;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.util.*;
@@ -61,12 +63,26 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Check the bootstrap method.
+ invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the method reference.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
referencingClass = clazz;
// Remember the specified class, since it might be different from
- // the referenced class that acutally contains the class member.
+ // the referenced class that actually contains the class member.
clazz.constantPoolEntryAccept(refConstant.u2classIndex, referencedClassFinder);
// Make sure the access flags of the referenced class member are
@@ -91,8 +107,8 @@
public void visitProgramClass(ProgramClass programClass)
{
- int currentAccessFlags = programClass.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ int currentAccessFlags = programClass.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
// Compute the required access level.
Clazz referencingClass = this.referencingClass;
@@ -117,8 +133,8 @@
public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
{
- int currentAccessFlags = programMember.getAccessFlags();
- int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
+ int currentAccessFlags = programMember.getAccessFlags();
+ int currentAccessLevel = AccessUtil.accessLevel(currentAccessFlags);
// Compute the required access level.
int requiredAccessLevel =
diff --git a/src/proguard/classfile/editor/AnnotationAdder.java b/src/proguard/classfile/editor/AnnotationAdder.java
index 359164a..3c35608 100644
--- a/src/proguard/classfile/editor/AnnotationAdder.java
+++ b/src/proguard/classfile/editor/AnnotationAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
index bf8852c..5537f5e 100644
--- a/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
+++ b/src/proguard/classfile/editor/AnnotationsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/AttributeAdder.java b/src/proguard/classfile/editor/AttributeAdder.java
index 2b610b7..a7f8dc3 100644
--- a/src/proguard/classfile/editor/AttributeAdder.java
+++ b/src/proguard/classfile/editor/AttributeAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -256,7 +256,7 @@
CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();
- codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
+ codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength + 32);
// Add the instructions.
codeAttribute.instructionsAccept(clazz,
diff --git a/src/proguard/classfile/editor/AttributeSorter.java b/src/proguard/classfile/editor/AttributeSorter.java
index d8e3367..dcae85e 100644
--- a/src/proguard/classfile/editor/AttributeSorter.java
+++ b/src/proguard/classfile/editor/AttributeSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/AttributesEditor.java b/src/proguard/classfile/editor/AttributesEditor.java
index 10846cc..91c0080 100644
--- a/src/proguard/classfile/editor/AttributesEditor.java
+++ b/src/proguard/classfile/editor/AttributesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/BridgeMethodFixer.java b/src/proguard/classfile/editor/BridgeMethodFixer.java
new file mode 100644
index 0000000..010c8a2
--- /dev/null
+++ b/src/proguard/classfile/editor/BridgeMethodFixer.java
@@ -0,0 +1,117 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This MemberVisitor fixes all inappropriate bridge access flags of the
+ * program methods that it visits, checking whether the methods to which they
+ * bridge have the same name. Some compilers, like in Eclipse and in later
+ * versions of JDK 1.6, complain if they can't find the method with the same
+ * name.
+ *
+ * @author Eric Lafortune
+ */
+public class BridgeMethodFixer
+extends SimplifiedVisitor
+implements MemberVisitor,
+ AttributeVisitor,
+ InstructionVisitor,
+ ConstantVisitor
+{
+ private static final boolean DEBUG = false;
+
+
+ // Return values for the visitor methods.
+ private String bridgedMethodName;
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if ((programMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
+ {
+ programMethod.attributesAccept(programClass, this);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ // Go over the instructions of the bridge method.
+ codeAttribute.instructionsAccept(clazz, method, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ switch (constantInstruction.opcode)
+ {
+ case InstructionConstants.OP_INVOKEVIRTUAL:
+ case InstructionConstants.OP_INVOKESPECIAL:
+ case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEINTERFACE:
+ // Get the name of the bridged method.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+
+ // Check if the name is different.
+ if (!method.getName(clazz).equals(bridgedMethodName))
+ {
+ if (DEBUG)
+ {
+ System.out.println("BridgeMethodFixer: ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] does not bridge to ["+bridgedMethodName+"]");
+ }
+
+ // Clear the bridge flag.
+ ((ProgramMethod)method).u2accessFlags &= ~ClassConstants.INTERNAL_ACC_BRIDGE;
+ }
+ break;
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ bridgedMethodName = refConstant.getName(clazz);
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/classfile/editor/ClassEditor.java b/src/proguard/classfile/editor/ClassEditor.java
index e503ea3..f51ae45 100644
--- a/src/proguard/classfile/editor/ClassEditor.java
+++ b/src/proguard/classfile/editor/ClassEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ClassElementSorter.java b/src/proguard/classfile/editor/ClassElementSorter.java
index 3256c88..c5eb366 100644
--- a/src/proguard/classfile/editor/ClassElementSorter.java
+++ b/src/proguard/classfile/editor/ClassElementSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ClassMemberSorter.java b/src/proguard/classfile/editor/ClassMemberSorter.java
index f31fcd0..61d69b2 100644
--- a/src/proguard/classfile/editor/ClassMemberSorter.java
+++ b/src/proguard/classfile/editor/ClassMemberSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ClassReferenceFixer.java b/src/proguard/classfile/editor/ClassReferenceFixer.java
index 9857903..808d339 100644
--- a/src/proguard/classfile/editor/ClassReferenceFixer.java
+++ b/src/proguard/classfile/editor/ClassReferenceFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/CodeAttributeComposer.java b/src/proguard/classfile/editor/CodeAttributeComposer.java
index e783203..a645f57 100644
--- a/src/proguard/classfile/editor/CodeAttributeComposer.java
+++ b/src/proguard/classfile/editor/CodeAttributeComposer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,6 +29,8 @@
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor accumulates instructions and exceptions, and then
* copies them into code attributes that it visits.
@@ -49,7 +51,7 @@
//*
private static final boolean DEBUG = false;
/*/
- public static boolean DEBUG = true;
+ public static boolean DEBUG = false;
//*/
@@ -313,7 +315,7 @@
int handlerPC = -exceptionInfo.u2handlerPC;
if (handlerPC > 0)
{
- if (remappableInstructionOffset(handlerPC))
+ if (remappableExceptionHandler(handlerPC))
{
exceptionInfo.u2handlerPC = remapInstructionOffset(handlerPC);
}
@@ -490,7 +492,7 @@
int handlerPC = exceptionInfo.u2handlerPC;
exceptionInfo.u2handlerPC =
!allowExternalExceptionHandlers ||
- remappableInstructionOffset(handlerPC) ?
+ remappableExceptionHandler(handlerPC) ?
remapInstructionOffset(handlerPC) :
-handlerPC;
}
@@ -674,13 +676,21 @@
/**
- * Returns whether the given old instruction offset can be remapped at the
+ * Returns whether the given old exception handler can be remapped in the
+ * current code fragment.
*/
- private boolean remappableInstructionOffset(int oldInstructionOffset)
+ private boolean remappableExceptionHandler(int oldInstructionOffset)
{
- return
- oldInstructionOffset <= codeFragmentLengths[level] &&
- instructionOffsetMap[level][oldInstructionOffset] > INVALID;
+ if (oldInstructionOffset > codeFragmentLengths[level])
+ {
+ return false;
+ }
+
+ int newInstructionOffset =
+ instructionOffsetMap[level][oldInstructionOffset];
+
+ return newInstructionOffset > INVALID &&
+ newInstructionOffset < codeLength;
}
@@ -703,10 +713,7 @@
}
// Clear the unused array entries.
- for (int index = newIndex; index < exceptionInfoCount; index++)
- {
- exceptionInfos[index] = null;
- }
+ Arrays.fill(exceptionInfos, newIndex, exceptionInfoCount, null);
return newIndex;
}
@@ -734,10 +741,7 @@
}
// Clear the unused array entries.
- for (int index = newIndex; index < lineNumberInfoCount; index++)
- {
- lineNumberInfos[index] = null;
- }
+ Arrays.fill(lineNumberInfos, newIndex, lineNumberInfoCount, null);
return newIndex;
}
@@ -764,10 +768,7 @@
}
// Clear the unused array entries.
- for (int index = newIndex; index < localVariableInfoCount; index++)
- {
- localVariableInfos[index] = null;
- }
+ Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null);
return newIndex;
}
@@ -794,10 +795,7 @@
}
// Clear the unused array entries.
- for (int index = newIndex; index < localVariableTypeInfoCount; index++)
- {
- localVariableTypeInfos[index] = null;
- }
+ Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null);
return newIndex;
}
diff --git a/src/proguard/classfile/editor/CodeAttributeEditor.java b/src/proguard/classfile/editor/CodeAttributeEditor.java
index 9658c98..82ed29e 100644
--- a/src/proguard/classfile/editor/CodeAttributeEditor.java
+++ b/src/proguard/classfile/editor/CodeAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,7 +28,8 @@
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.ClassPrinter;
+
+import java.util.Arrays;
/**
* This AttributeVisitor accumulates specified changes to code, and then applies
@@ -105,13 +106,10 @@
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- preInsertions[index] = null;
- replacements[index] = null;
- postInsertions[index] = null;
- deleted[index] = false;
- }
+ Arrays.fill(preInsertions, 0, codeLength, null);
+ Arrays.fill(replacements, 0, codeLength, null);
+ Arrays.fill(postInsertions, 0, codeLength, null);
+ Arrays.fill(deleted, 0, codeLength, false);
}
modified = false;
@@ -328,52 +326,51 @@
{
if (DEBUG)
{
- System.out.println("CodeAttributeEditor: ["+clazz.getName()+"."+method.getName(clazz)+"]");
+ System.out.println("CodeAttributeEditor: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
}
- // Avoid doing any work if nothing is changing anyway.
- if (!modified)
+ // Do we have to update the code?
+ if (modified)
{
- return;
- }
+ // Can we perform a faster simple replacement of instructions?
+ if (canPerformSimpleReplacements(codeAttribute))
+ {
+ if (DEBUG)
+ {
+ System.out.println(" Simple editing");
+ }
- // Check if we can perform a faster simple replacement of instructions.
- if (canPerformSimpleReplacements(codeAttribute))
- {
- // Simply overwrite the instructions.
- performSimpleReplacements(codeAttribute);
+ // Simply overwrite the instructions.
+ performSimpleReplacements(codeAttribute);
+ }
+ else
+ {
+ if (DEBUG)
+ {
+ System.out.println(" Full editing");
+ }
- // Update the maximum stack size and local variable frame size.
- updateFrameSizes(clazz, method, codeAttribute);
- }
- else
- {
- // Move and remap the instructions.
- codeAttribute.u4codeLength =
- updateInstructions(clazz, method, codeAttribute);
+ // Move and remap the instructions.
+ codeAttribute.u4codeLength =
+ updateInstructions(clazz, method, codeAttribute);
- // Remap the exception table.
- codeAttribute.exceptionsAccept(clazz, method, this);
+ // Remap the exception table.
+ codeAttribute.exceptionsAccept(clazz, method, this);
- // Remove exceptions with empty code blocks.
- codeAttribute.u2exceptionTableLength =
- removeEmptyExceptions(codeAttribute.exceptionTable,
- codeAttribute.u2exceptionTableLength);
+ // Remove exceptions with empty code blocks.
+ codeAttribute.u2exceptionTableLength =
+ removeEmptyExceptions(codeAttribute.exceptionTable,
+ codeAttribute.u2exceptionTableLength);
- // Update the maximum stack size and local variable frame size.
- updateFrameSizes(clazz, method, codeAttribute);
-
- // Remap the line number table and the local variable table.
- codeAttribute.attributesAccept(clazz, method, this);
+ // Remap the line number table and the local variable tables.
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
// Make sure instructions are widened if necessary.
instructionWriter.visitCodeAttribute(clazz, method, codeAttribute);
}
- }
-
- private void updateFrameSizes(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
+ // Update the maximum stack size and local variable frame size.
if (updateFrameSizes)
{
stackSizeUpdater.visitCodeAttribute(clazz, method, codeAttribute);
@@ -415,12 +412,6 @@
{
// Remap all local variable table entries.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables with empty code blocks.
- localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength,
- codeAttribute.u2maxLocals);
}
@@ -428,12 +419,6 @@
{
// Remap all local variable table entries.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables with empty code blocks.
- localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength,
- codeAttribute.u2maxLocals);
}
@@ -912,10 +897,12 @@
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
// Remap the code offset and length.
- // TODO: The local variable frame might not be strictly preserved.
- localVariableInfo.u2length = remapBranchOffset(localVariableInfo.u2startPC,
- localVariableInfo.u2length);
- localVariableInfo.u2startPC = remapInstructionOffset(localVariableInfo.u2startPC);
+ int newStartPC = remapInstructionOffset(localVariableInfo.u2startPC);
+ int newEndPC = remapInstructionOffset(localVariableInfo.u2startPC +
+ localVariableInfo.u2length);
+
+ localVariableInfo.u2length = newEndPC - newStartPC;
+ localVariableInfo.u2startPC = newStartPC;
}
@@ -924,10 +911,12 @@
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
// Remap the code offset and length.
- // TODO: The local variable frame might not be strictly preserved.
- localVariableTypeInfo.u2length = remapBranchOffset(localVariableTypeInfo.u2startPC,
- localVariableTypeInfo.u2length);
- localVariableTypeInfo.u2startPC = remapInstructionOffset(localVariableTypeInfo.u2startPC);
+ int newStartPC = remapInstructionOffset(localVariableTypeInfo.u2startPC);
+ int newEndPC = remapInstructionOffset(localVariableTypeInfo.u2startPC +
+ localVariableTypeInfo.u2length);
+
+ localVariableTypeInfo.u2length = newEndPC - newStartPC;
+ localVariableTypeInfo.u2startPC = newStartPC;
}
@@ -1017,54 +1006,6 @@
}
- /**
- * Returns the given list of local variables, without the ones that have empty
- * code blocks or that exceed the actual number of local variables.
- */
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount,
- int maxLocals)
- {
- // Overwrite all empty local variable entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount; index++)
- {
- LocalVariableInfo localVariableInfo = localVariableInfos[index];
- if (localVariableInfo.u2length > 0 &&
- localVariableInfo.u2index < maxLocals)
- {
- localVariableInfos[newIndex++] = localVariableInfo;
- }
- }
-
- return newIndex;
- }
-
-
- /**
- * Returns the given list of local variable types, without the ones that
- * have empty code blocks or that exceed the actual number of local variables.
- */
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount,
- int maxLocals)
- {
- // Overwrite all empty local variable type entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount; index++)
- {
- LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
- if (localVariableTypeInfo.u2length > 0 &&
- localVariableTypeInfo.u2index < maxLocals)
- {
- localVariableTypeInfos[newIndex++] = localVariableTypeInfo;
- }
- }
-
- return newIndex;
- }
-
-
private class CompositeInstruction
extends Instruction
{
diff --git a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
index 9962ea5..eedc045 100644
--- a/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
+++ b/src/proguard/classfile/editor/CodeAttributeEditorResetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ComparableConstant.java b/src/proguard/classfile/editor/ComparableConstant.java
index bb81221..ba5f3b1 100644
--- a/src/proguard/classfile/editor/ComparableConstant.java
+++ b/src/proguard/classfile/editor/ComparableConstant.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -39,7 +39,7 @@
extends SimplifiedVisitor
implements Comparable, ConstantVisitor
{
- private static final int[] PRIORITIES = new int[13];
+ private static final int[] PRIORITIES = new int[19];
static
{
PRIORITIES[ClassConstants.CONSTANT_Integer] = 0; // Possibly byte index (ldc).
@@ -47,12 +47,15 @@
PRIORITIES[ClassConstants.CONSTANT_String] = 2;
PRIORITIES[ClassConstants.CONSTANT_Class] = 3;
PRIORITIES[ClassConstants.CONSTANT_Long] = 4; // Always wide index (ldc2_w).
- PRIORITIES[ClassConstants.CONSTANT_Double] = 5;
- PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index.
- PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7;
- PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8;
- PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 9;
- PRIORITIES[ClassConstants.CONSTANT_Utf8] = 10;
+ PRIORITIES[ClassConstants.CONSTANT_Double] = 5; // Always wide index (ldc2_w).
+ PRIORITIES[ClassConstants.CONSTANT_Fieldref] = 6; // Always wide index (getfield,...).
+ PRIORITIES[ClassConstants.CONSTANT_Methodref] = 7; // Always wide index (invokespecial,...).
+ PRIORITIES[ClassConstants.CONSTANT_InterfaceMethodref] = 8; // Always wide index (invokeinterface).
+ PRIORITIES[ClassConstants.CONSTANT_InvokeDynamic] = 9; // Always wide index (invokedynamic).
+ PRIORITIES[ClassConstants.CONSTANT_MethodHandle] = 10;
+ PRIORITIES[ClassConstants.CONSTANT_NameAndType] = 11;
+ PRIORITIES[ClassConstants.CONSTANT_MethodType] = 12;
+ PRIORITIES[ClassConstants.CONSTANT_Utf8] = 13;
}
private final Clazz clazz;
@@ -122,26 +125,32 @@
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
- // In JDK 1.4, we can use Integer.compare(a,b).
- result = new Integer(integerConstant.getValue()).compareTo(new Integer(((IntegerConstant)otherConstant).getValue()));
+ int value = integerConstant.getValue();
+ int otherValue = ((IntegerConstant)otherConstant).getValue();
+ result = value < otherValue ? -1 :
+ value == otherValue ? 0 :
+ 1;
}
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
- // In JDK 1.4, we can use Long.compare(a,b).
- result = new Long(longConstant.getValue()).compareTo(new Long(((LongConstant)otherConstant).getValue()));
+ long value = longConstant.getValue();
+ long otherValue = ((LongConstant)otherConstant).getValue();
+ result = value < otherValue ? -1 :
+ value == otherValue ? 0 :
+ 1;
}
public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
- // In JDK 1.4, we can use Float.compare(a,b).
- result = new Float(floatConstant.getValue()).compareTo(new Float(((FloatConstant)otherConstant).getValue()));
+ result = Float.compare(floatConstant.getValue(),
+ ((FloatConstant)otherConstant).getValue());
}
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
- // In JDK 1.4, we can use Double.compare(a,b).
- result = new Double(doubleConstant.getValue()).compareTo(new Double(((DoubleConstant)otherConstant).getValue()));
+ {
+ result = Double.compare(doubleConstant.getValue(),
+ ((DoubleConstant)otherConstant).getValue());
}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
@@ -154,6 +163,38 @@
result = utf8Constant.getString().compareTo(((Utf8Constant)otherConstant).getString());
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ InvokeDynamicConstant otherInvokeDynamicConstant = (InvokeDynamicConstant)otherConstant;
+
+ int index = invokeDynamicConstant.getBootstrapMethodAttributeIndex();
+ int otherIndex = otherInvokeDynamicConstant.getBootstrapMethodAttributeIndex();
+
+ result = index < otherIndex ? -1 :
+ index > otherIndex ? 1 :
+ (invokeDynamicConstant.getName(clazz) + ' ' +
+ invokeDynamicConstant.getType(clazz))
+ .compareTo
+ (otherInvokeDynamicConstant.getName(clazz) + ' ' +
+ otherInvokeDynamicConstant.getType(clazz));
+ }
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ MethodHandleConstant otherMethodHandleConstant = (MethodHandleConstant)otherConstant;
+
+ int kind = methodHandleConstant.getReferenceKind();
+ int otherKind = methodHandleConstant.getReferenceKind();
+
+ result = kind < otherKind ? -1 :
+ kind > otherKind ? 1 :
+ (methodHandleConstant.getName(clazz) + ' ' +
+ methodHandleConstant.getType(clazz))
+ .compareTo
+ (otherMethodHandleConstant.getName(clazz) + ' ' +
+ otherMethodHandleConstant.getType(clazz));
+ }
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
RefConstant otherRefConstant = (RefConstant)otherConstant;
@@ -171,6 +212,14 @@
result = classConstant.getName(clazz).compareTo(((ClassConstant)otherConstant).getName(clazz));
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant MethodTypeConstant)
+ {
+ MethodTypeConstant otherMethodTypeConstant = (MethodTypeConstant)otherConstant;
+ result = MethodTypeConstant.getType(clazz)
+ .compareTo
+ (otherMethodTypeConstant.getType(clazz));
+ }
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
NameAndTypeConstant otherNameAndTypeConstant = (NameAndTypeConstant)otherConstant;
diff --git a/src/proguard/classfile/editor/ConstantAdder.java b/src/proguard/classfile/editor/ConstantAdder.java
index 2b74f5f..14edbce 100644
--- a/src/proguard/classfile/editor/ConstantAdder.java
+++ b/src/proguard/classfile/editor/ConstantAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -23,6 +23,7 @@
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.util.ListUtil;
/**
* This ConstantVisitor adds all constants that it visits to the constant pool
@@ -128,6 +129,43 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // First add the name and type constant.
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+
+ // Copy the referenced classes.
+ Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses;
+ Clazz[] referencedClassesCopy = null;
+ if (referencedClasses != null)
+ {
+ referencedClassesCopy = new Clazz[referencedClasses.length];
+ System.arraycopy(referencedClasses, 0,
+ referencedClassesCopy, 0,
+ referencedClasses.length);
+ }
+
+ // Then add the actual invoke dynamic constant.
+ constantIndex =
+ constantPoolEditor.addInvokeDynamicConstant(invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ constantIndex,
+ referencedClassesCopy);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // First add the field ref, interface method ref, or method ref
+ // constant.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+
+ // Then add the actual method handle constant.
+ constantIndex =
+ constantPoolEditor.addMethodHandleConstant(methodHandleConstant.getReferenceKind(),
+ constantIndex);
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
// First add the referenced class constant, with its own referenced class.
@@ -185,6 +223,13 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ constantIndex =
+ constantPoolEditor.addMethodTypeConstant(methodTypeConstant.getType(clazz));
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
constantIndex =
diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java
index 8663dee..6ba4857 100644
--- a/src/proguard/classfile/editor/ConstantPoolEditor.java
+++ b/src/proguard/classfile/editor/ConstantPoolEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -199,6 +199,93 @@
/**
+ * Finds or creates a InvokeDynamicConstant constant pool entry with the
+ * given bootstrap method constant pool entry index, method name, and
+ * descriptor.
+ * @return the constant pool index of the InvokeDynamicConstant.
+ */
+ public int addInvokeDynamicConstant(int bootstrapMethodIndex,
+ String name,
+ String descriptor,
+ Clazz[] referencedClasses)
+ {
+ return addInvokeDynamicConstant(bootstrapMethodIndex,
+ addNameAndTypeConstant(name, descriptor),
+ referencedClasses);
+ }
+
+
+ /**
+ * Finds or creates a InvokeDynamicConstant constant pool entry with the given
+ * class constant pool entry index and name and type constant pool entry
+ * index.
+ * @return the constant pool index of the InvokeDynamicConstant.
+ */
+ public int addInvokeDynamicConstant(int bootstrapMethodIndex,
+ int nameAndTypeIndex,
+ Clazz[] referencedClasses)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_InvokeDynamic)
+ {
+ InvokeDynamicConstant invokeDynamicConstant = (InvokeDynamicConstant)constant;
+ if (invokeDynamicConstant.u2bootstrapMethodAttributeIndex == bootstrapMethodIndex &&
+ invokeDynamicConstant.u2nameAndTypeIndex == nameAndTypeIndex)
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new InvokeDynamicConstant(bootstrapMethodIndex,
+ nameAndTypeIndex,
+ referencedClasses));
+ }
+
+
+ /**
+ * Finds or creates a MethodHandleConstant constant pool entry of the
+ * specified kind and with the given field ref, interface method ref,
+ * or method ref constant pool entry index.
+ * @return the constant pool index of the MethodHandleConstant.
+ */
+ public int addMethodHandleConstant(int referenceKind,
+ int referenceIndex)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_MethodHandle)
+ {
+ MethodHandleConstant methodHandleConstant = (MethodHandleConstant)constant;
+ if (methodHandleConstant.u1referenceKind == referenceKind &&
+ methodHandleConstant.u2referenceIndex == referenceIndex)
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new MethodHandleConstant(referenceKind,
+ referenceIndex));
+ }
+
+
+ /**
* Finds or creates a FieldrefConstant constant pool entry for the given
* class and field.
* @return the constant pool index of the FieldrefConstant.
@@ -563,6 +650,36 @@
/**
+ * Finds or creates a MethodTypeConstant constant pool entry with the given
+ * type.
+ * @return the constant pool index of the MethodTypeConstant.
+ */
+ public int addMethodTypeConstant(String type)
+ {
+ int constantPoolCount = targetClass.u2constantPoolCount;
+ Constant[] constantPool = targetClass.constantPool;
+
+ // Check if the entry already exists.
+ for (int index = 1; index < constantPoolCount; index++)
+ {
+ Constant constant = constantPool[index];
+
+ if (constant != null &&
+ constant.getTag() == ClassConstants.CONSTANT_MethodType)
+ {
+ MethodTypeConstant methodTypeConstant = (MethodTypeConstant)constant;
+ if (methodTypeConstant.getType(targetClass).equals(type))
+ {
+ return index;
+ }
+ }
+ }
+
+ return addConstant(new MethodTypeConstant(addUtf8Constant(type)));
+ }
+
+
+ /**
* Finds or creates a NameAndTypeConstant constant pool entry with the given
* name and type.
* @return the constant pool index of the NameAndTypeConstant.
diff --git a/src/proguard/classfile/editor/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java
index 7430d3d..7677218 100644
--- a/src/proguard/classfile/editor/ConstantPoolRemapper.java
+++ b/src/proguard/classfile/editor/ConstantPoolRemapper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -47,9 +47,10 @@
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
- InstructionVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
+ InstructionVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LocalVariableInfoVisitor,
@@ -57,7 +58,7 @@
AnnotationVisitor,
ElementValueVisitor
{
- private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
+ private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
private int[] constantIndexMap;
@@ -100,70 +101,27 @@
// Implementations for ConstantVisitor.
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
- {
- classConstant.u2nameIndex =
- remapConstantIndex(classConstant.u2nameIndex);
- }
-
-
- public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
- // Nothing to do.
- }
-
-
- public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
- {
- fieldrefConstant.u2classIndex =
- remapConstantIndex(fieldrefConstant.u2classIndex);
- fieldrefConstant.u2nameAndTypeIndex =
- remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
- }
-
-
- public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
- {
- // Nothing to do.
- }
-
-
public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
{
// Nothing to do.
}
- public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
- {
- interfaceMethodrefConstant.u2classIndex =
- remapConstantIndex(interfaceMethodrefConstant.u2classIndex);
- interfaceMethodrefConstant.u2nameAndTypeIndex =
- remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex);
- }
-
-
public void visitLongConstant(Clazz clazz, LongConstant longConstant)
{
// Nothing to do.
}
- public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
{
- methodrefConstant.u2classIndex =
- remapConstantIndex(methodrefConstant.u2classIndex);
- methodrefConstant.u2nameAndTypeIndex =
- remapConstantIndex(methodrefConstant.u2nameAndTypeIndex);
+ // Nothing to do.
}
- public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
+ public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
{
- nameAndTypeConstant.u2nameIndex =
- remapConstantIndex(nameAndTypeConstant.u2nameIndex);
- nameAndTypeConstant.u2descriptorIndex =
- remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
+ // Nothing to do.
}
@@ -180,6 +138,70 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ invokeDynamicConstant.u2nameAndTypeIndex =
+ remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ methodHandleConstant.u2referenceIndex =
+ remapConstantIndex(methodHandleConstant.u2referenceIndex);
+ }
+
+
+ public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
+ {
+ fieldrefConstant.u2classIndex =
+ remapConstantIndex(fieldrefConstant.u2classIndex);
+ fieldrefConstant.u2nameAndTypeIndex =
+ remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
+ {
+ interfaceMethodrefConstant.u2classIndex =
+ remapConstantIndex(interfaceMethodrefConstant.u2classIndex);
+ interfaceMethodrefConstant.u2nameAndTypeIndex =
+ remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ {
+ methodrefConstant.u2classIndex =
+ remapConstantIndex(methodrefConstant.u2classIndex);
+ methodrefConstant.u2nameAndTypeIndex =
+ remapConstantIndex(methodrefConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ classConstant.u2nameIndex =
+ remapConstantIndex(classConstant.u2nameIndex);
+ }
+
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ methodTypeConstant.u2descriptorIndex =
+ remapConstantIndex(methodTypeConstant.u2descriptorIndex);
+ }
+
+
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
+ {
+ nameAndTypeConstant.u2nameIndex =
+ remapConstantIndex(nameAndTypeConstant.u2nameIndex);
+ nameAndTypeConstant.u2descriptorIndex =
+ remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
@@ -230,6 +252,16 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ bootstrapMethodsAttribute.u2attributeNameIndex =
+ remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ // Remap the constant pool references of the bootstrap method entries.
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
sourceFileAttribute.u2attributeNameIndex =
@@ -410,6 +442,19 @@
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ bootstrapMethodInfo.u2methodHandleIndex =
+ remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Remap the constant pool references of the bootstrap methods..
+ remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments,
+ bootstrapMethodInfo.u2methodArgumentCount);
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
diff --git a/src/proguard/classfile/editor/ConstantPoolShrinker.java b/src/proguard/classfile/editor/ConstantPoolShrinker.java
new file mode 100644
index 0000000..8c8e5d6
--- /dev/null
+++ b/src/proguard/classfile/editor/ConstantPoolShrinker.java
@@ -0,0 +1,578 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.annotation.visitor.*;
+import proguard.classfile.attribute.preverification.*;
+import proguard.classfile.attribute.preverification.visitor.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.instruction.*;
+import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+import java.util.Arrays;
+
+/**
+ * This ClassVisitor removes all unused entries from the constant pool.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantPoolShrinker
+extends SimplifiedVisitor
+implements ClassVisitor,
+ MemberVisitor,
+ ConstantVisitor,
+ AttributeVisitor,
+ BootstrapMethodInfoVisitor,
+ InnerClassesInfoVisitor,
+ ExceptionInfoVisitor,
+ StackMapFrameVisitor,
+ VerificationTypeVisitor,
+ LocalVariableInfoVisitor,
+ LocalVariableTypeInfoVisitor,
+ AnnotationVisitor,
+ ElementValueVisitor,
+ InstructionVisitor
+{
+ // A visitor info flag to indicate the constant is being used.
+ private static final Object USED = new Object();
+
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Mark this class's name.
+ markConstant(programClass, programClass.u2thisClass);
+
+ // Mark the superclass class constant.
+ programClass.superClassConstantAccept(this);
+
+ // Mark the interface class constants.
+ programClass.interfaceConstantsAccept(this);
+
+ // Mark the constants referenced by the class members.
+ programClass.fieldsAccept(this);
+ programClass.methodsAccept(this);
+
+ // Mark the attributes.
+ programClass.attributesAccept(this);
+
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
+
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMember(ProgramClass programClass, ProgramMember programMember)
+ {
+ // Mark the name and descriptor.
+ markConstant(programClass, programMember.u2nameIndex);
+ markConstant(programClass, programMember.u2descriptorIndex);
+
+ // Mark the attributes.
+ programMember.attributesAccept(programClass, this);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant)
+ {
+ markAsUsed(constant);
+ }
+
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ markAsUsed(stringConstant);
+
+ markConstant(clazz, stringConstant.u2stringIndex);
+ }
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ markAsUsed(invokeDynamicConstant);
+
+ markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+
+ // Mark the bootstrap methods attribute.
+ clazz.attributesAccept(this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ markAsUsed(methodHandleConstant);
+
+ markConstant(clazz, methodHandleConstant.u2referenceIndex);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ markAsUsed(refConstant);
+
+ markConstant(clazz, refConstant.u2classIndex);
+ markConstant(clazz, refConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ markAsUsed(classConstant);
+
+ markConstant(clazz, classConstant.u2nameIndex);
+ }
+
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ markAsUsed(methodTypeConstant);
+
+ markConstant(clazz, methodTypeConstant.u2descriptorIndex);
+ }
+
+
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
+ {
+ markAsUsed(nameAndTypeConstant);
+
+ markConstant(clazz, nameAndTypeConstant.u2nameIndex);
+ markConstant(clazz, nameAndTypeConstant.u2descriptorIndex);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute)
+ {
+ markConstant(clazz, attribute.u2attributeNameIndex);
+ }
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ // Mark the bootstrap method entries.
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
+ public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
+ {
+ markConstant(clazz, sourceFileAttribute.u2attributeNameIndex);
+ markConstant(clazz, sourceFileAttribute.u2sourceFileIndex);
+ }
+
+
+ public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
+ {
+ markConstant(clazz, sourceDirAttribute.u2attributeNameIndex);
+ markConstant(clazz, sourceDirAttribute.u2sourceDirIndex);
+ }
+
+
+ public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
+ {
+ markConstant(clazz, innerClassesAttribute.u2attributeNameIndex);
+
+ // Mark the outer class entries.
+ innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ }
+
+
+ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
+ {
+ markConstant(clazz, enclosingMethodAttribute.u2attributeNameIndex);
+ markConstant(clazz, enclosingMethodAttribute.u2classIndex);
+
+ if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
+ {
+ markConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex);
+ }
+ }
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ markConstant(clazz, signatureAttribute.u2attributeNameIndex);
+ markConstant(clazz, signatureAttribute.u2signatureIndex);
+ }
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ markConstant(clazz, constantValueAttribute.u2attributeNameIndex);
+ markConstant(clazz, constantValueAttribute.u2constantValueIndex);
+ }
+
+
+ public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
+ {
+ markConstant(clazz, exceptionsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the exceptions.
+ exceptionsAttribute.exceptionEntriesAccept((ProgramClass)clazz, this);
+ }
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ markConstant(clazz, codeAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the instructions,
+ // by the exceptions, and by the attributes.
+ codeAttribute.instructionsAccept(clazz, method, this);
+ codeAttribute.exceptionsAccept(clazz, method, this);
+ codeAttribute.attributesAccept(clazz, method, this);
+ }
+
+
+ public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
+ {
+ markConstant(clazz, stackMapAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the stack map frames.
+ stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
+ {
+ markConstant(clazz, stackMapTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the stack map frames.
+ stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ markConstant(clazz, localVariableTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the local variables.
+ localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ markConstant(clazz, localVariableTypeTableAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the local variable types.
+ localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
+ {
+ markConstant(clazz, annotationsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the annotations.
+ annotationsAttribute.annotationsAccept(clazz, this);
+ }
+
+
+ public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
+ {
+ markConstant(clazz, parameterAnnotationsAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the annotations.
+ parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
+ }
+
+
+ public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
+ {
+ markConstant(clazz, annotationDefaultAttribute.u2attributeNameIndex);
+
+ // Mark the constant pool entries referenced by the element value.
+ annotationDefaultAttribute.defaultValueAccept(clazz, this);
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Mark the constant pool entries referenced by the arguments.
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, this);
+ }
+
+
+ // Implementations for InnerClassesInfoVisitor.
+
+ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+ {
+ innerClassesInfo.innerClassConstantAccept(clazz, this);
+ innerClassesInfo.outerClassConstantAccept(clazz, this);
+ innerClassesInfo.innerNameConstantAccept(clazz, this);
+ }
+
+
+ // Implementations for ExceptionInfoVisitor.
+
+ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
+ {
+ if (exceptionInfo.u2catchType != 0)
+ {
+ markConstant(clazz, exceptionInfo.u2catchType);
+ }
+ }
+
+
+ // Implementations for StackMapFrameVisitor.
+
+ public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}
+
+
+ public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
+ {
+ // Mark the constant pool entries referenced by the verification types.
+ fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
+ fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
+ }
+
+
+ // Implementations for VerificationTypeVisitor.
+
+ public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}
+
+
+ public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
+ {
+ markConstant(clazz, objectType.u2classIndex);
+ }
+
+
+ // Implementations for LocalVariableInfoVisitor.
+
+ public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
+ {
+ markConstant(clazz, localVariableInfo.u2nameIndex);
+ markConstant(clazz, localVariableInfo.u2descriptorIndex);
+ }
+
+
+ // Implementations for LocalVariableTypeInfoVisitor.
+
+ public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
+ {
+ markConstant(clazz, localVariableTypeInfo.u2nameIndex);
+ markConstant(clazz, localVariableTypeInfo.u2signatureIndex);
+ }
+
+
+ // Implementations for AnnotationVisitor.
+
+ public void visitAnnotation(Clazz clazz, Annotation annotation)
+ {
+ markConstant(clazz, annotation.u2typeIndex);
+
+ // Mark the constant pool entries referenced by the element values.
+ annotation.elementValuesAccept(clazz, this);
+ }
+
+
+ // Implementations for ElementValueVisitor.
+
+ public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
+ {
+ if (constantElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, constantElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, constantElementValue.u2constantValueIndex);
+ }
+
+
+ public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
+ {
+ if (enumConstantElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
+ markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
+ }
+
+
+ public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
+ {
+ if (classElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, classElementValue.u2elementNameIndex);
+ }
+
+ markConstant(clazz, classElementValue.u2classInfoIndex);
+ }
+
+
+ public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
+ {
+ if (annotationElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, annotationElementValue.u2elementNameIndex);
+ }
+
+ // Mark the constant pool entries referenced by the annotation.
+ annotationElementValue.annotationAccept(clazz, this);
+ }
+
+
+ public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
+ {
+ if (arrayElementValue.u2elementNameIndex != 0)
+ {
+ markConstant(clazz, arrayElementValue.u2elementNameIndex);
+ }
+
+ // Mark the constant pool entries referenced by the element values.
+ arrayElementValue.elementValuesAccept(clazz, annotation, this);
+ }
+
+
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
+ {
+ markConstant(clazz, constantInstruction.constantIndex);
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given constant pool entry of the given class. This includes
+ * visiting any referenced objects.
+ */
+ private void markConstant(Clazz clazz, int index)
+ {
+ clazz.constantPoolEntryAccept(index, this);
+ }
+
+
+ /**
+ * Marks the given visitor accepter as being used.
+ */
+ private void markAsUsed(Constant constant)
+ {
+ constant.setVisitorInfo(USED);
+ }
+
+
+ /**
+ * Returns whether the given visitor accepter has been marked as being used.
+ */
+ private boolean isUsed(VisitorAccepter visitorAccepter)
+ {
+ return visitorAccepter.getVisitorInfo() == USED;
+ }
+
+
+ /**
+ * Removes all constants that are not marked as being used from the given
+ * constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
+}
diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java
index faae318..8e18865 100644
--- a/src/proguard/classfile/editor/ConstantPoolSorter.java
+++ b/src/proguard/classfile/editor/ConstantPoolSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -112,10 +112,7 @@
System.arraycopy(newConstantPool, 0, programClass.constantPool, 0, newLength);
// Clear any remaining entries.
- for (int index = newLength; index < constantPoolCount; index++)
- {
- programClass.constantPool[index] = null;
- }
+ Arrays.fill(programClass.constantPool, newLength, constantPoolCount, null);
programClass.u2constantPoolCount = newLength;
diff --git a/src/proguard/classfile/editor/ElementValueAdder.java b/src/proguard/classfile/editor/ElementValueAdder.java
index 8cbd11d..895fd68 100644
--- a/src/proguard/classfile/editor/ElementValueAdder.java
+++ b/src/proguard/classfile/editor/ElementValueAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ElementValuesEditor.java b/src/proguard/classfile/editor/ElementValuesEditor.java
index bfc4e9f..ce9352a 100644
--- a/src/proguard/classfile/editor/ElementValuesEditor.java
+++ b/src/proguard/classfile/editor/ElementValuesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ExceptionAdder.java b/src/proguard/classfile/editor/ExceptionAdder.java
index 1ccb1a6..ee0fb52 100644
--- a/src/proguard/classfile/editor/ExceptionAdder.java
+++ b/src/proguard/classfile/editor/ExceptionAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ExceptionInfoAdder.java b/src/proguard/classfile/editor/ExceptionInfoAdder.java
index e0cc9c5..5fd98a8 100644
--- a/src/proguard/classfile/editor/ExceptionInfoAdder.java
+++ b/src/proguard/classfile/editor/ExceptionInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
index 4509a9a..d49658a 100644
--- a/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
+++ b/src/proguard/classfile/editor/ExceptionsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/InnerClassesAccessFixer.java b/src/proguard/classfile/editor/InnerClassesAccessFixer.java
new file mode 100644
index 0000000..1d991df
--- /dev/null
+++ b/src/proguard/classfile/editor/InnerClassesAccessFixer.java
@@ -0,0 +1,83 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.InnerClassesInfoVisitor;
+import proguard.classfile.attribute.InnerClassesInfo;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+/**
+ * This InnerClassesInfoVisitor fixes the inner class access flags of the
+ * inner classes information that it visits.
+ *
+ * @author Eric Lafortune
+ */
+public class InnerClassesAccessFixer
+extends SimplifiedVisitor
+implements InnerClassesInfoVisitor,
+ ConstantVisitor,
+ ClassVisitor
+{
+ private int innerClassAccessFlags;
+
+
+ // Implementations for InnerClassesInfoVisitor.
+
+ public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
+ {
+ // The current access flags are the default.
+ innerClassAccessFlags = innerClassesInfo.u2innerClassAccessFlags;
+
+ // See if we can find new access flags.
+ innerClassesInfo.innerClassConstantAccept(clazz, this);
+
+ // Update the access flags.
+ innerClassesInfo.u2innerClassAccessFlags = innerClassAccessFlags;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ classConstant.referencedClassAccept(this);
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitLibraryClass(LibraryClass libraryClass) {}
+
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ innerClassAccessFlags =
+ AccessUtil.replaceAccessFlags(innerClassAccessFlags,
+ programClass.u2accessFlags);
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/classfile/editor/InstructionAdder.java b/src/proguard/classfile/editor/InstructionAdder.java
index 60fde6d..34fb63b 100644
--- a/src/proguard/classfile/editor/InstructionAdder.java
+++ b/src/proguard/classfile/editor/InstructionAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java
index d842358..b7da62f 100644
--- a/src/proguard/classfile/editor/InstructionWriter.java
+++ b/src/proguard/classfile/editor/InstructionWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/InterfaceAdder.java b/src/proguard/classfile/editor/InterfaceAdder.java
index e095af6..9c11d97 100644
--- a/src/proguard/classfile/editor/InterfaceAdder.java
+++ b/src/proguard/classfile/editor/InterfaceAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/InterfaceSorter.java b/src/proguard/classfile/editor/InterfaceSorter.java
index 6521369..176e13e 100644
--- a/src/proguard/classfile/editor/InterfaceSorter.java
+++ b/src/proguard/classfile/editor/InterfaceSorter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,10 +21,14 @@
package proguard.classfile.editor;
import proguard.classfile.*;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.ClassVisitor;
-import java.util.Arrays;
+import java.util.*;
/**
* This ClassVisitor sorts the interfaces of the program classes that it visits.
@@ -33,7 +37,8 @@
*/
public class InterfaceSorter
extends SimplifiedVisitor
-implements ClassVisitor
+implements ClassVisitor,
+ AttributeVisitor
{
// Implementations for ClassVisitor.
@@ -42,26 +47,106 @@
int[] interfaces = programClass.u2interfaces;
int interfacesCount = programClass.u2interfacesCount;
- // Sort the interfaces.
- Arrays.sort(interfaces, 0, interfacesCount);
-
- // Remove any duplicate entries.
- int newInterfacesCount = 0;
- int previousInterfaceIndex = 0;
- for (int index = 0; index < interfacesCount; index++)
+ if (interfacesCount > 1)
{
- int interfaceIndex = interfaces[index];
+ // Sort the interfaces.
+ Arrays.sort(interfaces, 0, interfacesCount);
- // Isn't this a duplicate of the previous interface?
- if (interfaceIndex != previousInterfaceIndex)
+ // Remove any duplicate entries.
+ int newInterfacesCount = 0;
+ int previousInterfaceIndex = 0;
+ for (int index = 0; index < interfacesCount; index++)
{
- interfaces[newInterfacesCount++] = interfaceIndex;
+ int interfaceIndex = interfaces[index];
- // Remember the interface.
- previousInterfaceIndex = interfaceIndex;
+ // Isn't this a duplicate of the previous interface?
+ if (interfaceIndex != previousInterfaceIndex)
+ {
+ interfaces[newInterfacesCount++] = interfaceIndex;
+
+ // Remember the interface.
+ previousInterfaceIndex = interfaceIndex;
+ }
+ }
+
+ programClass.u2interfacesCount = newInterfacesCount;
+
+ // Update the signature, if any
+ programClass.attributesAccept(this);
+ }
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
+ {
+ // Process the generic definitions, superclass, and implemented
+ // interfaces.
+ String signature = clazz.getString(signatureAttribute.u2signatureIndex);
+
+ // Count the signature types.
+ InternalTypeEnumeration internalTypeEnumeration =
+ new InternalTypeEnumeration(signature);
+
+ int count = 0;
+ int interfacesCount = -1;
+ while (internalTypeEnumeration.hasMoreTypes())
+ {
+ String internalType = internalTypeEnumeration.nextType();
+
+ count++;
+
+ if (ClassUtil.isInternalClassType(internalType))
+ {
+ interfacesCount++;
}
}
- programClass.u2interfacesCount = newInterfacesCount;
+ // Put the signature types in an array.
+ internalTypeEnumeration =
+ new InternalTypeEnumeration(signature);
+
+ String[] internalTypes = new String[count];
+
+ for (int index = 0; index < count; index++)
+ {
+ String internalType = internalTypeEnumeration.nextType();
+
+ internalTypes[index] = internalType;
+ }
+
+ // Sort the interface types in the array.
+ Arrays.sort(internalTypes, count - interfacesCount, count);
+
+ // Recompose the signature types in a string.
+ StringBuffer newSignatureBuffer = new StringBuffer();
+
+ for (int index = 0; index < count; index++)
+ {
+ // Is this not an interface type, or an interface type that isn't
+ // a duplicate of the previous interface type?
+ if (index < count - interfacesCount ||
+ !internalTypes[index].equals(internalTypes[index-1]))
+ {
+ newSignatureBuffer.append(internalTypes[index]);
+ }
+ }
+
+ String newSignature = newSignatureBuffer.toString();
+
+ // Did the signature change?
+ if (!newSignature.equals(signature))
+ {
+ // Update the signature.
+ ((Utf8Constant)((ProgramClass)clazz).constantPool[signatureAttribute.u2signatureIndex]).setString(newSignatureBuffer.toString());
+
+ // Clear the referenced classes.
+ // TODO: Properly update the referenced classes.
+ signatureAttribute.referencedClasses = null;
+ }
}
}
diff --git a/src/proguard/classfile/editor/InterfacesEditor.java b/src/proguard/classfile/editor/InterfacesEditor.java
index d3170e1..59cdd6a 100644
--- a/src/proguard/classfile/editor/InterfacesEditor.java
+++ b/src/proguard/classfile/editor/InterfacesEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LineNumberInfoAdder.java b/src/proguard/classfile/editor/LineNumberInfoAdder.java
index aa8c0c4..b0db7fb 100644
--- a/src/proguard/classfile/editor/LineNumberInfoAdder.java
+++ b/src/proguard/classfile/editor/LineNumberInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
index ab96b38..7497458 100644
--- a/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LineNumberTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LocalVariableInfoAdder.java b/src/proguard/classfile/editor/LocalVariableInfoAdder.java
index f285e4f..0f47933 100644
--- a/src/proguard/classfile/editor/LocalVariableInfoAdder.java
+++ b/src/proguard/classfile/editor/LocalVariableInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
index 053b628..8bb051d 100644
--- a/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LocalVariableTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
index ca50f3f..a1c1379 100644
--- a/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
+++ b/src/proguard/classfile/editor/LocalVariableTypeInfoAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
index fe5a64d..9b1ebd5 100644
--- a/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
+++ b/src/proguard/classfile/editor/LocalVariableTypeTableAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/MemberAdder.java b/src/proguard/classfile/editor/MemberAdder.java
index 5f939bb..7791e3b 100644
--- a/src/proguard/classfile/editor/MemberAdder.java
+++ b/src/proguard/classfile/editor/MemberAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,8 +26,9 @@
import proguard.classfile.visitor.MemberVisitor;
/**
- * This ConstantVisitor adds all class members that it visits to the given
- * target class.
+ * This MemberVisitor copies all class members that it visits to the given
+ * target class. Their visitor info is set to the class members from which they
+ * were copied.
*
* @author Eric Lafortune
*/
@@ -45,8 +46,9 @@
private static final Attribute[] EMPTY_ATTRIBUTES = new Attribute[0];
- private final ProgramClass targetClass;
-// private final boolean addFields;
+ private final ProgramClass targetClass;
+// private final boolean addFields;
+ private final MemberVisitor extraMemberVisitor;
private final ConstantAdder constantAdder;
private final ClassEditor classEditor;
@@ -59,13 +61,30 @@
* @param targetClass the class to which all visited class members will be
* added.
*/
+ public MemberAdder(ProgramClass targetClass)
+ {
+ this(targetClass, null);
+ }
+
+
+ /**
+ * Creates a new MemberAdder that will copy methods into the given target
+ * class.
+ * @param targetClass the class to which all visited class members
+ * will be added.
+ * @param extraMemberVisitor an optional member visitor that visits each
+ * new member right after it has been added. This
+ * allows changing the visitor info, for instance.
+ */
// * @param addFields specifies whether fields should be added, or fused
// * with the present fields.
- public MemberAdder(ProgramClass targetClass)//),
-// boolean addFields)
+ public MemberAdder(ProgramClass targetClass,
+// boolean addFields,
+ MemberVisitor extraMemberVisitor)
{
- this.targetClass = targetClass;
-// this.addFields = addFields;
+ this.targetClass = targetClass;
+// this.addFields = addFields;
+ this.extraMemberVisitor = extraMemberVisitor;
constantAdder = new ConstantAdder(targetClass);
classEditor = new ClassEditor(targetClass);
@@ -150,6 +169,12 @@
// Add the completed field.
classEditor.addField(newProgramField);
+
+ // Visit the newly added field, if necessary.
+ if (extraMemberVisitor != null)
+ {
+ extraMemberVisitor.visitProgramField(targetClass, newProgramField);
+ }
}
@@ -240,6 +265,12 @@
// Add the completed method.
classEditor.addMethod(newProgramMethod);
+
+ // Visit the newly added method, if necessary.
+ if (extraMemberVisitor != null)
+ {
+ extraMemberVisitor.visitProgramMethod(targetClass, newProgramMethod);
+ }
}
diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java
index 4bd8af5..6d665c1 100644
--- a/src/proguard/classfile/editor/MemberReferenceFixer.java
+++ b/src/proguard/classfile/editor/MemberReferenceFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -298,22 +298,17 @@
{
Clazz referencedClass = enclosingMethodAttribute.referencedClass;
- // Does it have a new class?
- if (!enclosingMethodAttribute.getClassName(clazz).equals(referencedClass.getName()))
- {
- // Update the class index.
- enclosingMethodAttribute.u2classIndex =
- new ConstantPoolEditor((ProgramClass)clazz).addClassConstant(referencedClass);
- }
-
// Does it have a new name or type?
- if (!enclosingMethodAttribute.getName(clazz).equals(referencedMember.getName(referencedClass)) ||
- !enclosingMethodAttribute.getType(clazz).equals(referencedMember.getDescriptor(referencedClass)))
+ String newName = referencedMember.getName(referencedClass);
+ String newType = referencedMember.getDescriptor(referencedClass);
+
+ if (!enclosingMethodAttribute.getName(clazz).equals(newName) ||
+ !enclosingMethodAttribute.getType(clazz).equals(newType))
{
// Update the name and type index.
enclosingMethodAttribute.u2nameAndTypeIndex =
- new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(referencedMember.getName(referencedClass),
- referencedMember.getDescriptor(referencedClass));
+ new ConstantPoolEditor((ProgramClass)clazz).addNameAndTypeConstant(newName,
+ newType);
}
}
}
@@ -433,10 +428,9 @@
Member referencedMember)
{
System.out.println("MemberReferenceFixer:");
- System.out.println(" Class file = "+clazz.getName());
- System.out.println(" Ref class = "+referencedClass.getName());
- System.out.println(" Ref member name = "+stringConstant.getString(clazz));
- System.out.println(" -> "+referencedMember.getName(referencedClass));
+ System.out.println(" ["+clazz.getName()+"]: String ["+
+ stringConstant.getString(clazz)+"] -> ["+
+ referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]");
}
@@ -446,11 +440,8 @@
Member referencedMember)
{
System.out.println("MemberReferenceFixer:");
- System.out.println(" Class file = "+clazz.getName());
- System.out.println(" Ref class = "+referencedClass.getName());
- System.out.println(" Ref member name = "+refConstant.getName(clazz));
- System.out.println(" -> "+referencedMember.getName(referencedClass));
- System.out.println(" Ref descriptor = "+refConstant.getType(clazz));
- System.out.println(" -> "+referencedMember.getDescriptor(referencedClass));
+ System.out.println(" ["+clazz.getName()+"]: ["+
+ refConstant.getClassName(clazz)+"."+refConstant.getName(clazz)+" "+refConstant.getType(clazz)+"] -> ["+
+ referencedClass.getName()+"."+referencedMember.getName(referencedClass)+" "+referencedMember.getDescriptor(referencedClass)+"]");
}
}
diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java
index ef76012..f33ef1d 100644
--- a/src/proguard/classfile/editor/MethodInvocationFixer.java
+++ b/src/proguard/classfile/editor/MethodInvocationFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,7 +28,6 @@
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.*;
/**
* This AttributeVisitor fixes all inappropriate special/virtual/static/interface
@@ -40,9 +39,7 @@
extends SimplifiedVisitor
implements AttributeVisitor,
InstructionVisitor,
- ConstantVisitor,
- ClassVisitor,
- MemberVisitor
+ ConstantVisitor
{
private static final boolean DEBUG = false;
@@ -88,7 +85,8 @@
clazz.constantPoolEntryAccept(constantIndex, this);
// Did we find the called class and method?
- if (referencedMethod != null)
+ if (referencedClass != null &&
+ referencedMethod != null)
{
// Do we need to update the opcode?
byte opcode = constantInstruction.opcode;
@@ -168,6 +166,7 @@
// but not a super call)?
if (opcode != InstructionConstants.OP_INVOKEVIRTUAL &&
(opcode != InstructionConstants.OP_INVOKESPECIAL ||
+ clazz.equals(referencedClass) ||
!clazz.extends_(referencedClass)))
{
// Replace the invocation by an invokevirtual instruction.
@@ -194,40 +193,30 @@
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
{
- // Check if this is an interface method. Note that we're interested in
- // the class of the method reference, not in the class in which the
- // method was actually found.
- //refConstant.referencedClassAccept(this);
- clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+ // Remember the referenced class. Note that we're interested in the
+ // class of the method reference, not in the class in which the
+ // method 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
+ {
+ clazz.constantPoolEntryAccept(refConstant.u2classIndex, this);
+ }
- // Get the referenced access flags and names.
- refConstant.referencedMemberAccept(this);
+ // Remember the referenced method.
+ referencedMethodClass = refConstant.referencedClass;
+ referencedMethod = refConstant.referencedMember;
}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
- // Check if this is an interface class.
- classConstant.referencedClassAccept(this);
- }
-
-
- // Implementations for ClassVisitor.
-
- public void visitAnyClass(Clazz clazz)
- {
// Remember the referenced class.
- referencedClass = clazz;
- }
-
-
- // Implementations for MemberVisitor.
-
- public void visitAnyMember(Clazz clazz, Member member)
- {
- // Remember the referenced method.
- referencedMethodClass = clazz;
- referencedMethod = member;
+ referencedClass = classConstant.referencedClass;
}
diff --git a/src/proguard/classfile/editor/NameAndTypeShrinker.java b/src/proguard/classfile/editor/NameAndTypeShrinker.java
new file mode 100644
index 0000000..f316884
--- /dev/null
+++ b/src/proguard/classfile/editor/NameAndTypeShrinker.java
@@ -0,0 +1,188 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.editor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolRemapper;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.ClassVisitor;
+
+import java.util.Arrays;
+
+
+/**
+ * This ClassVisitor removes NameAndType constant pool entries that are not
+ * used.
+ *
+ * @author Eric Lafortune
+ */
+public class NameAndTypeShrinker
+extends SimplifiedVisitor
+implements ClassVisitor,
+ ConstantVisitor,
+ AttributeVisitor
+{
+ // A visitor info flag to indicate the NameAndType constant pool entry is being used.
+ private static final Object USED = new Object();
+
+ private int[] constantIndexMap;
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Mark the NameAndType entries referenced by all other constant pool
+ // entries.
+ programClass.constantPoolEntriesAccept(this);
+
+ // Mark the NameAndType entries referenced by all EnclosingMethod
+ // attributes.
+ programClass.attributesAccept(this);
+
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
+
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitAnyConstant(Clazz clazz, Constant constant) {}
+
+
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ markNameAndTypeConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex);
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
+ {
+ if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
+ {
+ markNameAndTypeConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex);
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Marks the given UTF-8 constant pool entry of the given class.
+ */
+ private void markNameAndTypeConstant(Clazz clazz, int index)
+ {
+ markAsUsed((NameAndTypeConstant)((ProgramClass)clazz).getConstant(index));
+ }
+
+
+ /**
+ * Marks the given VisitorAccepter as being used.
+ * In this context, the VisitorAccepter will be a NameAndTypeConstant object.
+ */
+ private void markAsUsed(VisitorAccepter visitorAccepter)
+ {
+ visitorAccepter.setVisitorInfo(USED);
+ }
+
+
+ /**
+ * Returns whether the given VisitorAccepter has been marked as being used.
+ * In this context, the VisitorAccepter will be a NameAndTypeConstant object.
+ */
+ private boolean isUsed(VisitorAccepter visitorAccepter)
+ {
+ return visitorAccepter.getVisitorInfo() == USED;
+ }
+
+
+ /**
+ * Removes all NameAndType entries that are not marked as being used
+ * from the given constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap == null ||
+ constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
+ isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
+}
diff --git a/src/proguard/classfile/editor/NamedAttributeDeleter.java b/src/proguard/classfile/editor/NamedAttributeDeleter.java
index 0c4d339..5ae950d 100644
--- a/src/proguard/classfile/editor/NamedAttributeDeleter.java
+++ b/src/proguard/classfile/editor/NamedAttributeDeleter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
index 4cad6b8..c97e2c8 100644
--- a/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
+++ b/src/proguard/classfile/editor/ParameterAnnotationsAttributeEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java
index 94e0519..cc743b1 100644
--- a/src/proguard/classfile/editor/StackSizeUpdater.java
+++ b/src/proguard/classfile/editor/StackSizeUpdater.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/SubclassAdder.java b/src/proguard/classfile/editor/SubclassAdder.java
index 6b9fd64..f944ef8 100644
--- a/src/proguard/classfile/editor/SubclassAdder.java
+++ b/src/proguard/classfile/editor/SubclassAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/editor/SubclassToAdder.java b/src/proguard/classfile/editor/SubclassToAdder.java
index deb242f..f4cdd70 100644
--- a/src/proguard/classfile/editor/SubclassToAdder.java
+++ b/src/proguard/classfile/editor/SubclassToAdder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/Utf8UsageMarker.java b/src/proguard/classfile/editor/Utf8Shrinker.java
similarity index 83%
rename from src/proguard/obfuscate/Utf8UsageMarker.java
rename to src/proguard/classfile/editor/Utf8Shrinker.java
index c59ebb8..b9dac44 100644
--- a/src/proguard/obfuscate/Utf8UsageMarker.java
+++ b/src/proguard/classfile/editor/Utf8Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -18,7 +18,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-package proguard.obfuscate;
+package proguard.classfile.editor;
import proguard.classfile.*;
import proguard.classfile.attribute.*;
@@ -28,18 +28,19 @@
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolRemapper;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
+
/**
- * This ClassVisitor marks all UTF-8 constant pool entries that are
- * being used in the program classes it visits.
- *
- * @see Utf8Shrinker
+ * This ClassVisitor removes UTF-8 constant pool entries that are not used.
*
* @author Eric Lafortune
*/
-public class Utf8UsageMarker
+public class Utf8Shrinker
extends SimplifiedVisitor
implements ClassVisitor,
MemberVisitor,
@@ -54,6 +55,9 @@
// A visitor info flag to indicate the UTF-8 constant pool entry is being used.
private static final Object USED = new Object();
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
+ private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
+
// Implementations for ClassVisitor.
@@ -68,6 +72,22 @@
// Mark the UTF-8 entries referenced by the attributes.
programClass.attributesAccept(this);
+
+ // Shift the used constant pool entries together, filling out the
+ // index map.
+ int newConstantPoolCount =
+ shrinkConstantPool(programClass.constantPool,
+ programClass.u2constantPoolCount);
+
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
}
@@ -375,7 +395,7 @@
* Marks the given VisitorAccepter as being used.
* In this context, the VisitorAccepter will be a Utf8Constant object.
*/
- private static void markAsUsed(VisitorAccepter visitorAccepter)
+ private void markAsUsed(VisitorAccepter visitorAccepter)
{
visitorAccepter.setVisitorInfo(USED);
}
@@ -385,8 +405,51 @@
* Returns whether the given VisitorAccepter has been marked as being used.
* In this context, the VisitorAccepter will be a Utf8Constant object.
*/
- static boolean isUsed(VisitorAccepter visitorAccepter)
+ private boolean isUsed(VisitorAccepter visitorAccepter)
{
return visitorAccepter.getVisitorInfo() == USED;
}
+
+
+ /**
+ * Removes all UTF-8 entries that are not marked as being used
+ * from the given constant pool.
+ * @return the new number of entries.
+ */
+ private int shrinkConstantPool(Constant[] constantPool, int length)
+ {
+ // Create a new index map, if necessary.
+ if (constantIndexMap.length < length)
+ {
+ constantIndexMap = new int[length];
+ }
+
+ int counter = 1;
+ boolean isUsed = false;
+
+ // Shift the used constant pool entries together.
+ for (int index = 1; index < length; index++)
+ {
+ constantIndexMap[index] = counter;
+
+ Constant constant = constantPool[index];
+
+ // Don't update the flag if this is the second half of a long entry.
+ if (constant != null)
+ {
+ isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 ||
+ isUsed(constant);
+ }
+
+ if (isUsed)
+ {
+ constantPool[counter++] = constant;
+ }
+ }
+
+ // Clear the remaining constant pool elements.
+ Arrays.fill(constantPool, counter, length, null);
+
+ return counter;
+ }
}
diff --git a/src/proguard/classfile/editor/VariableCleaner.java b/src/proguard/classfile/editor/VariableCleaner.java
index 1e93c15..af51403 100644
--- a/src/proguard/classfile/editor/VariableCleaner.java
+++ b/src/proguard/classfile/editor/VariableCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,15 +22,15 @@
import proguard.classfile.*;
import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.instruction.*;
-import proguard.classfile.instruction.visitor.InstructionVisitor;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.optimize.info.VariableUsageMarker;
+
+import java.util.Arrays;
/**
- * This AttributeVisitor cleans up unused variables in all attributes that it
- * visits.
+ * This AttributeVisitor cleans up variable tables in all code attributes that
+ * it visits. It trims overlapping local variables. It removes empty local
+ * variables and empty local variable tables.
*
* @author Eric Lafortune
*/
@@ -38,7 +38,8 @@
extends SimplifiedVisitor
implements AttributeVisitor
{
- private final VariableUsageMarker variableUsageMarker = new VariableUsageMarker();
+ private boolean deleteLocalVariableTableAttribute;
+ private boolean deleteLocalVariableTypeTableAttribute;
// Implementations for AttributeVisitor.
@@ -48,11 +49,35 @@
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
- // Figure out the local variables that are used by the code.
- variableUsageMarker.visitCodeAttribute(clazz, method, codeAttribute);
+ deleteLocalVariableTableAttribute = false;
+ deleteLocalVariableTypeTableAttribute = false;
- // Clean up the variables of the attributes.
+ // Trim the local variable table and the local variable type table.
codeAttribute.attributesAccept(clazz, method, this);
+
+ // Delete the local variable table if it ended up empty.
+ if (deleteLocalVariableTableAttribute)
+ {
+ AttributesEditor editor =
+ new AttributesEditor((ProgramClass)clazz,
+ (ProgramMember)method,
+ codeAttribute,
+ true);
+
+ editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTable);
+ }
+
+ // Delete the local variable type table if it ended up empty.
+ if (deleteLocalVariableTypeTableAttribute)
+ {
+ AttributesEditor editor =
+ new AttributesEditor((ProgramClass)clazz,
+ (ProgramMember)method,
+ codeAttribute,
+ true);
+
+ editor.deleteAttribute(ClassConstants.ATTR_LocalVariableTypeTable);
+ }
}
@@ -60,9 +85,20 @@
{
// Clean up local variables that aren't used.
localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength,
- codeAttribute.u2maxLocals);
+ removeUnusedLocalVariables(localVariableTableAttribute.localVariableTable,
+ localVariableTableAttribute.u2localVariableTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Trim the code blocks of the local variables.
+ trimLocalVariables(localVariableTableAttribute.localVariableTable,
+ localVariableTableAttribute.u2localVariableTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Delete the attribute in a moment, if it is empty.
+ if (localVariableTableAttribute.u2localVariableTableLength == 0)
+ {
+ deleteLocalVariableTableAttribute = true;
+ }
}
@@ -70,9 +106,20 @@
{
// Clean up local variables that aren't used.
localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength,
- codeAttribute.u2maxLocals);
+ removeUnusedLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Trim the code blocks of the local variables.
+ trimLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength,
+ codeAttribute.u2maxLocals);
+
+ // Delete the attribute in a moment, if it is empty.
+ if (localVariableTypeTableAttribute.u2localVariableTypeTableLength == 0)
+ {
+ deleteLocalVariableTypeTableAttribute = true;
+ }
}
@@ -80,27 +127,28 @@
/**
* Returns the given list of local variables, without the ones that aren't
- * used
+ * used.
*/
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount,
- int maxLocals)
+ private int removeUnusedLocalVariables(LocalVariableInfo[] localVariableInfos,
+ int localVariableInfoCount,
+ int maxLocals)
{
// Overwrite all empty local variable entries.
int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount && index < maxLocals; index++)
+ for (int index = 0; index < localVariableInfoCount; index++)
{
- if (variableUsageMarker.isVariableUsed(index))
+ LocalVariableInfo localVariableInfo = localVariableInfos[index];
+
+ if (localVariableInfo.u2index >= 0 &&
+ localVariableInfo.u2index < maxLocals &&
+ localVariableInfo.u2length > 0)
{
localVariableInfos[newIndex++] = localVariableInfos[index];
}
}
// Clean up any remaining array elements.
- for (int index = newIndex; index < localVariableInfoCount; index++)
- {
- localVariableInfos[index] = null;
- }
+ Arrays.fill(localVariableInfos, newIndex, localVariableInfoCount, null);
return newIndex;
}
@@ -108,28 +156,112 @@
/**
* Returns the given list of local variable types, without the ones that
- * aren't used
+ * aren't used.
*/
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount,
- int maxLocals)
+ private int removeUnusedLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
+ int localVariableTypeInfoCount,
+ int maxLocals)
{
// Overwrite all empty local variable type entries.
int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount && index < maxLocals; index++)
+ for (int index = 0; index < localVariableTypeInfoCount; index++)
{
- if (variableUsageMarker.isVariableUsed(index))
+ LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
+
+ if (localVariableTypeInfo.u2index >= 0 &&
+ localVariableTypeInfo.u2index < maxLocals &&
+ localVariableTypeInfo.u2length > 0)
{
localVariableTypeInfos[newIndex++] = localVariableTypeInfos[index];
}
}
// Clean up any remaining array elements.
- for (int index = newIndex; index < localVariableTypeInfoCount; index++)
- {
- localVariableTypeInfos[index] = null;
- }
+ Arrays.fill(localVariableTypeInfos, newIndex, localVariableTypeInfoCount, null);
return newIndex;
}
+
+
+ /**
+ * Sorts the given list of local variables and trims their code blocks
+ * when necessary. The block is trimmed at the end, which is a bit
+ * arbitrary.
+ */
+ private void trimLocalVariables(LocalVariableInfo[] localVariableInfos,
+ int localVariableInfoCount,
+ int maxLocals)
+ {
+ // Sort the local variable entries.
+ Arrays.sort(localVariableInfos, 0, localVariableInfoCount);
+
+ int[] startPCs = createMaxArray(maxLocals);
+
+ // Trim the local variable entries, starting at the last one.
+ for (int index = localVariableInfoCount-1; index >= 0; index--)
+ {
+ LocalVariableInfo localVariableInfo = localVariableInfos[index];
+
+ // Make sure the variable's code block doesn't overlap with the
+ // next one for the same variable.
+ int maxLength = startPCs[localVariableInfo.u2index] -
+ localVariableInfo.u2startPC;
+
+ if (localVariableInfo.u2length > maxLength)
+ {
+ localVariableInfo.u2length = maxLength;
+ }
+
+ startPCs[localVariableInfo.u2index] = localVariableInfo.u2startPC;
+ }
+ }
+
+
+ /**
+ * Sorts the given list of local variable types and trims their code blocks
+ * when necessary. The block is trimmed at the end, which is a bit
+ * arbitrary.
+ */
+ private void trimLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
+ int localVariableTypeInfoCount,
+ int maxLocals)
+ {
+ // Sort the local variable entries.
+ Arrays.sort(localVariableTypeInfos, 0, localVariableTypeInfoCount);
+
+ int[] startPCs = createMaxArray(maxLocals);
+
+ // Trim the local variable entries, starting at the last one.
+ for (int index = localVariableTypeInfoCount-1; index >= 0; index--)
+ {
+ LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
+
+ // Make sure the variable's code block doesn't overlap with the
+ // next one for the same variable.
+ int maxLength = startPCs[localVariableTypeInfo.u2index] -
+ localVariableTypeInfo.u2startPC;
+
+ if (localVariableTypeInfo.u2length > maxLength)
+ {
+ localVariableTypeInfo.u2length = maxLength;
+ }
+
+ startPCs[localVariableTypeInfo.u2index] = localVariableTypeInfo.u2startPC;
+ }
+ }
+
+
+ /**
+ * Creates an integer array of the given length, initialized with
+ * Integer.MAX_VALUE.
+ */
+ private int[] createMaxArray(int length)
+ {
+ int[] startPCs = new int[length];
+ for (int index = 0; index < length; index++)
+ {
+ startPCs[index] = Integer.MAX_VALUE;
+ }
+ return startPCs;
+ }
}
\ No newline at end of file
diff --git a/src/proguard/classfile/editor/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java
index a583b49..8c99ff8 100644
--- a/src/proguard/classfile/editor/VariableEditor.java
+++ b/src/proguard/classfile/editor/VariableEditor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -25,6 +25,8 @@
import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor accumulates specified changes to local variables, and
* then applies these accumulated changes to the code attributes that it visits.
@@ -53,14 +55,13 @@
// Try to reuse the previous array.
if (deleted.length < maxLocals)
{
+ // Create a new array.
deleted = new boolean[maxLocals];
}
else
{
- for (int index = 0; index < maxLocals; index++)
- {
- deleted[index] = false;
- }
+ // Reset the array.
+ Arrays.fill(deleted, 0, maxLocals, false);
}
modified = false;
diff --git a/src/proguard/classfile/editor/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java
index 590cd4e..df26534 100644
--- a/src/proguard/classfile/editor/VariableRemapper.java
+++ b/src/proguard/classfile/editor/VariableRemapper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -40,6 +40,9 @@
LocalVariableInfoVisitor,
LocalVariableTypeInfoVisitor
{
+ private static final boolean DEBUG = false;
+
+
private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
private int[] variableMap;
@@ -62,6 +65,19 @@
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
+ if (DEBUG)
+ {
+ System.out.println("VariableRemapper: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
+ for (int index= 0; index < codeAttribute.u2maxLocals; index++)
+ {
+ System.out.println(" v"+index+" -> "+variableMap[index]);
+ }
+ }
+
+ // Remap the variables of the attributes, before editing the code and
+ // cleaning up its local variable frame.
+ codeAttribute.attributesAccept(clazz, method, this);
+
// Initially, the code attribute editor doesn't contain any changes.
codeAttributeEditor.reset(codeAttribute.u4codeLength);
@@ -70,9 +86,6 @@
// Apply the code atribute editor.
codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
-
- // Remap the variables of the attributes.
- codeAttribute.attributesAccept(clazz, method, this);
}
@@ -80,11 +93,6 @@
{
// Remap the variable references of the local variables.
localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables that haven't been mapped.
- localVariableTableAttribute.u2localVariableTableLength =
- removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable,
- localVariableTableAttribute.u2localVariableTableLength);
}
@@ -92,11 +100,6 @@
{
// Remap the variable references of the local variables.
localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
-
- // Remove local variables that haven't been mapped.
- localVariableTypeTableAttribute.u2localVariableTypeTableLength =
- removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable,
- localVariableTypeTableAttribute.u2localVariableTypeTableLength);
}
@@ -150,48 +153,4 @@
{
return variableMap[variableIndex];
}
-
-
- /**
- * Returns the given list of local variables, without the ones that have
- * been removed.
- */
- private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos,
- int localVariableInfoCount)
- {
- // Overwrite all empty local variable entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableInfoCount; index++)
- {
- LocalVariableInfo localVariableInfo = localVariableInfos[index];
- if (localVariableInfo.u2index >= 0)
- {
- localVariableInfos[newIndex++] = localVariableInfo;
- }
- }
-
- return newIndex;
- }
-
-
- /**
- * Returns the given list of local variable types, without the ones that
- * have been removed.
- */
- private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos,
- int localVariableTypeInfoCount)
- {
- // Overwrite all empty local variable type entries.
- int newIndex = 0;
- for (int index = 0; index < localVariableTypeInfoCount; index++)
- {
- LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index];
- if (localVariableTypeInfo.u2index >= 0)
- {
- localVariableTypeInfos[newIndex++] = localVariableTypeInfo;
- }
- }
-
- return newIndex;
- }
}
diff --git a/src/proguard/classfile/editor/VariableSizeUpdater.java b/src/proguard/classfile/editor/VariableSizeUpdater.java
index 18958c5..bb87151 100644
--- a/src/proguard/classfile/editor/VariableSizeUpdater.java
+++ b/src/proguard/classfile/editor/VariableSizeUpdater.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,7 +29,8 @@
/**
* This AttributeVisitor computes and updates the maximum local variable frame
- * size of the code attributes that it visits.
+ * size of the code attributes that it visits. It also cleans up the local
+ * variable tables.
*
* @author Eric Lafortune
*/
@@ -45,6 +46,9 @@
//*/
+ private VariableCleaner variableCleaner = new VariableCleaner();
+
+
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@@ -69,6 +73,9 @@
// Go over all instructions.
codeAttribute.instructionsAccept(clazz, method, this);
+
+ // Remove the unused variables of the attributes.
+ variableCleaner.visitCodeAttribute(clazz, method, codeAttribute);
}
@@ -91,7 +98,7 @@
if (DEBUG)
{
- System.out.println("Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset));
+ System.out.println(" Max locals: "+codeAttribute.u2maxLocals+" <- "+variableInstruction.toString(offset));
}
}
}
diff --git a/src/proguard/classfile/instruction/BranchInstruction.java b/src/proguard/classfile/instruction/BranchInstruction.java
index 2baa917..54f583b 100644
--- a/src/proguard/classfile/instruction/BranchInstruction.java
+++ b/src/proguard/classfile/instruction/BranchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/ConstantInstruction.java b/src/proguard/classfile/instruction/ConstantInstruction.java
index 6c2d1a3..900a8d5 100644
--- a/src/proguard/classfile/instruction/ConstantInstruction.java
+++ b/src/proguard/classfile/instruction/ConstantInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -93,13 +93,9 @@
public byte canonicalOpcode()
{
// Remove the _w extension, if any.
- switch (opcode)
- {
- case InstructionConstants.OP_LDC_W:
- case InstructionConstants.OP_LDC2_W: return InstructionConstants.OP_LDC;
-
- default: return opcode;
- }
+ return
+ opcode == InstructionConstants.OP_LDC_W ? InstructionConstants.OP_LDC :
+ opcode;
}
public Instruction shrink()
@@ -185,7 +181,8 @@
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
- // The some parameters may be popped from the stack.
+ case InstructionConstants.OP_INVOKEDYNAMIC:
+ // Some parameters may be popped from the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPopCount += parameterStackDelta;
break;
@@ -208,6 +205,7 @@
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
// The field value or a return value may be pushed onto the stack.
clazz.constantPoolEntryAccept(constantIndex, this);
stackPushCount += typeStackDelta;
@@ -226,8 +224,9 @@
public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant) {}
public void visitStringConstant(Clazz clazz, StringConstant stringConstant) {}
public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant) {}
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant) {}
public void visitClassConstant(Clazz clazz, ClassConstant classConstant) {}
- public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant) {}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant) {}
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
@@ -238,21 +237,27 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+ }
+
+
public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
{
- visitRefConstant(clazz, interfaceMethodrefConstant);
+ clazz.constantPoolEntryAccept(interfaceMethodrefConstant.u2nameAndTypeIndex, this);
}
public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
{
- visitRefConstant(clazz, methodrefConstant);
+ clazz.constantPoolEntryAccept(methodrefConstant.u2nameAndTypeIndex, this);
}
- private void visitRefConstant(Clazz clazz, RefConstant methodrefConstant)
+ public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
- String type = methodrefConstant.getType(clazz);
+ String type = nameAndTypeConstant.getType(clazz);
parameterStackDelta = ClassUtil.internalMethodParameterSize(type);
typeStackDelta = ClassUtil.internalTypeSize(ClassUtil.internalMethodReturnType(type));
@@ -285,6 +290,7 @@
private int constantSize()
{
return opcode == InstructionConstants.OP_MULTIANEWARRAY ? 1 :
+ opcode == InstructionConstants.OP_INVOKEDYNAMIC ||
opcode == InstructionConstants.OP_INVOKEINTERFACE ? 2 :
0;
}
diff --git a/src/proguard/classfile/instruction/Instruction.java b/src/proguard/classfile/instruction/Instruction.java
index 8437495..77b0e20 100644
--- a/src/proguard/classfile/instruction/Instruction.java
+++ b/src/proguard/classfile/instruction/Instruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -220,7 +220,7 @@
false, // invokespecial
false, // invokestatic
false, // invokeinterface
- false, // unused
+ false, // invokedynamic
false, // new
false, // newarray
false, // anewarray
@@ -429,7 +429,7 @@
1, // invokespecial
0, // invokestatic
1, // invokeinterface
- 0, // unused
+ 0, // invokedynamic
0, // new
1, // newarray
1, // anewarray
@@ -638,7 +638,7 @@
0, // invokespecial
0, // invokestatic
0, // invokeinterface
- 0, // unused
+ 0, // invokedynamic
1, // new
1, // newarray
1, // anewarray
diff --git a/src/proguard/classfile/instruction/InstructionConstants.java b/src/proguard/classfile/instruction/InstructionConstants.java
index 78730b3..8ca03cc 100644
--- a/src/proguard/classfile/instruction/InstructionConstants.java
+++ b/src/proguard/classfile/instruction/InstructionConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -213,22 +213,22 @@
public static final byte OP_INVOKESPECIAL = -73;
public static final byte OP_INVOKESTATIC = -72;
public static final byte OP_INVOKEINTERFACE = -71;
-// public static final byte OP_UNUSED = -70;
- public static final byte OP_NEW = -69;
- public static final byte OP_NEWARRAY = -68;
- public static final byte OP_ANEWARRAY = -67;
- public static final byte OP_ARRAYLENGTH = -66;
- public static final byte OP_ATHROW = -65;
- public static final byte OP_CHECKCAST = -64;
- public static final byte OP_INSTANCEOF = -63;
- public static final byte OP_MONITORENTER = -62;
- public static final byte OP_MONITOREXIT = -61;
- public static final byte OP_WIDE = -60;
- public static final byte OP_MULTIANEWARRAY = -59;
- public static final byte OP_IFNULL = -58;
- public static final byte OP_IFNONNULL = -57;
- public static final byte OP_GOTO_W = -56;
- public static final byte OP_JSR_W = -55;
+ public static final byte OP_INVOKEDYNAMIC = -70;
+ public static final byte OP_NEW = -69;
+ public static final byte OP_NEWARRAY = -68;
+ public static final byte OP_ANEWARRAY = -67;
+ public static final byte OP_ARRAYLENGTH = -66;
+ public static final byte OP_ATHROW = -65;
+ public static final byte OP_CHECKCAST = -64;
+ public static final byte OP_INSTANCEOF = -63;
+ public static final byte OP_MONITORENTER = -62;
+ public static final byte OP_MONITOREXIT = -61;
+ public static final byte OP_WIDE = -60;
+ public static final byte OP_MULTIANEWARRAY = -59;
+ public static final byte OP_IFNULL = -58;
+ public static final byte OP_IFNONNULL = -57;
+ public static final byte OP_GOTO_W = -56;
+ public static final byte OP_JSR_W = -55;
public static final String[] NAMES =
@@ -419,7 +419,7 @@
"invokespecial",
"invokestatic",
"invokeinterface",
- "unused",
+ "invokedynamic",
"new",
"newarray",
"anewarray",
diff --git a/src/proguard/classfile/instruction/InstructionFactory.java b/src/proguard/classfile/instruction/InstructionFactory.java
index f898471..288acc2 100644
--- a/src/proguard/classfile/instruction/InstructionFactory.java
+++ b/src/proguard/classfile/instruction/InstructionFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -182,6 +182,7 @@
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
case InstructionConstants.OP_NEW:
case InstructionConstants.OP_ANEWARRAY:
diff --git a/src/proguard/classfile/instruction/InstructionUtil.java b/src/proguard/classfile/instruction/InstructionUtil.java
index a3a328a..12d4d05 100644
--- a/src/proguard/classfile/instruction/InstructionUtil.java
+++ b/src/proguard/classfile/instruction/InstructionUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
index 178cce5..2da639b 100644
--- a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/SimpleInstruction.java b/src/proguard/classfile/instruction/SimpleInstruction.java
index 84e6344..83499dc 100644
--- a/src/proguard/classfile/instruction/SimpleInstruction.java
+++ b/src/proguard/classfile/instruction/SimpleInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/SwitchInstruction.java b/src/proguard/classfile/instruction/SwitchInstruction.java
index b98c2fb..11f05c4 100644
--- a/src/proguard/classfile/instruction/SwitchInstruction.java
+++ b/src/proguard/classfile/instruction/SwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/TableSwitchInstruction.java b/src/proguard/classfile/instruction/TableSwitchInstruction.java
index ee81af5..a5e8c5e 100644
--- a/src/proguard/classfile/instruction/TableSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/TableSwitchInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/VariableInstruction.java b/src/proguard/classfile/instruction/VariableInstruction.java
index 309f802..6cbd3de 100644
--- a/src/proguard/classfile/instruction/VariableInstruction.java
+++ b/src/proguard/classfile/instruction/VariableInstruction.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
index 71b2cde..c355433 100644
--- a/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/AllInstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/visitor/InstructionCounter.java b/src/proguard/classfile/instruction/visitor/InstructionCounter.java
index 1d10980..64c0f65 100644
--- a/src/proguard/classfile/instruction/visitor/InstructionCounter.java
+++ b/src/proguard/classfile/instruction/visitor/InstructionCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
index 11af131..d7d1b24 100644
--- a/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/InstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
index aada455..160ccd7 100644
--- a/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
+++ b/src/proguard/classfile/instruction/visitor/MultiInstructionVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/io/LibraryClassReader.java b/src/proguard/classfile/io/LibraryClassReader.java
index f14471c..32bb569 100644
--- a/src/proguard/classfile/io/LibraryClassReader.java
+++ b/src/proguard/classfile/io/LibraryClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -277,6 +277,18 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ dataInput.skipBytes(4);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ dataInput.skipBytes(3);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
dataInput.skipBytes(4);
@@ -289,6 +301,12 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ dataInput.skipBytes(2);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataInput.skipBytes(4);
@@ -325,16 +343,19 @@
switch (u1tag)
{
- case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
case ClassConstants.CONSTANT_Integer: return new IntegerConstant();
case ClassConstants.CONSTANT_Float: return new FloatConstant();
case ClassConstants.CONSTANT_Long: return new LongConstant();
case ClassConstants.CONSTANT_Double: return new DoubleConstant();
case ClassConstants.CONSTANT_String: return new StringConstant();
+ case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
+ case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant();
+ case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant();
case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant();
case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant();
case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant();
case ClassConstants.CONSTANT_Class: return new ClassConstant();
+ case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant();
case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant();
default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool");
diff --git a/src/proguard/classfile/io/ProgramClassReader.java b/src/proguard/classfile/io/ProgramClassReader.java
index 476a346..01f057f 100644
--- a/src/proguard/classfile/io/ProgramClassReader.java
+++ b/src/proguard/classfile/io/ProgramClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -46,6 +46,7 @@
MemberVisitor,
ConstantVisitor,
AttributeVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
@@ -250,6 +251,20 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ invokeDynamicConstant.u2bootstrapMethodAttributeIndex = dataInput.readUnsignedShort();
+ invokeDynamicConstant.u2nameAndTypeIndex = dataInput.readUnsignedShort();
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ methodHandleConstant.u1referenceKind = dataInput.readUnsignedByte();
+ methodHandleConstant.u2referenceIndex = dataInput.readUnsignedShort();
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
refConstant.u2classIndex = dataInput.readUnsignedShort();
@@ -263,6 +278,12 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ methodTypeConstant.u2descriptorIndex = dataInput.readUnsignedShort();
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
nameAndTypeConstant.u2nameIndex = dataInput.readUnsignedShort();
@@ -281,6 +302,21 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Read the bootstrap methods.
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount = dataInput.readUnsignedShort();
+
+ bootstrapMethodsAttribute.bootstrapMethods = new BootstrapMethodInfo[bootstrapMethodsAttribute.u2bootstrapMethodsCount];
+ for (int index = 0; index < bootstrapMethodsAttribute.u2bootstrapMethodsCount; index++)
+ {
+ BootstrapMethodInfo bootstrapMethodInfo = new BootstrapMethodInfo();
+ visitBootstrapMethodInfo(clazz, bootstrapMethodInfo);
+ bootstrapMethodsAttribute.bootstrapMethods[index] = bootstrapMethodInfo;
+ }
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
sourceFileAttribute.u2sourceFileIndex = dataInput.readUnsignedShort();
@@ -302,7 +338,7 @@
for (int index = 0; index < innerClassesAttribute.u2classesCount; index++)
{
InnerClassesInfo innerClassesInfo = new InnerClassesInfo();
- this.visitInnerClassesInfo(clazz, innerClassesInfo);
+ visitInnerClassesInfo(clazz, innerClassesInfo);
innerClassesAttribute.classes[index] = innerClassesInfo;
}
}
@@ -372,7 +408,7 @@
for (int index = 0; index < codeAttribute.u2exceptionTableLength; index++)
{
ExceptionInfo exceptionInfo = new ExceptionInfo();
- this.visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
+ visitExceptionInfo(clazz, method, codeAttribute, exceptionInfo);
codeAttribute.exceptionTable[index] = exceptionInfo;
}
@@ -398,7 +434,7 @@
for (int index = 0; index < stackMapAttribute.u2stackMapFramesCount; index++)
{
FullFrame stackMapFrame = new FullFrame();
- this.visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
+ visitFullFrame(clazz, method, codeAttribute, index, stackMapFrame);
stackMapAttribute.stackMapFrames[index] = stackMapFrame;
}
}
@@ -428,7 +464,7 @@
for (int index = 0; index < lineNumberTableAttribute.u2lineNumberTableLength; index++)
{
LineNumberInfo lineNumberInfo = new LineNumberInfo();
- this.visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
+ visitLineNumberInfo(clazz, method, codeAttribute, lineNumberInfo);
lineNumberTableAttribute.lineNumberTable[index] = lineNumberInfo;
}
}
@@ -443,7 +479,7 @@
for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
{
LocalVariableInfo localVariableInfo = new LocalVariableInfo();
- this.visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
+ visitLocalVariableInfo(clazz, method, codeAttribute, localVariableInfo);
localVariableTableAttribute.localVariableTable[index] = localVariableInfo;
}
}
@@ -458,7 +494,7 @@
for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
{
LocalVariableTypeInfo localVariableTypeInfo = new LocalVariableTypeInfo();
- this.visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
+ visitLocalVariableTypeInfo(clazz, method, codeAttribute, localVariableTypeInfo);
localVariableTypeTableAttribute.localVariableTypeTable[index] = localVariableTypeInfo;
}
}
@@ -473,7 +509,7 @@
for (int index = 0; index < annotationsAttribute.u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotation);
annotationsAttribute.annotations[index] = annotation;
}
}
@@ -508,7 +544,7 @@
for (int index = 0; index < u2annotationsCount; index++)
{
Annotation annotation = new Annotation();
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotation);
annotations[index] = annotation;
}
@@ -527,6 +563,22 @@
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ bootstrapMethodInfo.u2methodHandleIndex = dataInput.readUnsignedShort();
+
+ // Read the bootstrap method arguments.
+ bootstrapMethodInfo.u2methodArgumentCount = dataInput.readUnsignedShort();
+ bootstrapMethodInfo.u2methodArguments = new int[bootstrapMethodInfo.u2methodArgumentCount];
+ for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++)
+ {
+ bootstrapMethodInfo.u2methodArguments[index] = dataInput.readUnsignedShort();
+ }
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
@@ -721,7 +773,7 @@
{
// Read the annotation.
Annotation annotationValue = new Annotation();
- this.visitAnnotation(clazz, annotationValue);
+ visitAnnotation(clazz, annotationValue);
annotationElementValue.annotationValue = annotationValue;
}
@@ -749,16 +801,19 @@
switch (u1tag)
{
- case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
case ClassConstants.CONSTANT_Integer: return new IntegerConstant();
case ClassConstants.CONSTANT_Float: return new FloatConstant();
case ClassConstants.CONSTANT_Long: return new LongConstant();
case ClassConstants.CONSTANT_Double: return new DoubleConstant();
case ClassConstants.CONSTANT_String: return new StringConstant();
+ case ClassConstants.CONSTANT_Utf8: return new Utf8Constant();
+ case ClassConstants.CONSTANT_InvokeDynamic: return new InvokeDynamicConstant();
+ case ClassConstants.CONSTANT_MethodHandle: return new MethodHandleConstant();
case ClassConstants.CONSTANT_Fieldref: return new FieldrefConstant();
case ClassConstants.CONSTANT_Methodref: return new MethodrefConstant();
case ClassConstants.CONSTANT_InterfaceMethodref: return new InterfaceMethodrefConstant();
case ClassConstants.CONSTANT_Class: return new ClassConstant();
+ case ClassConstants.CONSTANT_MethodType : return new MethodTypeConstant();
case ClassConstants.CONSTANT_NameAndType: return new NameAndTypeConstant();
default: throw new RuntimeException("Unknown constant type ["+u1tag+"] in constant pool");
@@ -771,7 +826,9 @@
int u2attributeNameIndex = dataInput.readUnsignedShort();
int u4attributeLength = dataInput.readInt();
String attributeName = clazz.getString(u2attributeNameIndex);
+
Attribute attribute =
+ attributeName.equals(ClassConstants.ATTR_BootstrapMethods) ? (Attribute)new BootstrapMethodsAttribute():
attributeName.equals(ClassConstants.ATTR_SourceFile) ? (Attribute)new SourceFileAttribute():
attributeName.equals(ClassConstants.ATTR_SourceDir) ? (Attribute)new SourceDirAttribute():
attributeName.equals(ClassConstants.ATTR_InnerClasses) ? (Attribute)new InnerClassesAttribute():
diff --git a/src/proguard/classfile/io/ProgramClassWriter.java b/src/proguard/classfile/io/ProgramClassWriter.java
index e56f08a..53995d4 100644
--- a/src/proguard/classfile/io/ProgramClassWriter.java
+++ b/src/proguard/classfile/io/ProgramClassWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -57,7 +57,7 @@
/**
- * Creates a new ProgramClassWriter for reading from the given DataOutput.
+ * Creates a new ProgramClassWriter for writing to the given DataOutput.
*/
public ProgramClassWriter(DataOutput dataOutput)
{
@@ -208,6 +208,20 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ dataOutput.writeShort(invokeDynamicConstant.u2bootstrapMethodAttributeIndex);
+ dataOutput.writeShort(invokeDynamicConstant.u2nameAndTypeIndex);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ dataOutput.writeByte(methodHandleConstant.u1referenceKind);
+ dataOutput.writeShort(methodHandleConstant.u2referenceIndex);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
dataOutput.writeShort(refConstant.u2classIndex);
@@ -221,6 +235,12 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ dataOutput.writeShort(methodTypeConstant.u2descriptorIndex);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
dataOutput.writeShort(nameAndTypeConstant.u2nameIndex);
@@ -263,6 +283,7 @@
private class AttributeBodyWriter
extends SimplifiedVisitor
implements AttributeVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
ExceptionInfoVisitor,
StackMapFrameVisitor,
@@ -282,6 +303,15 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Write the bootstrap methods.
+ dataOutput.writeShort(bootstrapMethodsAttribute.u2bootstrapMethodsCount);
+
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
dataOutput.writeShort(sourceFileAttribute.u2sourceFileIndex);
@@ -438,8 +468,7 @@
for (int index = 0; index < u2annotationsCount; index++)
{
- Annotation annotation = annotations[index];
- this.visitAnnotation(clazz, annotation);
+ visitAnnotation(clazz, annotations[index]);
}
}
@@ -453,6 +482,22 @@
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Write the bootstrap method arguments.
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodArgumentCount);
+
+ for (int index = 0; index < bootstrapMethodInfo.u2methodArgumentCount; index++)
+ {
+ dataOutput.writeShort(bootstrapMethodInfo.u2methodArguments[index]);
+ }
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
diff --git a/src/proguard/classfile/io/RuntimeDataInput.java b/src/proguard/classfile/io/RuntimeDataInput.java
index 104b7c9..7225ec9 100644
--- a/src/proguard/classfile/io/RuntimeDataInput.java
+++ b/src/proguard/classfile/io/RuntimeDataInput.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/io/RuntimeDataOutput.java b/src/proguard/classfile/io/RuntimeDataOutput.java
index ffde3af..75d0642 100644
--- a/src/proguard/classfile/io/RuntimeDataOutput.java
+++ b/src/proguard/classfile/io/RuntimeDataOutput.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/AccessUtil.java b/src/proguard/classfile/util/AccessUtil.java
index 3ad6961..068a89e 100644
--- a/src/proguard/classfile/util/AccessUtil.java
+++ b/src/proguard/classfile/util/AccessUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/ClassReferenceInitializer.java b/src/proguard/classfile/util/ClassReferenceInitializer.java
index b1f2c27..e7709ab 100644
--- a/src/proguard/classfile/util/ClassReferenceInitializer.java
+++ b/src/proguard/classfile/util/ClassReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -166,17 +166,30 @@
}
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Fill out the MethodHandle class.
+ methodHandleConstant.javaLangInvokeMethodHandleClass =
+ findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
String className = refConstant.getClassName(clazz);
+ // Methods for array types should be found in the Object class.
+ if (ClassUtil.isInternalArrayType(className))
+ {
+ className = ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT;
+ }
+
// See if we can find the referenced class.
// Unresolved references are assumed to refer to library classes
// that will not change anyway.
Clazz referencedClass = findClass(clazz.getName(), className);
- if (referencedClass != null &&
- !ClassUtil.isInternalArrayType(className))
+ if (referencedClass != null)
{
String name = refConstant.getName(clazz);
String type = refConstant.getType(clazz);
@@ -194,7 +207,7 @@
if (refConstant.referencedMember == null)
{
- // We've haven't found the class member anywhere in the hierarchy.
+ // We haven't found the class member anywhere in the hierarchy.
missingMemberWarningPrinter.print(clazz.getName(),
className,
"Warning: " +
@@ -216,7 +229,7 @@
// Fill out the referenced class.
classConstant.referencedClass =
- findClass(className, classConstant.getName(clazz));
+ findClass(className, ClassUtil.internalClassNameFromClassType(classConstant.getName(clazz)));
// Fill out the Class class.
classConstant.javaLangClassClass =
@@ -224,6 +237,14 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ // Fill out the MethodType class.
+ methodTypeConstant.javaLangInvokeMethodTypeClass =
+ findClass(clazz.getName(), ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE);
+ }
+
+
// Implementations for AttributeVisitor.
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
@@ -235,49 +256,36 @@
String enclosingClassName = enclosingMethodAttribute.getClassName(clazz);
// See if we can find the referenced class.
- Clazz referencedClass = findClass(className, enclosingClassName);
+ enclosingMethodAttribute.referencedClass =
+ findClass(className, enclosingClassName);
- if (referencedClass == null)
+ if (enclosingMethodAttribute.referencedClass != null)
{
- // We couldn't find the enclosing class.
- missingClassWarningPrinter.print(className,
- enclosingClassName,
- "Warning: " +
- ClassUtil.externalClassName(className) +
- ": can't find enclosing class " +
- ClassUtil.externalClassName(enclosingClassName));
- return;
+ // Is there an enclosing method? Otherwise it's just initialization
+ // code outside of the constructors.
+ if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
+ {
+ String name = enclosingMethodAttribute.getName(clazz);
+ String type = enclosingMethodAttribute.getType(clazz);
+
+ // See if we can find the method in the referenced class.
+ enclosingMethodAttribute.referencedMethod =
+ enclosingMethodAttribute.referencedClass.findMethod(name, type);
+
+ if (enclosingMethodAttribute.referencedMethod == null)
+ {
+ // We couldn't find the enclosing method.
+ missingMemberWarningPrinter.print(className,
+ enclosingClassName,
+ "Warning: " +
+ ClassUtil.externalClassName(className) +
+ ": can't find enclosing method '" +
+ ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) +
+ "' in class " +
+ ClassUtil.externalClassName(enclosingClassName));
+ }
+ }
}
-
- // Make sure there is actually an enclosed method.
- if (enclosingMethodAttribute.u2nameAndTypeIndex == 0)
- {
- return;
- }
-
- String name = enclosingMethodAttribute.getName(clazz);
- String type = enclosingMethodAttribute.getType(clazz);
-
- // See if we can find the method in the referenced class.
- Method referencedMethod = referencedClass.findMethod(name, type);
-
- if (referencedMethod == null)
- {
- // We couldn't find the enclosing method.
- missingMemberWarningPrinter.print(className,
- enclosingClassName,
- "Warning: " +
- ClassUtil.externalClassName(className) +
- ": can't find enclosing method '" +
- ClassUtil.externalFullMethodDescription(enclosingClassName, 0, name, type) +
- "' in class " +
- ClassUtil.externalClassName(enclosingClassName));
- return;
- }
-
- // Save the references.
- enclosingMethodAttribute.referencedClass = referencedClass;
- enclosingMethodAttribute.referencedMethod = referencedMethod;
}
@@ -501,11 +509,17 @@
*/
private Clazz findClass(String referencingClassName, String name)
{
- // Ignore any primitive array types.
- if (ClassUtil.isInternalArrayType(name) &&
- !ClassUtil.isInternalClassType(name))
+ // Is it an array type?
+ if (ClassUtil.isInternalArrayType(name))
{
- return null;
+ // Ignore any primitive array types.
+ if (!ClassUtil.isInternalClassType(name))
+ {
+ return null;
+ }
+
+ // Strip the array part.
+ name = ClassUtil.internalClassNameFromClassType(name);
}
// First look for the class in the program class pool.
diff --git a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
index 30fd526..304efd7 100644
--- a/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
+++ b/src/proguard/classfile/util/ClassSubHierarchyInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
index af2a209..de95250 100644
--- a/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
+++ b/src/proguard/classfile/util/ClassSuperHierarchyInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -106,11 +106,6 @@
libraryClass.interfaceClasses = interfaceClasses;
}
-
- // Discard the name Strings. From now on, we'll use the object
- // references.
- libraryClass.superClassName = null;
- libraryClass.interfaceNames = null;
}
diff --git a/src/proguard/classfile/util/ClassUtil.java b/src/proguard/classfile/util/ClassUtil.java
index 5f25f01..e92a022 100644
--- a/src/proguard/classfile/util/ClassUtil.java
+++ b/src/proguard/classfile/util/ClassUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -100,6 +100,8 @@
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_5) ? ClassConstants.INTERNAL_CLASS_VERSION_1_5 :
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6_ALIAS) ||
classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_6) ? ClassConstants.INTERNAL_CLASS_VERSION_1_6 :
+ classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7_ALIAS) ||
+ classVersion.equals(ClassConstants.EXTERNAL_CLASS_VERSION_1_7) ? ClassConstants.INTERNAL_CLASS_VERSION_1_7 :
0;
}
@@ -119,6 +121,7 @@
case ClassConstants.INTERNAL_CLASS_VERSION_1_4: return ClassConstants.EXTERNAL_CLASS_VERSION_1_4;
case ClassConstants.INTERNAL_CLASS_VERSION_1_5: return ClassConstants.EXTERNAL_CLASS_VERSION_1_5;
case ClassConstants.INTERNAL_CLASS_VERSION_1_6: return ClassConstants.EXTERNAL_CLASS_VERSION_1_6;
+ case ClassConstants.INTERNAL_CLASS_VERSION_1_7: return ClassConstants.EXTERNAL_CLASS_VERSION_1_7;
default: return null;
}
}
@@ -132,11 +135,14 @@
public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException
{
if (classVersion < ClassConstants.INTERNAL_CLASS_VERSION_1_0 ||
- classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_6)
+ classVersion > ClassConstants.INTERNAL_CLASS_VERSION_1_7)
{
- throw new UnsupportedOperationException("Unsupported version number ["+
+ throw new UnsupportedOperationException("Unsupported class version number ["+
internalMajorClassVersion(classVersion)+"."+
- internalMinorClassVersion(classVersion)+"] for class format");
+ internalMinorClassVersion(classVersion)+"] (maximum "+
+ ClassConstants.INTERNAL_CLASS_VERSION_1_7_MAJOR+"."+
+ ClassConstants.INTERNAL_CLASS_VERSION_1_7_MINOR+", Java "+
+ ClassConstants.EXTERNAL_CLASS_VERSION_1_7+")");
}
}
@@ -189,8 +195,25 @@
/**
- * Converts an internal class name into an external short class name, without
- * package specification.
+ * Returns the external base type of an external array type, dropping any
+ * array brackets.
+ * @param externalArrayType the external array type,
+ * e.g. "<code>java.lang.Object[][]</code>"
+ * @return the external base type,
+ * e.g. "<code>java.lang.Object</code>".
+ */
+ public static String externalBaseType(String externalArrayType)
+ {
+ int index = externalArrayType.indexOf(ClassConstants.EXTERNAL_TYPE_ARRAY);
+ return index >= 0 ?
+ externalArrayType.substring(0, index) :
+ externalArrayType;
+ }
+
+
+ /**
+ * Returns the external short class name of an external class name, dropping
+ * the package specification.
* @param externalClassName the external class name,
* e.g. "<code>java.lang.Object</code>"
* @return the external short class name,
@@ -410,6 +433,21 @@
/**
+ * Returns whether the given method name refers to a class initializer or
+ * an instance initializer.
+ * @param internalMethodName the internal method name,
+ * e.g. "<code><clinit></code>".
+ * @return whether the method name refers to an initializer,
+ * e.g. <code>true</code>.
+ */
+ public static boolean isInitializer(String internalMethodName)
+ {
+ return internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_CLINIT) ||
+ internalMethodName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);
+ }
+
+
+ /**
* Returns the internal type of the given internal method descriptor.
* @param internalMethodDescriptor the internal method descriptor,
* e.g. "<code>(II)Z</code>".
@@ -869,6 +907,21 @@
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PUBLIC).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PRIVATE).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_PROTECTED) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_PROTECTED).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
+ {
+ // Only in InnerClasses attributes.
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STATIC).append(' ');
+ }
if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_FINAL).append(' ');
@@ -889,6 +942,10 @@
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_ABSTRACT).append(' ');
}
+ else if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
@@ -950,6 +1007,10 @@
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_TRANSIENT).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
@@ -1007,6 +1068,14 @@
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNCHRONIZED).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_BRIDGE) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_BRIDGE).append(' ');
+ }
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_VARARGS) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_VARARGS).append(' ');
+ }
if ((accessFlags & ClassConstants.INTERNAL_ACC_NATIVE) != 0)
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_NATIVE).append(' ');
@@ -1019,6 +1088,10 @@
{
string.append(prefix).append(ClassConstants.EXTERNAL_ACC_STRICT).append(' ');
}
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_SYNTHETIC) != 0)
+ {
+ string.append(prefix).append(ClassConstants.EXTERNAL_ACC_SYNTHETIC).append(' ');
+ }
return string.toString();
}
diff --git a/src/proguard/classfile/util/DescriptorClassEnumeration.java b/src/proguard/classfile/util/DescriptorClassEnumeration.java
index 0bee2d5..bb08f08 100644
--- a/src/proguard/classfile/util/DescriptorClassEnumeration.java
+++ b/src/proguard/classfile/util/DescriptorClassEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
index 09ffdd0..bdf2102 100644
--- a/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
+++ b/src/proguard/classfile/util/DynamicClassReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -301,7 +301,8 @@
{
// Save a reference to the corresponding class.
String externalClassName = stringConstant.getString(clazz);
- String internalClassName = ClassUtil.internalClassName(externalClassName);
+ String internalClassName = ClassUtil.internalClassName(
+ ClassUtil.externalBaseType(externalClassName));
stringConstant.referencedClass = findClass(clazz.getName(), internalClassName);
}
@@ -350,7 +351,7 @@
return;
}
- String className = methodrefConstant.getClassName(clazz);
+ String className = methodrefConstant.getClassName(clazz);
// Note that we look for the class by name, since the referenced
// class has not been initialized yet.
@@ -434,11 +435,17 @@
*/
private Clazz findClass(String referencingClassName, String name)
{
- // Ignore any primitive array types.
- if (ClassUtil.isInternalArrayType(name) &&
- !ClassUtil.isInternalClassType(name))
+ // Is it an array type?
+ if (ClassUtil.isInternalArrayType(name))
{
- return null;
+ // Ignore any primitive array types.
+ if (!ClassUtil.isInternalClassType(name))
+ {
+ return null;
+ }
+
+ // Strip the array part.
+ name = ClassUtil.internalClassNameFromClassType(name);
}
// First look for the class in the program class pool.
diff --git a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
index 1f57708..110dc43 100644
--- a/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
+++ b/src/proguard/classfile/util/DynamicMemberReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -55,14 +55,20 @@
AttributeVisitor,
MemberVisitor
{
- public static final int X = InstructionSequenceMatcher.X;
- public static final int Y = InstructionSequenceMatcher.Y;
- public static final int Z = InstructionSequenceMatcher.Z;
+ /*
+ private static boolean DEBUG = true;
+ /*/
+ private static final boolean DEBUG = false;
+ //*/
- public static final int A = InstructionSequenceMatcher.A;
- public static final int B = InstructionSequenceMatcher.B;
- public static final int C = InstructionSequenceMatcher.C;
- public static final int D = InstructionSequenceMatcher.D;
+ public static final int CLASS_INDEX = InstructionSequenceMatcher.X;
+ public static final int MEMBER_NAME_INDEX = InstructionSequenceMatcher.Y;
+ public static final int TYPE_CLASS_INDEX = InstructionSequenceMatcher.Z;
+
+ public static final int PARAMETER0_CLASS_INDEX = InstructionSequenceMatcher.A;
+ public static final int PARAMETER1_CLASS_INDEX = InstructionSequenceMatcher.B;
+ public static final int PARAMETER2_CLASS_INDEX = InstructionSequenceMatcher.C;
+ public static final int PARAMETER3_CLASS_INDEX = InstructionSequenceMatcher.D;
private final Constant[] GET_FIELD_CONSTANTS = new Constant[]
@@ -85,6 +91,26 @@
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_FIELD),
};
+ private final Constant[] GET_CONSTRUCTOR_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_CONSTRUCTOR),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_CONSTRUCTOR),
+ };
+
+ private final Constant[] GET_DECLARED_CONSTRUCTOR_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_NAME_CLASS_GET_DECLARED_CONSTRUCTOR),
+ new Utf8Constant(ClassConstants.INTERNAL_CONSTRUCTOR_TYPE_CLASS_GET_DECLARED_CONSTRUCTOR),
+ };
+
private final Constant[] GET_METHOD_CONSTANTS = new Constant[]
{
new MethodrefConstant(1, 2, null, null),
@@ -105,19 +131,88 @@
new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CLASS_GET_DECLARED_METHOD),
};
+ private final Constant[] NEW_INTEGER_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_INTEGER_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_INTEGER_UPDATER),
+ };
+
+ private final Constant[] NEW_LONG_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_LONG_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_LONG_UPDATER),
+ };
+
+ private final Constant[] NEW_REFERENCE_UPDATER_CONSTANTS = new Constant[]
+ {
+ new MethodrefConstant(1, 2, null, null),
+ new ClassConstant(3, null),
+ new NameAndTypeConstant(4, 5),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_UTIL_CONCURRENT_ATOMIC_ATOMIC_REFERENCE_FIELD_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_NEW_UPDATER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_NEW_REFERENCE_UPDATER),
+ };
+
// SomeClass.class.get[Declared]Field("someField").
private final Instruction[] CONSTANT_GET_FIELD_INSTRUCTIONS = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+// // SomeClass.class.get[Declared]Constructor(new Class[] {}).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+//
+// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class }).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+//
+// // SomeClass.class.get[Declared]Constructor(new Class[] { A.class, B.class }).
+// private final Instruction[] CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[]
+// {
+// new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_2),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new SimpleInstruction(InstructionConstants.OP_DUP),
+// new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+// new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
+// new SimpleInstruction(InstructionConstants.OP_AASTORE),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+
// SomeClass.class.get[Declared]Method("someMethod", new Class[] {}).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS0 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
@@ -126,13 +221,13 @@
// SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
@@ -140,32 +235,86 @@
// SomeClass.class.get[Declared]Method("someMethod", new Class[] { A.class, B.class }).
private final Instruction[] CONSTANT_GET_METHOD_INSTRUCTIONS2 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, X),
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_2),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
- new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+ // AtomicIntegerFieldUpdater.newUpdater(A.class, "someField").
+ // AtomicLongFieldUpdater.newUpdater(A.class, "someField").
+ private final Instruction[] CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
+ // AtomicReferenceFieldUpdater.newUpdater(A.class, B.class, "someField").
+ private final Instruction[] CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, TYPE_CLASS_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
// get[Declared]Field("someField").
private final Instruction[] GET_FIELD_INSTRUCTIONS = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+ };
+
+// // get[Declared]Constructor(new Class[] {}).
+// private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS0 = new Instruction[]
+// {
+// new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+// new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+// new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+// };
+
+ // get[Declared]Constructor(new Class[] { A.class }).
+ private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS1 = new Instruction[]
+ {
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
+ };
+
+ // get[Declared]Constructor(new Class[] { A.class, B.class }).
+ private final Instruction[] GET_CONSTRUCTOR_INSTRUCTIONS2 = new Instruction[]
+ {
+ new SimpleInstruction(InstructionConstants.OP_ICONST_2),
+ new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
+ new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
// get[Declared]Method("someMethod", new Class[] {}).
private final Instruction[] GET_METHOD_INSTRUCTIONS0 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
@@ -174,12 +323,12 @@
// get[Declared]Method("someMethod", new Class[] { A.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS1 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
@@ -187,20 +336,29 @@
// get[Declared]Method("someMethod", new Class[] { A.class, B.class }).
private final Instruction[] GET_METHOD_INSTRUCTIONS2 = new Instruction[]
{
- new ConstantInstruction(InstructionConstants.OP_LDC, Y),
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
new SimpleInstruction(InstructionConstants.OP_ICONST_2),
new ConstantInstruction(InstructionConstants.OP_ANEWARRAY, 1),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
- new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER0_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new SimpleInstruction(InstructionConstants.OP_DUP),
new SimpleInstruction(InstructionConstants.OP_ICONST_1),
- new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_LDC, PARAMETER1_CLASS_INDEX),
new SimpleInstruction(InstructionConstants.OP_AASTORE),
new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, 0),
};
+ // AtomicIntegerFieldUpdater.newUpdater(..., "someField").
+ // AtomicLongFieldUpdater.newUpdater(..., "someField").
+ // AtomicReferenceFieldUpdater.newUpdater(..., "someField").
+ private final Instruction[] NEW_UPDATER_INSTRUCTIONS = new Instruction[]
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, MEMBER_NAME_INDEX),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESTATIC, 0),
+ };
+
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;
@@ -217,6 +375,30 @@
new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS,
CONSTANT_GET_FIELD_INSTRUCTIONS);
+// private final InstructionSequenceMatcher constantGetConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher constantGetConstructorMatcher1 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher1 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS1);
+//
+// private final InstructionSequenceMatcher constantGetConstructorMatcher2 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2);
+//
+// private final InstructionSequenceMatcher constantGetDeclaredConstructorMatcher2 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// CONSTANT_GET_CONSTRUCTOR_INSTRUCTIONS2);
+
private final InstructionSequenceMatcher constantGetMethodMatcher0 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS0);
@@ -241,6 +423,18 @@
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
CONSTANT_GET_METHOD_INSTRUCTIONS2);
+ private final InstructionSequenceMatcher constantGetIntegerUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS,
+ CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher constantGetLongUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS,
+ CONSTANT_NEW_PRIMITIVE_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher constantGetReferenceUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS,
+ CONSTANT_NEW_REFERENCE_UPDATER_INSTRUCTIONS);
+
private final InstructionSequenceMatcher getFieldMatcher =
new InstructionSequenceMatcher(GET_FIELD_CONSTANTS,
GET_FIELD_INSTRUCTIONS);
@@ -249,6 +443,30 @@
new InstructionSequenceMatcher(GET_DECLARED_FIELD_CONSTANTS,
GET_FIELD_INSTRUCTIONS);
+// private final InstructionSequenceMatcher getConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+// GET_CONSTRUCTOR_INSTRUCTIONS0);
+//
+// private final InstructionSequenceMatcher getDeclaredConstructorMatcher0 =
+// new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+// GET_CONSTRUCTOR_INSTRUCTIONS0);
+
+ private final InstructionSequenceMatcher getConstructorMatcher1 =
+ new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS1);
+
+ private final InstructionSequenceMatcher getDeclaredConstructorMatcher1 =
+ new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS1);
+
+ private final InstructionSequenceMatcher getConstructorMatcher2 =
+ new InstructionSequenceMatcher(GET_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS2);
+
+ private final InstructionSequenceMatcher getDeclaredConstructorMatcher2 =
+ new InstructionSequenceMatcher(GET_DECLARED_CONSTRUCTOR_CONSTANTS,
+ GET_CONSTRUCTOR_INSTRUCTIONS2);
+
private final InstructionSequenceMatcher getMethodMatcher0 =
new InstructionSequenceMatcher(GET_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS0);
@@ -273,11 +491,24 @@
new InstructionSequenceMatcher(GET_DECLARED_METHOD_CONSTANTS,
GET_METHOD_INSTRUCTIONS2);
+ private final InstructionSequenceMatcher getIntegerUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_INTEGER_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher getLongUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_LONG_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
+ private final InstructionSequenceMatcher getReferenceUpdaterMatcher =
+ new InstructionSequenceMatcher(NEW_REFERENCE_UPDATER_CONSTANTS,
+ NEW_UPDATER_INSTRUCTIONS);
+
private final MemberFinder memberFinder = new MemberFinder();
// Fields acting as parameters for the visitors.
private Clazz referencedClass;
+ private String descriptor;
private boolean isDeclared;
private boolean isField;
@@ -307,48 +538,110 @@
// Try to match the SomeClass.class.getField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetFieldMatcher,
- getFieldMatcher, true, false);
+ getFieldMatcher, true, false, null, null);
// Try to match the SomeClass.class.getDeclaredField("someField") construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredFieldMatcher,
- getDeclaredFieldMatcher, true, true);
+ getDeclaredFieldMatcher, true, true, null, null);
+
+// // Try to match the SomeClass.class.getConstructor(new Class[]
+// // {}) construct.
+// matchGetMember(clazz, method, codeAttribute, offset, instruction,
+// cnull, //onstantGetConstructorMatcher0,
+// getConstructorMatcher0, false, false,
+// ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+//
+// // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+// // {}) construct.
+// matchGetMember(clazz, method, codeAttribute, offset, instruction,
+// null, //constantGetDeclaredConstructorMatcher0,
+// getDeclaredConstructorMatcher0, false, true,
+// ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getConstructor(new Class[]
+ // { A.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetConstructorMatcher1,
+ getConstructorMatcher1, false, false,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+ // { A.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetDeclaredConstructorMatcher1,
+ getDeclaredConstructorMatcher1, false, true,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getConstructor(new Class[]
+ // { A.class, B.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetConstructorMatcher2,
+ getConstructorMatcher2, false, false,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
+
+ // Try to match the SomeClass.class.getDeclaredConstructor(new Class[]
+ // { A.class, B.class }) construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ null, //constantGetDeclaredConstructorMatcher2,
+ getDeclaredConstructorMatcher2, false, true,
+ ClassConstants.INTERNAL_METHOD_NAME_INIT, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// {}) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher0,
- getMethodMatcher0, false, false);
+ getMethodMatcher0, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
- // new Class[] {}) construct.
+ // new Class[] {}) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher0,
- getDeclaredMethodMatcher0, false, true);
+ getDeclaredMethodMatcher0, false, true, null, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// { A.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher1,
- getMethodMatcher1, false, false);
+ getMethodMatcher1, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
// new Class[] { A.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher1,
- getDeclaredMethodMatcher1, false, true);
+ getDeclaredMethodMatcher1, false, true, null, null);
// Try to match the SomeClass.class.getMethod("someMethod", new Class[]
// { A.class, B.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetMethodMatcher2,
- getMethodMatcher2, false, false);
+ getMethodMatcher2, false, false, null, null);
// Try to match the SomeClass.class.getDeclaredMethod("someMethod",
- // new Class[] { A.class, B.class }) construct.
+ // new Class[] { A.class, B.class }) construct.
matchGetMember(clazz, method, codeAttribute, offset, instruction,
constantGetDeclaredMethodMatcher2,
- getDeclaredMethodMatcher2, false, true);
+ getDeclaredMethodMatcher2, false, true, null, null);
+
+ // Try to match the AtomicIntegerFieldUpdater.newUpdater(
+ // SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetIntegerUpdaterMatcher,
+ getIntegerUpdaterMatcher, true, false, null,
+ "" + ClassConstants.INTERNAL_TYPE_INT);
+
+ // Try to match the AtomicLongFieldUpdater.newUpdater(
+ // SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetLongUpdaterMatcher,
+ getLongUpdaterMatcher, true, false, null,
+ "" + ClassConstants.INTERNAL_TYPE_LONG);
+
+ // Try to match the AtomicReferenceFieldUpdater.newUpdater(
+ // SomeClass.class, SomeClass.class, "someField") construct.
+ matchGetMember(clazz, method, codeAttribute, offset, instruction,
+ constantGetReferenceUpdaterMatcher,
+ getReferenceUpdaterMatcher, true, false, null, null);
}
@@ -364,26 +657,28 @@
InstructionSequenceMatcher constantSequenceMatcher,
InstructionSequenceMatcher variableSequenceMatcher,
boolean isField,
- boolean isDeclared)
+ boolean isDeclared,
+ String defaultName,
+ String defaultDescriptor)
{
- // Try to match the next instruction in the constant sequence.
- instruction.accept(clazz, method, codeAttribute, offset,
- constantSequenceMatcher);
-
- // Did we find a match to fill out the string constant?
- if (constantSequenceMatcher.isMatching())
+ if (constantSequenceMatcher != null)
{
- this.isField = isField;
- this.isDeclared = isDeclared;
+ // Try to match the next instruction in the constant sequence.
+ instruction.accept(clazz, method, codeAttribute, offset,
+ constantSequenceMatcher);
- // Get the member's class.
- clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(X), this);
+ // Did we find a match to fill out the string constant?
+ if (constantSequenceMatcher.isMatching())
+ {
+ initializeStringReference(clazz,
+ constantSequenceMatcher,
+ isField,
+ isDeclared,
+ defaultDescriptor);
- // Fill out the matched string constant.
- clazz.constantPoolEntryAccept(constantSequenceMatcher.matchedConstantIndex(Y), this);
-
- // Don't look for the dynamic construct.
- variableSequenceMatcher.reset();
+ // Don't look for the dynamic construct.
+ variableSequenceMatcher.reset();
+ }
}
// Try to match the next instruction in the variable sequence.
@@ -397,11 +692,41 @@
printDynamicInvocationNote(clazz,
variableSequenceMatcher,
isField,
- isDeclared);
+ isDeclared,
+ defaultName,
+ defaultDescriptor);
}
}
+ /**
+ * Initializes the reference of the matched string constant to the
+ * referenced class member and its class.
+ */
+ private void initializeStringReference(Clazz clazz,
+ InstructionSequenceMatcher constantSequenceMatcher,
+ boolean isField,
+ boolean isDeclared,
+ String defaultDescriptor)
+ {
+ this.isField = isField;
+ this.isDeclared = isDeclared;
+
+ // Get the member's class.
+ int classIndex = constantSequenceMatcher.matchedConstantIndex(CLASS_INDEX);
+ clazz.constantPoolEntryAccept(classIndex, this);
+
+ // Get the field's reference type, if applicable.
+ int typeClassIndex = constantSequenceMatcher.matchedConstantIndex(TYPE_CLASS_INDEX);
+ descriptor = typeClassIndex <= 0 ? defaultDescriptor :
+ ClassUtil.internalTypeFromClassName(clazz.getClassName(typeClassIndex));
+
+ // Fill out the matched string constant.
+ int memberNameIndex = constantSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX);
+ clazz.constantPoolEntryAccept(memberNameIndex, this);
+ }
+
+
// Implementations for ConstantVisitor.
/**
@@ -409,6 +734,11 @@
*/
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
+ if (DEBUG)
+ {
+ System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched class ["+classConstant.getName(clazz)+"]");
+ }
+
// Remember the referenced class.
referencedClass = ClassUtil.isInternalArrayType(classConstant.getName(clazz)) ?
null :
@@ -425,15 +755,20 @@
{
String name = stringConstant.getString(clazz);
+ if (DEBUG)
+ {
+ System.out.println("DynamicMemberReferenceInitializer: ["+clazz.getName()+"] matched string ["+name+"]");
+ }
+
// See if we can find the referenced class member locally, or
// somewhere in the hierarchy.
Member referencedMember = isDeclared ? isField ?
- (Member)referencedClass.findField(name, null) :
- (Member)referencedClass.findMethod(name, null) :
+ (Member)referencedClass.findField(name, descriptor) :
+ (Member)referencedClass.findMethod(name, descriptor) :
(Member)memberFinder.findMember(clazz,
referencedClass,
name,
- null,
+ descriptor,
isField);
if (referencedMember != null)
{
@@ -454,7 +789,9 @@
private void printDynamicInvocationNote(Clazz clazz,
InstructionSequenceMatcher noteSequenceMatcher,
boolean isField,
- boolean isDeclared)
+ boolean isDeclared,
+ String defaultName,
+ String defaultDescriptor)
{
// Print out a note about the dynamic invocation.
if (notePrinter != null &&
@@ -465,8 +802,9 @@
noteFieldExceptionMatcher :
noteMethodExceptionMatcher;
- int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(Y);
- String memberName = clazz.getStringString(memberNameIndex);
+ int memberNameIndex = noteSequenceMatcher.matchedConstantIndex(MEMBER_NAME_INDEX);
+ String memberName = memberNameIndex <= 0 ? defaultName :
+ clazz.getStringString(memberNameIndex);
if (noteExceptionMatcher == null ||
!noteExceptionMatcher.matches(memberName))
@@ -479,7 +817,8 @@
externalMemberDescription += '(';
for (int count = 0; count < 2; count++)
{
- int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);
+ int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(
+ PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
if (count > 0)
@@ -501,7 +840,9 @@
ClassUtil.externalClassName(clazz.getName()) +
" accesses a " +
(isDeclared ? "declared " : "") +
- (isField ? "field" : "method") +
+ (isField ? "field" :
+ memberName.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
+ "constructor" : "method") +
" '" +
externalMemberDescription +
"' dynamically");
@@ -511,9 +852,12 @@
if (isField)
{
- classVisitor =
+ classVisitor = defaultDescriptor == null ?
new AllFieldVisitor(
- new MemberNameFilter(memberName, this));
+ new MemberNameFilter(memberName, this)) :
+ new AllFieldVisitor(
+ new MemberNameFilter(memberName,
+ new MemberDescriptorFilter(defaultDescriptor, this)));
}
else
{
@@ -521,20 +865,16 @@
String methodDescriptor = "(";
for (int count = 0; count < 2; count++)
{
- int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(A + count);
+ int memberArgumentIndex = noteSequenceMatcher.matchedConstantIndex(PARAMETER0_CLASS_INDEX + count);
if (memberArgumentIndex > 0)
{
- if (count > 0)
- {
- methodDescriptor += ',';
- }
String className = clazz.getClassName(memberArgumentIndex);
methodDescriptor += ClassUtil.isInternalArrayType(className) ?
className :
ClassUtil.internalTypeFromClassName(className);
}
}
- methodDescriptor += ")L///;";
+ methodDescriptor += ")L***;";
classVisitor =
new AllMethodVisitor(
@@ -571,7 +911,7 @@
System.out.println(" Maybe this is program method '" +
ClassUtil.externalFullClassDescription(0, programClass.getName()) +
" { " +
- ClassUtil.externalFullMethodDescription(null, 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +
+ ClassUtil.externalFullMethodDescription(programClass.getName(), 0, programMethod.getName(programClass), programMethod.getDescriptor(programClass)) +
"; }'");
}
}
@@ -597,7 +937,7 @@
System.out.println(" Maybe this is library method '" +
ClassUtil.externalFullClassDescription(0, libraryClass.getName()) +
" { " +
- ClassUtil.externalFullMethodDescription(null, 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +
+ ClassUtil.externalFullMethodDescription(libraryClass.getName(), 0, libraryMethod.getName(libraryClass), libraryMethod.getDescriptor(libraryClass)) +
"; }'");
}
}
diff --git a/src/proguard/classfile/util/ExternalTypeEnumeration.java b/src/proguard/classfile/util/ExternalTypeEnumeration.java
index 6371888..7edfbc9 100644
--- a/src/proguard/classfile/util/ExternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/ExternalTypeEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/InstructionSequenceMatcher.java b/src/proguard/classfile/util/InstructionSequenceMatcher.java
index 8a689d5..51eb7bc 100644
--- a/src/proguard/classfile/util/InstructionSequenceMatcher.java
+++ b/src/proguard/classfile/util/InstructionSequenceMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -27,6 +27,8 @@
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
+import java.util.Arrays;
+
/**
* This InstructionVisitor checks whether a given pattern instruction sequence
* occurs in the instructions that are visited. The arguments of the
@@ -40,8 +42,8 @@
ConstantVisitor
{
/*
- private static boolean DEBUG = false;
- public static boolean DEBUG_MORE = false;
+ public static boolean DEBUG = true;
+ public static boolean DEBUG_MORE = true;
/*/
private static final boolean DEBUG = false;
private static final boolean DEBUG_MORE = false;
@@ -60,14 +62,15 @@
private final Constant[] patternConstants;
private final Instruction[] patternInstructions;
- private boolean matching;
- private boolean matchingAnyWildCards;
- private int patternInstructionIndex;
- private final int[] matchedInstructionOffsets;
- private int matchedArgumentFlags;
- private final int[] matchedArguments = new int[7];
- private long matchedConstantFlags;
- private final int[] matchedConstantIndices;
+ private boolean matching;
+ private int patternInstructionIndex;
+ private final int[] matchedInstructionOffsets;
+ private int matchedArgumentFlags;
+ private final int[] matchedArguments = new int[7];
+ private final long[] matchedConstantFlags;
+ private final int[] matchedConstantIndices;
+ private int constantFlags;
+ private int previousConstantFlags;
// Fields acting as a parameter and a return value for visitor methods.
private Constant patternConstant;
@@ -87,6 +90,7 @@
this.patternInstructions = patternInstructions;
matchedInstructionOffsets = new int[patternInstructions.length];
+ matchedConstantFlags = new long[(patternConstants.length + 63) / 64];
matchedConstantIndices = new int[patternConstants.length];
}
@@ -98,34 +102,55 @@
{
patternInstructionIndex = 0;
matchedArgumentFlags = 0;
- matchedConstantFlags = 0L;
+
+ Arrays.fill(matchedConstantFlags, 0L);
+
+ previousConstantFlags = constantFlags;
+ constantFlags = 0;
}
+ /**
+ * Returns whether the complete pattern sequence has been matched.
+ */
public boolean isMatching()
{
return matching;
}
- public boolean isMatchingAnyWildcards()
- {
- return matchingAnyWildCards;
- }
-
-
+ /**
+ * Returns the number of instructions in the pattern sequence.
+ */
public int instructionCount()
{
return patternInstructions.length;
}
+ /**
+ * Returns the matched instruction offset of the specified pattern
+ * instruction.
+ */
public int matchedInstructionOffset(int index)
{
return matchedInstructionOffsets[index];
}
+ /**
+ * Returns whether the specified wildcard argument was a constant from
+ * the constant pool in the most recent match.
+ */
+ public boolean wasConstant(int argument)
+ {
+ return (previousConstantFlags & (1 << (argument - X))) != 0;
+ }
+
+
+ /**
+ * Returns the value of the specified matched argument (wildcard or not).
+ */
public int matchedArgument(int argument)
{
int argumentIndex = argument - X;
@@ -135,6 +160,9 @@
}
+ /**
+ * Returns the values of the specified matched arguments (wildcard or not).
+ */
public int[] matchedArguments(int[] arguments)
{
int[] matchedArguments = new int[arguments.length];
@@ -148,6 +176,9 @@
}
+ /**
+ * Returns the index of the specified matched constant (wildcard or not).
+ */
public int matchedConstantIndex(int constantIndex)
{
int argumentIndex = constantIndex - X;
@@ -157,6 +188,10 @@
}
+ /**
+ * Returns the value of the specified matched branch offset (wildcard or
+ * not).
+ */
public int matchedBranchOffset(int offset, int branchOffset)
{
int argumentIndex = branchOffset - X;
@@ -166,6 +201,10 @@
}
+ /**
+ * Returns the values of the specified matched jump offsets (wildcard or
+ * not).
+ */
public int[] matchedJumpOffsets(int offset, int[] jumpOffsets)
{
int[] matchedJumpOffsets = new int[jumpOffsets.length];
@@ -387,6 +426,35 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ InvokeDynamicConstant invokeDynamicPatternConstant = (InvokeDynamicConstant)patternConstant;
+
+ // Check the bootstrap method and the name and type.
+ matchingConstant =
+ matchingConstantIndices(clazz,
+ invokeDynamicConstant.getBootstrapMethodAttributeIndex(),
+ invokeDynamicPatternConstant.getBootstrapMethodAttributeIndex()) &&
+ matchingConstantIndices(clazz,
+ invokeDynamicConstant.getNameAndTypeIndex(),
+ invokeDynamicPatternConstant.getNameAndTypeIndex());
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ MethodHandleConstant methodHandlePatternConstant = (MethodHandleConstant)patternConstant;
+
+ // Check the handle type and the name and type.
+ matchingConstant =
+ matchingArguments(methodHandleConstant.getReferenceKind(),
+ methodHandlePatternConstant.getReferenceKind()) &&
+ matchingConstantIndices(clazz,
+ methodHandleConstant.getReferenceIndex(),
+ methodHandlePatternConstant.getReferenceIndex());
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
RefConstant refPatternConstant = (RefConstant)patternConstant;
@@ -414,6 +482,18 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ MethodTypeConstant typePatternConstant = (MethodTypeConstant)patternConstant;
+
+ // Check the descriptor.
+ matchingConstant =
+ matchingConstantIndices(clazz,
+ methodTypeConstant.u2descriptorIndex,
+ typePatternConstant.u2descriptorIndex);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
NameAndTypeConstant typePatternConstant = (NameAndTypeConstant)patternConstant;
@@ -449,11 +529,10 @@
// Check the literal argument.
return argument1 == argument2;
}
- else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0)
+ else if (!isMatchingArgumentIndex(argumentIndex))
{
- // Store a wildcard argument.
- matchedArguments[argumentIndex] = argument1;
- matchedArgumentFlags |= 1 << argumentIndex;
+ // Store the wildcard argument.
+ setMatchingArgument(argumentIndex, argument1);
return true;
}
@@ -465,6 +544,28 @@
}
+ /**
+ * Marks the specified argument (by index) as matching the specified
+ * argument value.
+ */
+ private void setMatchingArgument(int argumentIndex,
+ int argument)
+ {
+ matchedArguments[argumentIndex] = argument;
+ matchedArgumentFlags |= 1 << argumentIndex;
+ }
+
+
+ /**
+ * Returns whether the specified wildcard argument (by index) has been
+ * matched.
+ */
+ private boolean isMatchingArgumentIndex(int argumentIndex)
+ {
+ return (matchedArgumentFlags & (1 << argumentIndex)) != 0;
+ }
+
+
private boolean matchingArguments(int[] arguments1,
int[] arguments2)
{
@@ -491,10 +592,13 @@
{
if (constantIndex2 >= X)
{
+ // Remember that we are trying to match a constant.
+ constantFlags |= 1 << (constantIndex2 - X);
+
// Check the constant index.
return matchingArguments(constantIndex1, constantIndex2);
}
- else if ((matchedConstantFlags & (1L << constantIndex2)) == 0)
+ else if (!isMatchingConstantIndex(constantIndex2))
{
// Check the actual constant.
matchingConstant = false;
@@ -507,8 +611,7 @@
if (matchingConstant)
{
// Store the constant index.
- matchedConstantIndices[constantIndex2] = constantIndex1;
- matchedConstantFlags |= 1L << constantIndex2;
+ setMatchingConstant(constantIndex2, constantIndex1);
}
}
@@ -522,6 +625,27 @@
}
+ /**
+ * Marks the specified constant (by index) as matching the specified
+ * constant index value.
+ */
+ private void setMatchingConstant(int constantIndex,
+ int constantIndex1)
+ {
+ matchedConstantIndices[constantIndex] = constantIndex1;
+ matchedConstantFlags[constantIndex / 64] |= 1L << constantIndex;
+ }
+
+
+ /**
+ * Returns whether the specified wildcard constant has been matched.
+ */
+ private boolean isMatchingConstantIndex(int constantIndex)
+ {
+ return (matchedConstantFlags[constantIndex / 64] & (1L << constantIndex)) != 0;
+ }
+
+
private boolean matchingBranchOffsets(int offset,
int branchOffset1,
int branchOffset2)
@@ -532,11 +656,10 @@
// Check the literal argument.
return branchOffset1 == branchOffset2;
}
- else if ((matchedArgumentFlags & (1 << argumentIndex)) == 0)
+ else if (!isMatchingArgumentIndex(argumentIndex))
{
// Store a wildcard argument.
- matchedArguments[argumentIndex] = offset + branchOffset1;
- matchedArgumentFlags |= 1 << argumentIndex;
+ setMatchingArgument(argumentIndex, offset + branchOffset1);
return true;
}
@@ -595,9 +718,6 @@
// Did we match all instructions in the sequence?
matching = patternInstructionIndex == patternInstructions.length;
- // Did we match any wildcards along the way?
- matchingAnyWildCards = matchedArgumentFlags != 0;
-
if (matching)
{
if (DEBUG)
diff --git a/src/proguard/classfile/util/InternalTypeEnumeration.java b/src/proguard/classfile/util/InternalTypeEnumeration.java
index 76f7e84..8658be3 100644
--- a/src/proguard/classfile/util/InternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/InternalTypeEnumeration.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/MemberFinder.java b/src/proguard/classfile/util/MemberFinder.java
index 0fdeec0..6108b6d 100644
--- a/src/proguard/classfile/util/MemberFinder.java
+++ b/src/proguard/classfile/util/MemberFinder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/util/MethodLinker.java b/src/proguard/classfile/util/MethodLinker.java
index 5f2ea6f..8aed77a 100644
--- a/src/proguard/classfile/util/MethodLinker.java
+++ b/src/proguard/classfile/util/MethodLinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,16 +26,11 @@
import java.util.*;
/**
- * This ClassVisitor links all corresponding non-private methods in the class
- * hierarchies of all visited classes. Visited classes are typically all class
- * files that are not being subclassed. Chains of links that have been created
- * in previous invocations are merged with new chains of links, in order to
- * create a consistent set of chains.
- * <p>
- * As a MemberVisitor, it links all corresponding class members that it visits,
- * including fields and private class members.
- * <p>
- * Class initialization methods and constructors are always ignored.
+ * This ClassVisitor links all corresponding non-private, non-static,
+ * non-initializer methods in the class hierarchies of all visited classes.
+ * Visited classes are typically all class files that are not being subclassed.
+ * Chains of links that have been created in previous invocations are merged
+ * with new chains of links, in order to create a consistent set of chains.
*
* @author Eric Lafortune
*/
@@ -56,7 +51,7 @@
// Collect all non-private members in this class hierarchy.
clazz.hierarchyAccept(true, true, true, false,
new AllMethodVisitor(
- new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+ new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE | ClassConstants.INTERNAL_ACC_STATIC,
this)));
// Clean up for the next class hierarchy.
diff --git a/src/proguard/classfile/util/SimplifiedVisitor.java b/src/proguard/classfile/util/SimplifiedVisitor.java
index 87b7fe4..55b3848 100644
--- a/src/proguard/classfile/util/SimplifiedVisitor.java
+++ b/src/proguard/classfile/util/SimplifiedVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -42,7 +42,7 @@
/**
* Visits any type of class member of the given class.
*/
- public void visitAnyClass(Clazz Clazz)
+ public void visitAnyClass(Clazz clazz)
{
throw new UnsupportedOperationException("Method must be overridden in ["+this.getClass().getName()+"] if ever called");
}
@@ -157,6 +157,18 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ visitAnyConstant(clazz, invokeDynamicConstant);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ visitAnyConstant(clazz, methodHandleConstant);
+ }
+
+
/**
* Visits any type of RefConstant of the given class.
*/
@@ -199,6 +211,12 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ visitAnyConstant(clazz, methodTypeConstant);
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
visitAnyConstant(clazz, nameAndTypeConstant);
@@ -222,6 +240,12 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ visitAnyAttribute(clazz, bootstrapMethodsAttribute);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
visitAnyAttribute(clazz, sourceFileAttribute);
diff --git a/src/proguard/classfile/util/StringReferenceInitializer.java b/src/proguard/classfile/util/StringReferenceInitializer.java
index 3884a04..aff9b9f 100644
--- a/src/proguard/classfile/util/StringReferenceInitializer.java
+++ b/src/proguard/classfile/util/StringReferenceInitializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -62,7 +62,8 @@
{
// See if we can find the referenced class.
stringConstant.referencedClass =
- findClass(ClassUtil.internalClassName(stringConstant.getString(clazz)));
+ findClass(ClassUtil.internalClassName(
+ ClassUtil.externalBaseType(stringConstant.getString(clazz))));
}
}
diff --git a/src/proguard/classfile/util/StringSharer.java b/src/proguard/classfile/util/StringSharer.java
index 56de7c5..04dc1d0 100644
--- a/src/proguard/classfile/util/StringSharer.java
+++ b/src/proguard/classfile/util/StringSharer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -64,6 +64,23 @@
{
libraryClass.superClassName = superClass.getName();
}
+
+ // Replace the interface name strings by the shared name strings.
+ if (libraryClass.interfaceNames != null)
+ {
+ String[] interfaceNames = libraryClass.interfaceNames;
+ Clazz[] interfaceClasses = new Clazz[interfaceNames.length];
+
+ for (int index = 0; index < interfaceNames.length; index++)
+ {
+ // Keep a reference to the interface class.
+ Clazz interfaceClass = interfaceClasses[index];
+ if (interfaceClass != null)
+ {
+ interfaceNames[index] = interfaceClass.getName();
+ }
+ }
+ }
}
@@ -73,7 +90,7 @@
public void visitAnyConstant(Clazz clazz, Constant constant) {}
- public void visitAnyStringConstant(Clazz clazz, StringConstant stringConstant)
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
Member referencedMember = stringConstant.referencedMember;
if (referencedMember != null)
diff --git a/src/proguard/classfile/util/WarningPrinter.java b/src/proguard/classfile/util/WarningPrinter.java
index 87d8978..de66bd6 100644
--- a/src/proguard/classfile/util/WarningPrinter.java
+++ b/src/proguard/classfile/util/WarningPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/AllClassVisitor.java b/src/proguard/classfile/visitor/AllClassVisitor.java
index 06aca2c..ea6272d 100644
--- a/src/proguard/classfile/visitor/AllClassVisitor.java
+++ b/src/proguard/classfile/visitor/AllClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/AllFieldVisitor.java b/src/proguard/classfile/visitor/AllFieldVisitor.java
index 8bff7d4..40af76c 100644
--- a/src/proguard/classfile/visitor/AllFieldVisitor.java
+++ b/src/proguard/classfile/visitor/AllFieldVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/AllMemberVisitor.java b/src/proguard/classfile/visitor/AllMemberVisitor.java
index 448470e..2a6f34e 100644
--- a/src/proguard/classfile/visitor/AllMemberVisitor.java
+++ b/src/proguard/classfile/visitor/AllMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/AllMethodVisitor.java b/src/proguard/classfile/visitor/AllMethodVisitor.java
index 75b919d..2526a6a 100644
--- a/src/proguard/classfile/visitor/AllMethodVisitor.java
+++ b/src/proguard/classfile/visitor/AllMethodVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/BottomClassFilter.java b/src/proguard/classfile/visitor/BottomClassFilter.java
index 8f5bdd1..6f442ac 100644
--- a/src/proguard/classfile/visitor/BottomClassFilter.java
+++ b/src/proguard/classfile/visitor/BottomClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassAccessFilter.java b/src/proguard/classfile/visitor/ClassAccessFilter.java
index a8815b6..cab208f 100644
--- a/src/proguard/classfile/visitor/ClassAccessFilter.java
+++ b/src/proguard/classfile/visitor/ClassAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassCleaner.java b/src/proguard/classfile/visitor/ClassCleaner.java
index 36165ef..4dd1790 100644
--- a/src/proguard/classfile/visitor/ClassCleaner.java
+++ b/src/proguard/classfile/visitor/ClassCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassCollector.java b/src/proguard/classfile/visitor/ClassCollector.java
index a69fe76..07c6a15 100644
--- a/src/proguard/classfile/visitor/ClassCollector.java
+++ b/src/proguard/classfile/visitor/ClassCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassCounter.java b/src/proguard/classfile/visitor/ClassCounter.java
index c58c090..3c2dac7 100644
--- a/src/proguard/classfile/visitor/ClassCounter.java
+++ b/src/proguard/classfile/visitor/ClassCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java b/src/proguard/classfile/visitor/ClassForNameClassVisitor.java
deleted file mode 100644
index ee028f8..0000000
--- a/src/proguard/classfile/visitor/ClassForNameClassVisitor.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 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.visitor;
-
-import proguard.classfile.Clazz;
-import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
-
-
-/**
- * This ConstantVisitor lets a given <code>ClassVisitor</code> visit all
- * constant classes involved in any <code>Class.forName</code> constructs that
- * it visits.
- *
- * @see DotClassClassVisitor
- *
- * @author Eric Lafortune
- */
-public class ClassForNameClassVisitor
-extends SimplifiedVisitor
-implements ConstantVisitor
-{
- private final ClassVisitor classVisitor;
-
-
- /**
- * Creates a new ClassHierarchyTraveler.
- * @param classVisitor the <code>ClassVisitor</code> to which visits will
- * be delegated.
- */
- public ClassForNameClassVisitor(ClassVisitor classVisitor)
- {
- this.classVisitor = classVisitor;
- }
-
-
- // Implementations for ConstantVisitor.
-
- public void visitAnyConstant(Clazz clazz, Constant constant) {}
-
-
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
- {
- // Visit the referenced class from the Class.forName construct, if any.
- stringConstant.referencedClassAccept(classVisitor);
- }
-}
diff --git a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
index 2e1755e..116b0bf 100644
--- a/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
+++ b/src/proguard/classfile/visitor/ClassHierarchyTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassNameFilter.java b/src/proguard/classfile/visitor/ClassNameFilter.java
index c016a34..64f5a61 100644
--- a/src/proguard/classfile/visitor/ClassNameFilter.java
+++ b/src/proguard/classfile/visitor/ClassNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassPoolFiller.java b/src/proguard/classfile/visitor/ClassPoolFiller.java
index e1773de..c9efaa0 100644
--- a/src/proguard/classfile/visitor/ClassPoolFiller.java
+++ b/src/proguard/classfile/visitor/ClassPoolFiller.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassPoolVisitor.java b/src/proguard/classfile/visitor/ClassPoolVisitor.java
index 0b659dc..da2876f 100644
--- a/src/proguard/classfile/visitor/ClassPoolVisitor.java
+++ b/src/proguard/classfile/visitor/ClassPoolVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassPresenceFilter.java b/src/proguard/classfile/visitor/ClassPresenceFilter.java
index 429c340..bb90e22 100644
--- a/src/proguard/classfile/visitor/ClassPresenceFilter.java
+++ b/src/proguard/classfile/visitor/ClassPresenceFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassPrinter.java b/src/proguard/classfile/visitor/ClassPrinter.java
index 1da7d16..8d35ab7 100644
--- a/src/proguard/classfile/visitor/ClassPrinter.java
+++ b/src/proguard/classfile/visitor/ClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -48,8 +48,9 @@
ConstantVisitor,
MemberVisitor,
AttributeVisitor,
- ExceptionInfoVisitor,
+ BootstrapMethodInfoVisitor,
InnerClassesInfoVisitor,
+ ExceptionInfoVisitor,
StackMapFrameVisitor,
VerificationTypeVisitor,
LineNumberInfoVisitor,
@@ -62,7 +63,8 @@
private static final String INDENTATION = " ";
private final PrintStream ps;
- private int indentation;
+
+ private int indentation;
/**
@@ -222,10 +224,30 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ println(visitorInfo(invokeDynamicConstant) + " InvokeDynamic [bootstrap method index = " + invokeDynamicConstant.u2bootstrapMethodAttributeIndex + "]:");
+
+ indent();
+ clazz.constantPoolEntryAccept(invokeDynamicConstant.u2nameAndTypeIndex, this);
+ outdent();
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ println(visitorInfo(methodHandleConstant) + " MethodHandle [kind = " + methodHandleConstant.u1referenceKind + "]:");
+
+ indent();
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ outdent();
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
println(visitorInfo(fieldrefConstant) + " Fieldref [" +
- clazz.getClassName(fieldrefConstant.u2classIndex) + "." +
+ clazz.getClassName(fieldrefConstant.u2classIndex) + "." +
clazz.getName(fieldrefConstant.u2nameAndTypeIndex) + " " +
clazz.getType(fieldrefConstant.u2nameAndTypeIndex) + "]");
}
@@ -256,6 +278,13 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ println(visitorInfo(methodTypeConstant) + " MethodType [" +
+ clazz.getString(methodTypeConstant.u2descriptorIndex) + "]");
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
println(visitorInfo(nameAndTypeConstant) + " NameAndType [" +
@@ -361,6 +390,17 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ println(visitorInfo(bootstrapMethodsAttribute) +
+ " Bootstrap methods attribute (count = " + bootstrapMethodsAttribute.u2bootstrapMethodsCount + "):");
+
+ indent();
+ bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
+ outdent();
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
println(visitorInfo(sourceFileAttribute) +
@@ -595,6 +635,21 @@
}
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ println(visitorInfo(bootstrapMethodInfo) +
+ " BootstrapMethodInfo (argument count = " +
+ bootstrapMethodInfo.u2methodArgumentCount+ "):");
+
+ indent();
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this);
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, this);
+ outdent();
+ }
+
+
// Implementations for InnerClassesInfoVisitor.
public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
@@ -603,6 +658,8 @@
" InnerClassesInfo:");
indent();
+ println("Access flags: 0x" + Integer.toHexString(innerClassesInfo.u2innerClassAccessFlags) + " = " +
+ ClassUtil.externalClassAccessFlags(innerClassesInfo.u2innerClassAccessFlags));
innerClassesInfo.innerClassConstantAccept(clazz, this);
innerClassesInfo.outerClassConstantAccept(clazz, this);
innerClassesInfo.innerNameConstantAccept(clazz, this);
@@ -816,7 +873,7 @@
public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
{
- println("#" + localVariableInfo.u2index + ": " +
+ println("v" + localVariableInfo.u2index + ": " +
localVariableInfo.u2startPC + " -> " +
(localVariableInfo.u2startPC + localVariableInfo.u2length) + " [" +
clazz.getString(localVariableInfo.u2descriptorIndex) + " " +
@@ -828,7 +885,7 @@
public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
{
- println("#" + localVariableTypeInfo.u2index + ": " +
+ println("v" + localVariableTypeInfo.u2index + ": " +
localVariableTypeInfo.u2startPC + " -> " +
(localVariableTypeInfo.u2startPC + localVariableTypeInfo.u2length) + " [" +
clazz.getString(localVariableTypeInfo.u2signatureIndex) + " " +
diff --git a/src/proguard/classfile/visitor/ClassVersionFilter.java b/src/proguard/classfile/visitor/ClassVersionFilter.java
index 578cabf..4400ea3 100644
--- a/src/proguard/classfile/visitor/ClassVersionFilter.java
+++ b/src/proguard/classfile/visitor/ClassVersionFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -39,6 +39,19 @@
/**
* Creates a new ClassVersionFilter.
* @param minimumClassVersion the minimum class version number.
+ * @param classVisitor the <code>ClassVisitor</code> to which visits
+ * will be delegated.
+ */
+ public ClassVersionFilter(int minimumClassVersion,
+ ClassVisitor classVisitor)
+ {
+ this(minimumClassVersion, Integer.MAX_VALUE, classVisitor);
+ }
+
+
+ /**
+ * Creates a new ClassVersionFilter.
+ * @param minimumClassVersion the minimum class version number.
* @param maximumClassVersion the maximum class version number.
* @param classVisitor the <code>ClassVisitor</code> to which visits
* will be delegated.
diff --git a/src/proguard/classfile/visitor/ClassVersionSetter.java b/src/proguard/classfile/visitor/ClassVersionSetter.java
index 34dfbc1..4090d44 100644
--- a/src/proguard/classfile/visitor/ClassVersionSetter.java
+++ b/src/proguard/classfile/visitor/ClassVersionSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ClassVisitor.java b/src/proguard/classfile/visitor/ClassVisitor.java
index fdba2df..989910c 100644
--- a/src/proguard/classfile/visitor/ClassVisitor.java
+++ b/src/proguard/classfile/visitor/ClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
index ec3fe68..0c8a9bc 100644
--- a/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
+++ b/src/proguard/classfile/visitor/ConcreteClassDownTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/DotClassClassVisitor.java b/src/proguard/classfile/visitor/DotClassClassVisitor.java
index 263dbd5..8289f42 100644
--- a/src/proguard/classfile/visitor/DotClassClassVisitor.java
+++ b/src/proguard/classfile/visitor/DotClassClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -36,8 +36,6 @@
* Note that before JDK 1.5, <code>.class</code> constructs are actually
* compiled differently, using <code>Class.forName</code> constructs.
*
- * @see ClassForNameClassVisitor
- *
* @author Eric Lafortune
*/
public class DotClassClassVisitor
diff --git a/src/proguard/classfile/visitor/ExceptClassFilter.java b/src/proguard/classfile/visitor/ExceptClassFilter.java
index 924485e..c9694e6 100644
--- a/src/proguard/classfile/visitor/ExceptClassFilter.java
+++ b/src/proguard/classfile/visitor/ExceptClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptClassesFilter.java b/src/proguard/classfile/visitor/ExceptClassesFilter.java
index 7380c40..ae70ffe 100644
--- a/src/proguard/classfile/visitor/ExceptClassesFilter.java
+++ b/src/proguard/classfile/visitor/ExceptClassesFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionCounter.java b/src/proguard/classfile/visitor/ExceptionCounter.java
index c324129..e750b69 100644
--- a/src/proguard/classfile/visitor/ExceptionCounter.java
+++ b/src/proguard/classfile/visitor/ExceptionCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
index 3911e39..27e1159 100644
--- a/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionExcludedOffsetFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
index e0fdec3..c77fb83 100644
--- a/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
+++ b/src/proguard/classfile/visitor/ExceptionHandlerConstantVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
index a90fb56..74ccbe5 100644
--- a/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionHandlerFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
index e2a4fc9..d9fa3c7 100644
--- a/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionOffsetFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ExceptionRangeFilter.java b/src/proguard/classfile/visitor/ExceptionRangeFilter.java
index c541b1f..b094907 100644
--- a/src/proguard/classfile/visitor/ExceptionRangeFilter.java
+++ b/src/proguard/classfile/visitor/ExceptionRangeFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
index 6fe2e7d..574bbf1 100644
--- a/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
+++ b/src/proguard/classfile/visitor/ImplementedClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ImplementedClassFilter.java b/src/proguard/classfile/visitor/ImplementedClassFilter.java
index 955a74e..d2b5ce0 100644
--- a/src/proguard/classfile/visitor/ImplementedClassFilter.java
+++ b/src/proguard/classfile/visitor/ImplementedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
index 9e9cea3..d052916 100644
--- a/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
+++ b/src/proguard/classfile/visitor/ImplementingClassConstantFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/LibraryClassFilter.java b/src/proguard/classfile/visitor/LibraryClassFilter.java
index 0e40f2f..1d00e1d 100644
--- a/src/proguard/classfile/visitor/LibraryClassFilter.java
+++ b/src/proguard/classfile/visitor/LibraryClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/LibraryMemberFilter.java b/src/proguard/classfile/visitor/LibraryMemberFilter.java
index 0ee80e5..d006d8d 100644
--- a/src/proguard/classfile/visitor/LibraryMemberFilter.java
+++ b/src/proguard/classfile/visitor/LibraryMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberAccessFilter.java b/src/proguard/classfile/visitor/MemberAccessFilter.java
index 6fd32e3..baf5173 100644
--- a/src/proguard/classfile/visitor/MemberAccessFilter.java
+++ b/src/proguard/classfile/visitor/MemberAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberClassAccessFilter.java b/src/proguard/classfile/visitor/MemberClassAccessFilter.java
index 85272ff..0c5bfdd 100644
--- a/src/proguard/classfile/visitor/MemberClassAccessFilter.java
+++ b/src/proguard/classfile/visitor/MemberClassAccessFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberCollector.java b/src/proguard/classfile/visitor/MemberCollector.java
index ec68b2d..1373409 100644
--- a/src/proguard/classfile/visitor/MemberCollector.java
+++ b/src/proguard/classfile/visitor/MemberCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberCounter.java b/src/proguard/classfile/visitor/MemberCounter.java
index c2da72e..f6f1204 100644
--- a/src/proguard/classfile/visitor/MemberCounter.java
+++ b/src/proguard/classfile/visitor/MemberCounter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberDescriptorFilter.java b/src/proguard/classfile/visitor/MemberDescriptorFilter.java
index bd69304..81251e0 100644
--- a/src/proguard/classfile/visitor/MemberDescriptorFilter.java
+++ b/src/proguard/classfile/visitor/MemberDescriptorFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberNameFilter.java b/src/proguard/classfile/visitor/MemberNameFilter.java
index 0fe450e..f638f09 100644
--- a/src/proguard/classfile/visitor/MemberNameFilter.java
+++ b/src/proguard/classfile/visitor/MemberNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberToClassVisitor.java b/src/proguard/classfile/visitor/MemberToClassVisitor.java
index a405cfc..b5b0385 100644
--- a/src/proguard/classfile/visitor/MemberToClassVisitor.java
+++ b/src/proguard/classfile/visitor/MemberToClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MemberVisitor.java b/src/proguard/classfile/visitor/MemberVisitor.java
index 01fdf71..c0d48cb 100644
--- a/src/proguard/classfile/visitor/MemberVisitor.java
+++ b/src/proguard/classfile/visitor/MemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MethodImplementationFilter.java b/src/proguard/classfile/visitor/MethodImplementationFilter.java
index 57d923a..c4af8b0 100644
--- a/src/proguard/classfile/visitor/MethodImplementationFilter.java
+++ b/src/proguard/classfile/visitor/MethodImplementationFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MethodImplementationTraveler.java b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
index dc0ea36..d696215 100644
--- a/src/proguard/classfile/visitor/MethodImplementationTraveler.java
+++ b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
index 044d55a..a52c1d6 100644
--- a/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
+++ b/src/proguard/classfile/visitor/MultiClassPoolVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MultiClassVisitor.java b/src/proguard/classfile/visitor/MultiClassVisitor.java
index d34d91e..d8ac3d7 100644
--- a/src/proguard/classfile/visitor/MultiClassVisitor.java
+++ b/src/proguard/classfile/visitor/MultiClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/MultiMemberVisitor.java b/src/proguard/classfile/visitor/MultiMemberVisitor.java
index cc4629c..609b6a9 100644
--- a/src/proguard/classfile/visitor/MultiMemberVisitor.java
+++ b/src/proguard/classfile/visitor/MultiMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/NamedClassVisitor.java b/src/proguard/classfile/visitor/NamedClassVisitor.java
index a14d04a..a0d9fc5 100644
--- a/src/proguard/classfile/visitor/NamedClassVisitor.java
+++ b/src/proguard/classfile/visitor/NamedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/NamedFieldVisitor.java b/src/proguard/classfile/visitor/NamedFieldVisitor.java
index 76b66c6..7ccf0fe 100644
--- a/src/proguard/classfile/visitor/NamedFieldVisitor.java
+++ b/src/proguard/classfile/visitor/NamedFieldVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/NamedMethodVisitor.java b/src/proguard/classfile/visitor/NamedMethodVisitor.java
index d4611c1..3f94680 100644
--- a/src/proguard/classfile/visitor/NamedMethodVisitor.java
+++ b/src/proguard/classfile/visitor/NamedMethodVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ProgramClassFilter.java b/src/proguard/classfile/visitor/ProgramClassFilter.java
index fba3b21..98e4e15 100644
--- a/src/proguard/classfile/visitor/ProgramClassFilter.java
+++ b/src/proguard/classfile/visitor/ProgramClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ProgramMemberFilter.java b/src/proguard/classfile/visitor/ProgramMemberFilter.java
index 048a1e6..dd21cea 100644
--- a/src/proguard/classfile/visitor/ProgramMemberFilter.java
+++ b/src/proguard/classfile/visitor/ProgramMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/ReferencedClassVisitor.java b/src/proguard/classfile/visitor/ReferencedClassVisitor.java
index 986c3f9..5b4ee20 100644
--- a/src/proguard/classfile/visitor/ReferencedClassVisitor.java
+++ b/src/proguard/classfile/visitor/ReferencedClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -123,6 +123,13 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Let the visitor visit the class referenced in the reference constant.
+ invokeDynamicConstant.referencedClassesAccept(classVisitor);
+ }
+
+
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Let the visitor visit the class referenced in the class constant.
diff --git a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
index c4d34b8..762cb06 100644
--- a/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
+++ b/src/proguard/classfile/visitor/ReferencedMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/SimilarMemberVisitor.java b/src/proguard/classfile/visitor/SimilarMemberVisitor.java
index 6dc06af..9df79cb 100644
--- a/src/proguard/classfile/visitor/SimilarMemberVisitor.java
+++ b/src/proguard/classfile/visitor/SimilarMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/SimpleClassPrinter.java b/src/proguard/classfile/visitor/SimpleClassPrinter.java
index a661110..b025ebf 100644
--- a/src/proguard/classfile/visitor/SimpleClassPrinter.java
+++ b/src/proguard/classfile/visitor/SimpleClassPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/SubclassFilter.java b/src/proguard/classfile/visitor/SubclassFilter.java
index 69ea1a1..cecb0b6 100644
--- a/src/proguard/classfile/visitor/SubclassFilter.java
+++ b/src/proguard/classfile/visitor/SubclassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/SubclassTraveler.java b/src/proguard/classfile/visitor/SubclassTraveler.java
index 4170341..505510d 100644
--- a/src/proguard/classfile/visitor/SubclassTraveler.java
+++ b/src/proguard/classfile/visitor/SubclassTraveler.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/VariableClassVisitor.java b/src/proguard/classfile/visitor/VariableClassVisitor.java
index 2f575c4..b9a40f1 100644
--- a/src/proguard/classfile/visitor/VariableClassVisitor.java
+++ b/src/proguard/classfile/visitor/VariableClassVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/classfile/visitor/VariableMemberVisitor.java b/src/proguard/classfile/visitor/VariableMemberVisitor.java
index c58cff3..7b93a62 100644
--- a/src/proguard/classfile/visitor/VariableMemberVisitor.java
+++ b/src/proguard/classfile/visitor/VariableMemberVisitor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/BasicBranchUnit.java b/src/proguard/evaluation/BasicBranchUnit.java
index 3a2db76..1c01888 100644
--- a/src/proguard/evaluation/BasicBranchUnit.java
+++ b/src/proguard/evaluation/BasicBranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/BasicInvocationUnit.java b/src/proguard/evaluation/BasicInvocationUnit.java
index bccd866..33b0d0c 100644
--- a/src/proguard/evaluation/BasicInvocationUnit.java
+++ b/src/proguard/evaluation/BasicInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -162,6 +162,7 @@
break;
case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
isStatic = true;
break;
@@ -230,6 +231,31 @@
}
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ String type = invokeDynamicConstant.getType(clazz);
+
+ // Count the number of parameters.
+ int parameterCount = ClassUtil.internalMethodParameterCount(type);
+ if (!isStatic)
+ {
+ parameterCount++;
+ }
+
+ // Pop the parameters and the class reference, in reverse order.
+ for (int parameterIndex = parameterCount-1; parameterIndex >= 0; parameterIndex--)
+ {
+ stack.pop();
+ }
+
+ // Push the return value, if applicable.
+ String returnType = ClassUtil.internalMethodReturnType(type);
+ if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
+ {
+ stack.push(getMethodReturnValue(clazz, invokeDynamicConstant, returnType));
+ }
+ }
+
/**
* Sets the class through which the specified field is accessed.
@@ -340,6 +366,25 @@
}
+ /**
+ * Returns the return value of the specified method.
+ */
+ protected Value getMethodReturnValue(Clazz clazz,
+ InvokeDynamicConstant invokeDynamicConstant,
+ String type)
+ {
+ // Try to figure out the class of the return type.
+ Clazz[] referencedClasses = invokeDynamicConstant.referencedClasses;
+
+ Clazz returnTypeClass = referencedClasses == null ? null :
+ referencedClasses[referencedClasses.length - 1];
+
+ return valueFactory.createValue(type,
+ returnTypeClass,
+ true);
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
diff --git a/src/proguard/evaluation/BranchUnit.java b/src/proguard/evaluation/BranchUnit.java
index b709807..1493b6f 100644
--- a/src/proguard/evaluation/BranchUnit.java
+++ b/src/proguard/evaluation/BranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/ClassConstantValueFactory.java b/src/proguard/evaluation/ClassConstantValueFactory.java
new file mode 100644
index 0000000..8214eea
--- /dev/null
+++ b/src/proguard/evaluation/ClassConstantValueFactory.java
@@ -0,0 +1,53 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.evaluation;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.evaluation.value.*;
+
+/**
+ * This class creates java.lang.Class ReferenceValue instances that correspond
+ * to specified constant pool entries.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassConstantValueFactory
+extends ConstantValueFactory
+{
+ public ClassConstantValueFactory(ValueFactory valueFactory)
+ {
+ super(valueFactory);
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Create a Class reference instead of a reference to the class.
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
+ classConstant.javaLangClassClass,
+ false);
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/evaluation/ConstantValueFactory.java b/src/proguard/evaluation/ConstantValueFactory.java
new file mode 100644
index 0000000..e76b869
--- /dev/null
+++ b/src/proguard/evaluation/ConstantValueFactory.java
@@ -0,0 +1,113 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.evaluation;
+
+import proguard.classfile.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.evaluation.value.*;
+
+/**
+ * This class creates Value instance that correspond to specified constant pool
+ * entries.
+ *
+ * @author Eric Lafortune
+ */
+public class ConstantValueFactory
+extends SimplifiedVisitor
+implements ConstantVisitor
+{
+ protected final ValueFactory valueFactory;
+
+ // Field acting as a parameter for the ConstantVisitor methods.
+ protected Value value;
+
+
+ public ConstantValueFactory(ValueFactory valueFactory)
+ {
+ this.valueFactory = valueFactory;
+ }
+
+
+ /**
+ * Returns the Value of the constant pool element at the given index.
+ */
+ public Value constantValue(Clazz clazz,
+ int constantIndex)
+ {
+ // Visit the constant pool entry to get its return value.
+ clazz.constantPoolEntryAccept(constantIndex, this);
+
+ return value;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
+ {
+ value = valueFactory.createIntegerValue(integerConstant.getValue());
+ }
+
+ public void visitLongConstant(Clazz clazz, LongConstant longConstant)
+ {
+ value = valueFactory.createLongValue(longConstant.getValue());
+ }
+
+ public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
+ {
+ value = valueFactory.createFloatValue(floatConstant.getValue());
+ }
+
+ public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
+ {
+ value = valueFactory.createDoubleValue(doubleConstant.getValue());
+ }
+
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
+ stringConstant.javaLangStringClass,
+ false);
+ }
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE,
+ methodHandleConstant.javaLangInvokeMethodHandleClass,
+ false);
+ }
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ value = valueFactory.createReferenceValue(classConstant.getName(clazz),
+ classConstant.referencedClass,
+ false);
+ }
+
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE,
+ methodTypeConstant.javaLangInvokeMethodTypeClass,
+ false);
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/evaluation/InvocationUnit.java b/src/proguard/evaluation/InvocationUnit.java
index cb4d3c5..a8809ee 100644
--- a/src/proguard/evaluation/InvocationUnit.java
+++ b/src/proguard/evaluation/InvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/Processor.java b/src/proguard/evaluation/Processor.java
index 74afd0b..b694d66 100644
--- a/src/proguard/evaluation/Processor.java
+++ b/src/proguard/evaluation/Processor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,11 +22,8 @@
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
import proguard.evaluation.value.*;
/**
@@ -36,9 +33,7 @@
* @author Eric Lafortune
*/
public class Processor
-extends SimplifiedVisitor
-implements InstructionVisitor,
- ConstantVisitor
+implements InstructionVisitor
{
private final Variables variables;
private final Stack stack;
@@ -46,9 +41,8 @@
private final BranchUnit branchUnit;
private final InvocationUnit invocationUnit;
- // Fields acting as parameters for the ConstantVisitor methods.
- private boolean handleClassConstantAsClassValue;
- private Value cpValue;
+ private final ConstantValueFactory constantValueFactory;
+ private final ClassConstantValueFactory classConstantValueFactory;
/**
@@ -69,6 +63,9 @@
this.valueFactory = valueFactory;
this.branchUnit = branchUnit;
this.invocationUnit = invocationUnit;
+
+ constantValueFactory = new ConstantValueFactory(valueFactory);
+ classConstantValueFactory = new ClassConstantValueFactory(valueFactory);
}
@@ -561,7 +558,7 @@
case InstructionConstants.OP_LDC:
case InstructionConstants.OP_LDC_W:
case InstructionConstants.OP_LDC2_W:
- stack.push(cpValue(clazz, constantIndex, true));
+ stack.push(classConstantValueFactory.constantValue(clazz, constantIndex));
break;
case InstructionConstants.OP_GETSTATIC:
@@ -572,16 +569,17 @@
case InstructionConstants.OP_INVOKESPECIAL:
case InstructionConstants.OP_INVOKESTATIC:
case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
invocationUnit.invokeMember(clazz, method, codeAttribute, offset, constantInstruction, stack);
break;
case InstructionConstants.OP_NEW:
- stack.push(cpValue(clazz, constantIndex).referenceValue());
+ stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
case InstructionConstants.OP_ANEWARRAY:
{
- ReferenceValue referenceValue = cpValue(clazz, constantIndex).referenceValue();
+ ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
stack.push(valueFactory.createArrayReferenceValue(referenceValue.internalType(),
referenceValue.getReferencedClass(),
@@ -594,14 +592,14 @@
ReferenceValue castValue = stack.apop();
ReferenceValue castResultValue =
castValue.isNull() == Value.ALWAYS ? castValue :
- castValue.isNull() == Value.NEVER ? cpValue(clazz, constantIndex).referenceValue() :
- cpValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
+ castValue.isNull() == Value.NEVER ? constantValueFactory.constantValue(clazz, constantIndex).referenceValue() :
+ constantValueFactory.constantValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
stack.push(castResultValue);
break;
case InstructionConstants.OP_INSTANCEOF:
{
- ReferenceValue referenceValue = cpValue(clazz, constantIndex).referenceValue();
+ ReferenceValue referenceValue = constantValueFactory.constantValue(clazz, constantIndex).referenceValue();
int instanceOf = stack.apop().instanceOf(referenceValue.getType(),
referenceValue.getReferencedClass());
@@ -621,7 +619,7 @@
IntegerValue arrayLength = stack.ipop();
}
- stack.push(cpValue(clazz, constantIndex).referenceValue());
+ stack.push(constantValueFactory.constantValue(clazz, constantIndex).referenceValue());
break;
}
@@ -907,73 +905,4 @@
}
}
}
-
-
- // Implementations for ConstantVisitor.
-
- public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
- {
- cpValue = valueFactory.createIntegerValue(integerConstant.getValue());
- }
-
- public void visitLongConstant(Clazz clazz, LongConstant longConstant)
- {
- cpValue = valueFactory.createLongValue(longConstant.getValue());
- }
-
- public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
- {
- cpValue = valueFactory.createFloatValue(floatConstant.getValue());
- }
-
- public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
- {
- cpValue = valueFactory.createDoubleValue(doubleConstant.getValue());
- }
-
- public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
- {
- cpValue = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
- stringConstant.javaLangStringClass,
- false);
- }
-
- public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
- {
- cpValue = handleClassConstantAsClassValue ?
- valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
- classConstant.javaLangClassClass,
- false) :
- valueFactory.createReferenceValue(classConstant.getName(clazz),
- classConstant.referencedClass,
- false);
- }
-
-
- // Small utility methods.
-
- /**
- * Returns the Value of the constant pool element at the given index.
- */
- private Value cpValue(Clazz clazz,
- int constantIndex)
- {
- return cpValue(clazz, constantIndex, false);
- }
-
-
- /**
- * Returns the Value of the constant pool element at the given index.
- */
- private Value cpValue(Clazz clazz,
- int constantIndex,
- boolean handleClassConstantAsClassValue)
- {
- this.handleClassConstantAsClassValue = handleClassConstantAsClassValue;
-
- // Visit the constant pool entry to get its return value.
- clazz.constantPoolEntryAccept(constantIndex, this);
-
- return cpValue;
- }
}
diff --git a/src/proguard/evaluation/Stack.java b/src/proguard/evaluation/Stack.java
index 2808e62..46c1b40 100644
--- a/src/proguard/evaluation/Stack.java
+++ b/src/proguard/evaluation/Stack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,6 +22,8 @@
import proguard.evaluation.value.*;
+import java.util.Arrays;
+
/**
* This class represents an operand stack that contains <code>Value</code>
* objects.
@@ -163,10 +165,7 @@
public void clear()
{
// Clear the stack contents.
- for (int index = 0; index < currentSize; index++)
- {
- values[index] = null;
- }
+ Arrays.fill(values, 0, currentSize, null);
currentSize = 0;
}
diff --git a/src/proguard/evaluation/TracedStack.java b/src/proguard/evaluation/TracedStack.java
index c24f783..3c3def4 100644
--- a/src/proguard/evaluation/TracedStack.java
+++ b/src/proguard/evaluation/TracedStack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/TracedVariables.java b/src/proguard/evaluation/TracedVariables.java
index 1ae6ba6..5f58f97 100644
--- a/src/proguard/evaluation/TracedVariables.java
+++ b/src/proguard/evaluation/TracedVariables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -30,9 +30,6 @@
* stores. It then generalizes a given collected Value with the producer Value
* of each Value it loads. The producer Value and the initial collected Value
* can be set; the generalized collected Value can be retrieved.
- * <p>
- * In addition, an initialization index can be reset and retrieved, pointing
- * to the most recent variable that has been initialized by a store operation.
*
* @author Eric Lafortune
*/
@@ -43,7 +40,6 @@
private Value producerValue;
private Variables producerVariables;
- private int initializationIndex;
/**
@@ -78,24 +74,6 @@
/**
- * Resets the initialization index.
- */
- public void resetInitialization()
- {
- initializationIndex = NONE;
- }
-
-
- /**
- * Returns the most recent initialization index since it has been reset.
- */
- public int getInitializationIndex()
- {
- return initializationIndex;
- }
-
-
- /**
* Gets the producer Value for the specified variable, without disturbing it.
* @param index the variable index.
* @return the producer value of the given variable.
@@ -164,14 +142,6 @@
public void store(int index, Value value)
{
- // Is this store operation an initialization of the variable?
- Value previousValue = super.load(index);
- if (previousValue == null ||
- previousValue.computationalType() != value.computationalType())
- {
- initializationIndex = index;
- }
-
// Store the value itself in the variable.
super.store(index, value);
diff --git a/src/proguard/evaluation/Variables.java b/src/proguard/evaluation/Variables.java
index 4496aaa..0cf2584 100644
--- a/src/proguard/evaluation/Variables.java
+++ b/src/proguard/evaluation/Variables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,6 +22,8 @@
import proguard.evaluation.value.*;
+import java.util.Arrays;
+
/**
* This class represents a local variable frame that contains <code>Value</code>
* objects. Values are generalizations of all values that have been stored in
@@ -75,10 +77,7 @@
else
{
// Clear the variables.
- for (int index = 0; index < values.length; index++)
- {
- values[index] = null;
- }
+ Arrays.fill(values, null);
}
this.size = size;
diff --git a/src/proguard/evaluation/value/Category1Value.java b/src/proguard/evaluation/value/Category1Value.java
index b8c5db2..0d5650b 100644
--- a/src/proguard/evaluation/value/Category1Value.java
+++ b/src/proguard/evaluation/value/Category1Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/Category2Value.java b/src/proguard/evaluation/value/Category2Value.java
index 65916c7..dde0625 100644
--- a/src/proguard/evaluation/value/Category2Value.java
+++ b/src/proguard/evaluation/value/Category2Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ComparisonValue.java b/src/proguard/evaluation/value/ComparisonValue.java
index e4e2e02..55c942c 100644
--- a/src/proguard/evaluation/value/ComparisonValue.java
+++ b/src/proguard/evaluation/value/ComparisonValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -35,11 +35,11 @@
/**
* Creates a new comparison integer value of the two given scalar values.
*/
- public ComparisonValue(Value integerValue1,
- Value integerValue2)
+ public ComparisonValue(Value value1,
+ Value value2)
{
- this.value1 = integerValue1;
- this.value2 = integerValue2;
+ this.value1 = value1;
+ this.value2 = value2;
}
diff --git a/src/proguard/evaluation/value/CompositeDoubleValue.java b/src/proguard/evaluation/value/CompositeDoubleValue.java
index a6d48ef..d183dee 100644
--- a/src/proguard/evaluation/value/CompositeDoubleValue.java
+++ b/src/proguard/evaluation/value/CompositeDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/CompositeFloatValue.java b/src/proguard/evaluation/value/CompositeFloatValue.java
index 4df890a..ecc32bb 100644
--- a/src/proguard/evaluation/value/CompositeFloatValue.java
+++ b/src/proguard/evaluation/value/CompositeFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -36,7 +36,7 @@
private final FloatValue floatValue1;
- private final byte operation;
+ private final byte operation;
private final FloatValue floatValue2;
@@ -45,11 +45,11 @@
* and the given operation.
*/
public CompositeFloatValue(FloatValue floatValue1,
- byte operation,
- FloatValue floatValue2)
+ byte operation,
+ FloatValue floatValue2)
{
this.floatValue1 = floatValue1;
- this.operation = operation;
+ this.operation = operation;
this.floatValue2 = floatValue2;
}
diff --git a/src/proguard/evaluation/value/CompositeIntegerValue.java b/src/proguard/evaluation/value/CompositeIntegerValue.java
index 6d4f59c..a042fcf 100644
--- a/src/proguard/evaluation/value/CompositeIntegerValue.java
+++ b/src/proguard/evaluation/value/CompositeIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/CompositeLongValue.java b/src/proguard/evaluation/value/CompositeLongValue.java
index 7f63211..d4fa331 100644
--- a/src/proguard/evaluation/value/CompositeLongValue.java
+++ b/src/proguard/evaluation/value/CompositeLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedByteValue.java b/src/proguard/evaluation/value/ConvertedByteValue.java
index 7ab5d0a..115e7d1 100644
--- a/src/proguard/evaluation/value/ConvertedByteValue.java
+++ b/src/proguard/evaluation/value/ConvertedByteValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedCharacterValue.java b/src/proguard/evaluation/value/ConvertedCharacterValue.java
index 76568d1..88e0e25 100644
--- a/src/proguard/evaluation/value/ConvertedCharacterValue.java
+++ b/src/proguard/evaluation/value/ConvertedCharacterValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedDoubleValue.java b/src/proguard/evaluation/value/ConvertedDoubleValue.java
index a6afe34..943e2a5 100644
--- a/src/proguard/evaluation/value/ConvertedDoubleValue.java
+++ b/src/proguard/evaluation/value/ConvertedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedFloatValue.java b/src/proguard/evaluation/value/ConvertedFloatValue.java
index 33683b7..df4994d 100644
--- a/src/proguard/evaluation/value/ConvertedFloatValue.java
+++ b/src/proguard/evaluation/value/ConvertedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedIntegerValue.java b/src/proguard/evaluation/value/ConvertedIntegerValue.java
index aecb533..23ec03f 100644
--- a/src/proguard/evaluation/value/ConvertedIntegerValue.java
+++ b/src/proguard/evaluation/value/ConvertedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedLongValue.java b/src/proguard/evaluation/value/ConvertedLongValue.java
index ec97008..026bd5b 100644
--- a/src/proguard/evaluation/value/ConvertedLongValue.java
+++ b/src/proguard/evaluation/value/ConvertedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ConvertedShortValue.java b/src/proguard/evaluation/value/ConvertedShortValue.java
index ab79b49..c209d44 100644
--- a/src/proguard/evaluation/value/ConvertedShortValue.java
+++ b/src/proguard/evaluation/value/ConvertedShortValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/DoubleValue.java b/src/proguard/evaluation/value/DoubleValue.java
index e39ee5c..48d8f11 100644
--- a/src/proguard/evaluation/value/DoubleValue.java
+++ b/src/proguard/evaluation/value/DoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -342,11 +342,6 @@
return this;
}
- public Value refresh()
- {
- return this;
- }
-
public final Value generalize(Value other)
{
return this.generalize(other.doubleValue());
diff --git a/src/proguard/evaluation/value/FloatValue.java b/src/proguard/evaluation/value/FloatValue.java
index b30e395..3783096 100644
--- a/src/proguard/evaluation/value/FloatValue.java
+++ b/src/proguard/evaluation/value/FloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IdentifiedDoubleValue.java b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
index 4009c6e..86393a7 100644
--- a/src/proguard/evaluation/value/IdentifiedDoubleValue.java
+++ b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IdentifiedFloatValue.java b/src/proguard/evaluation/value/IdentifiedFloatValue.java
index 87bed64..363530b 100644
--- a/src/proguard/evaluation/value/IdentifiedFloatValue.java
+++ b/src/proguard/evaluation/value/IdentifiedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IdentifiedIntegerValue.java b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
index 66e88ee..57e73cb 100644
--- a/src/proguard/evaluation/value/IdentifiedIntegerValue.java
+++ b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IdentifiedLongValue.java b/src/proguard/evaluation/value/IdentifiedLongValue.java
index eea1816..a0c4636 100644
--- a/src/proguard/evaluation/value/IdentifiedLongValue.java
+++ b/src/proguard/evaluation/value/IdentifiedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IdentifiedReferenceValue.java b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
index cb5efc1..1514d4d 100644
--- a/src/proguard/evaluation/value/IdentifiedReferenceValue.java
+++ b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -57,6 +57,17 @@
}
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ // Remove the ID if both values don't share the same ID.
+ return this.equals(other) ?
+ this :
+ new ReferenceValue(type, referencedClass, mayBeNull).generalize(other);
+ }
+
+
// Implementations for Value.
public boolean isSpecific()
diff --git a/src/proguard/evaluation/value/IdentifiedValueFactory.java b/src/proguard/evaluation/value/IdentifiedValueFactory.java
index 2b14e72..f2a3cab 100644
--- a/src/proguard/evaluation/value/IdentifiedValueFactory.java
+++ b/src/proguard/evaluation/value/IdentifiedValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/InstructionOffsetValue.java b/src/proguard/evaluation/value/InstructionOffsetValue.java
index 10b5a6f..93d0380 100644
--- a/src/proguard/evaluation/value/InstructionOffsetValue.java
+++ b/src/proguard/evaluation/value/InstructionOffsetValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/IntegerValue.java b/src/proguard/evaluation/value/IntegerValue.java
index 508c5f5..6a0775d 100644
--- a/src/proguard/evaluation/value/IntegerValue.java
+++ b/src/proguard/evaluation/value/IntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/LongValue.java b/src/proguard/evaluation/value/LongValue.java
index f7ba162..1d8f413 100644
--- a/src/proguard/evaluation/value/LongValue.java
+++ b/src/proguard/evaluation/value/LongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/NegatedDoubleValue.java b/src/proguard/evaluation/value/NegatedDoubleValue.java
index 2bc9423..6409f8c 100644
--- a/src/proguard/evaluation/value/NegatedDoubleValue.java
+++ b/src/proguard/evaluation/value/NegatedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/NegatedFloatValue.java b/src/proguard/evaluation/value/NegatedFloatValue.java
index 0ddf4ab..f0f7e40 100644
--- a/src/proguard/evaluation/value/NegatedFloatValue.java
+++ b/src/proguard/evaluation/value/NegatedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/NegatedIntegerValue.java b/src/proguard/evaluation/value/NegatedIntegerValue.java
index a89a2d9..74b857c 100644
--- a/src/proguard/evaluation/value/NegatedIntegerValue.java
+++ b/src/proguard/evaluation/value/NegatedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/NegatedLongValue.java b/src/proguard/evaluation/value/NegatedLongValue.java
index c3b22bb..3f97fd0 100644
--- a/src/proguard/evaluation/value/NegatedLongValue.java
+++ b/src/proguard/evaluation/value/NegatedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ParticularDoubleValue.java b/src/proguard/evaluation/value/ParticularDoubleValue.java
index 05bc559..383cae3 100644
--- a/src/proguard/evaluation/value/ParticularDoubleValue.java
+++ b/src/proguard/evaluation/value/ParticularDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -79,17 +79,23 @@
public DoubleValue add(DoubleValue other)
{
- return value == 0.0 ? other : other.add(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.add(this);
+ return other.add(this);
}
public DoubleValue subtract(DoubleValue other)
{
- return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ return other.subtractFrom(this);
}
public DoubleValue subtractFrom(DoubleValue other)
{
- return value == 0.0 ? other : other.subtract(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.subtract(this);
+ return other.subtract(this);
}
public DoubleValue multiply(DoubleValue other)
diff --git a/src/proguard/evaluation/value/ParticularFloatValue.java b/src/proguard/evaluation/value/ParticularFloatValue.java
index 59e4357..335765c 100644
--- a/src/proguard/evaluation/value/ParticularFloatValue.java
+++ b/src/proguard/evaluation/value/ParticularFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -79,17 +79,23 @@
public FloatValue add(FloatValue other)
{
- return value == 0.0 ? other : other.add(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.add(this);
+ return other.add(this);
}
public FloatValue subtract(FloatValue other)
{
- return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other.negate() : other.subtractFrom(this);
+ return other.subtractFrom(this);
}
public FloatValue subtractFrom(FloatValue other)
{
- return value == 0.0 ? other : other.subtract(this);
+ // Careful: -0.0 + 0.0 == 0.0
+ //return value == 0.0 ? other : other.subtract(this);
+ return other.subtract(this);
}
public FloatValue multiply(FloatValue other)
diff --git a/src/proguard/evaluation/value/ParticularIntegerValue.java b/src/proguard/evaluation/value/ParticularIntegerValue.java
index 8a4ac1d..d6906e7 100644
--- a/src/proguard/evaluation/value/ParticularIntegerValue.java
+++ b/src/proguard/evaluation/value/ParticularIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ParticularLongValue.java b/src/proguard/evaluation/value/ParticularLongValue.java
index 61d2e04..22d9d1a 100644
--- a/src/proguard/evaluation/value/ParticularLongValue.java
+++ b/src/proguard/evaluation/value/ParticularLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ReferenceValue.java b/src/proguard/evaluation/value/ReferenceValue.java
index 418c6f8..084a1a4 100644
--- a/src/proguard/evaluation/value/ReferenceValue.java
+++ b/src/proguard/evaluation/value/ReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -280,11 +280,25 @@
thisReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(thisSuperClasses));
+ int thisSuperClassesCount = thisSuperClasses.size();
+ if (thisSuperClassesCount == 0 &&
+ thisReferencedClass.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+thisType+"] (not even immediate super class ["+thisReferencedClass.getSuperName()+"])");
+ }
+
// Collect the superclasses and interfaces of the other class.
Set otherSuperClasses = new HashSet();
otherReferencedClass.hierarchyAccept(false, true, true, false,
new ClassCollector(otherSuperClasses));
+ int otherSuperClassesCount = otherSuperClasses.size();
+ if (otherSuperClassesCount == 0 &&
+ otherReferencedClass.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+otherType+"] (not even immediate super class ["+otherReferencedClass.getSuperName()+"])");
+ }
+
if (DEBUG)
{
System.out.println("ReferenceValue.generalize this ["+thisReferencedClass.getName()+"] with other ["+otherReferencedClass.getName()+"]");
@@ -302,7 +316,7 @@
// Find a class that is a subclass of all common superclasses,
// or that at least has the maximum number of common superclasses.
- Clazz commonClazz = null;
+ Clazz commonClass = null;
int maximumSuperClassCount = -1;
@@ -317,31 +331,33 @@
int superClassCount = superClassCount(commonSuperClass, thisSuperClasses);
if (maximumSuperClassCount < superClassCount ||
(maximumSuperClassCount == superClassCount &&
- commonClazz != null &&
- commonClazz.getName().compareTo(commonSuperClass.getName()) > 0))
+ commonClass != null &&
+ commonClass.getName().compareTo(commonSuperClass.getName()) > 0))
{
- commonClazz = commonSuperClass;
+ commonClass = commonSuperClass;
maximumSuperClassCount = superClassCount;
}
}
- if (commonClazz == null)
+ if (commonClass == null)
{
- throw new IllegalArgumentException("Can't find common super class of ["+thisType+"] and ["+otherType+"]");
+ throw new IllegalArgumentException("Can't find common super class of ["+
+ thisType +"] (with "+thisSuperClassesCount +" known super classes) and ["+
+ otherType+"] (with "+otherSuperClassesCount+" known super classes)");
}
if (DEBUG)
{
- System.out.println(" Best common class: ["+commonClazz.getName()+"]");
+ System.out.println(" Best common class: ["+commonClass.getName()+"]");
}
// TODO: Handle more difficult cases, with multiple global subclasses.
return new ReferenceValue(commonDimensionCount == 0 ?
- commonClazz.getName() :
- ClassUtil.internalArrayTypeFromClassName(commonClazz.getName(),
+ commonClass.getName() :
+ ClassUtil.internalArrayTypeFromClassName(commonClass.getName(),
commonDimensionCount),
- commonClazz,
+ commonClass,
mayBeNull);
}
}
@@ -402,8 +418,6 @@
}
}
- //System.out.println("ReferenceValue.superClassCount: ["+subClass.getName()+"]: "+count);
-
return count;
}
diff --git a/src/proguard/evaluation/value/SpecificDoubleValue.java b/src/proguard/evaluation/value/SpecificDoubleValue.java
index 572d891..ea4ecc4 100644
--- a/src/proguard/evaluation/value/SpecificDoubleValue.java
+++ b/src/proguard/evaluation/value/SpecificDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -153,9 +153,12 @@
public IntegerValue compare(SpecificDoubleValue other)
{
- return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
- new ComparisonValue(this, other);
+ return ValueFactory.INTEGER_VALUE;
+
+ // Not handling NaN properly.
+ //return this.equals(other) ?
+ // SpecificValueFactory.INTEGER_VALUE_0 :
+ // new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificFloatValue.java b/src/proguard/evaluation/value/SpecificFloatValue.java
index 3bc3679..1e55c23 100644
--- a/src/proguard/evaluation/value/SpecificFloatValue.java
+++ b/src/proguard/evaluation/value/SpecificFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -153,9 +153,12 @@
public IntegerValue compare(SpecificFloatValue other)
{
- return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
- new ComparisonValue(this, other);
+ return ValueFactory.INTEGER_VALUE;
+
+ // Not handling NaN properly.
+ //return this.equals(other) ?
+ // SpecificValueFactory.INTEGER_VALUE_0 :
+ // new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificIntegerValue.java b/src/proguard/evaluation/value/SpecificIntegerValue.java
index 57c48b1..45eb013 100644
--- a/src/proguard/evaluation/value/SpecificIntegerValue.java
+++ b/src/proguard/evaluation/value/SpecificIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/SpecificLongValue.java b/src/proguard/evaluation/value/SpecificLongValue.java
index 5e12bde..32302a4 100644
--- a/src/proguard/evaluation/value/SpecificLongValue.java
+++ b/src/proguard/evaluation/value/SpecificLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/SpecificValueFactory.java b/src/proguard/evaluation/value/SpecificValueFactory.java
index 72dd1d3..145ff55 100644
--- a/src/proguard/evaluation/value/SpecificValueFactory.java
+++ b/src/proguard/evaluation/value/SpecificValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -45,6 +45,10 @@
static final DoubleValue DOUBLE_VALUE_1 = new ParticularDoubleValue(1.0);
+ private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
+ private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);
+
+
// Implementations for ValueFactory.
public IntegerValue createIntegerValue(int value)
@@ -73,7 +77,9 @@
public FloatValue createFloatValue(float value)
{
- return value == 0.0f ? FLOAT_VALUE_0 :
+ // Make sure to distinguish between +0.0 and -0.0.
+ return value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS
+ ? FLOAT_VALUE_0 :
value == 1.0f ? FLOAT_VALUE_1 :
value == 2.0f ? FLOAT_VALUE_2 :
new ParticularFloatValue(value);
@@ -82,7 +88,9 @@
public DoubleValue createDoubleValue(double value)
{
- return value == 0.0 ? DOUBLE_VALUE_0 :
+ // Make sure to distinguish between +0.0 and -0.0.
+ return value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS
+ ? DOUBLE_VALUE_0 :
value == 1.0 ? DOUBLE_VALUE_1 :
new ParticularDoubleValue(value);
}
diff --git a/src/proguard/evaluation/value/TopValue.java b/src/proguard/evaluation/value/TopValue.java
index 048a1ff..ecd182e 100644
--- a/src/proguard/evaluation/value/TopValue.java
+++ b/src/proguard/evaluation/value/TopValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/UnknownDoubleValue.java b/src/proguard/evaluation/value/UnknownDoubleValue.java
index 79cc4de..96bf06a 100644
--- a/src/proguard/evaluation/value/UnknownDoubleValue.java
+++ b/src/proguard/evaluation/value/UnknownDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/UnknownFloatValue.java b/src/proguard/evaluation/value/UnknownFloatValue.java
index 3f9622a..14469f8 100644
--- a/src/proguard/evaluation/value/UnknownFloatValue.java
+++ b/src/proguard/evaluation/value/UnknownFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/UnknownIntegerValue.java b/src/proguard/evaluation/value/UnknownIntegerValue.java
index be5e79d..94fcf60 100644
--- a/src/proguard/evaluation/value/UnknownIntegerValue.java
+++ b/src/proguard/evaluation/value/UnknownIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/UnknownLongValue.java b/src/proguard/evaluation/value/UnknownLongValue.java
index 83a75dc..f183447 100644
--- a/src/proguard/evaluation/value/UnknownLongValue.java
+++ b/src/proguard/evaluation/value/UnknownLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/Value.java b/src/proguard/evaluation/value/Value.java
index e24ece1..b4f1c6a 100644
--- a/src/proguard/evaluation/value/Value.java
+++ b/src/proguard/evaluation/value/Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/evaluation/value/ValueFactory.java b/src/proguard/evaluation/value/ValueFactory.java
index 8415381..2b9e7f1 100644
--- a/src/proguard/evaluation/value/ValueFactory.java
+++ b/src/proguard/evaluation/value/ValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/ClassPathPanel.java b/src/proguard/gui/ClassPathPanel.java
index 95f3d1b..6fa6154 100644
--- a/src/proguard/gui/ClassPathPanel.java
+++ b/src/proguard/gui/ClassPathPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,7 +26,7 @@
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
-import java.io.File;
+import java.io.*;
import java.util.List;
/**
@@ -141,7 +141,7 @@
// Up to JDK 1.3.1, setSelectedFiles doesn't show in the file
// chooser, so we just use setSelectedFile first. It also sets
// the current directory.
- chooser.setSelectedFile(selectedFiles[0]);
+ chooser.setSelectedFile(selectedFiles[0].getAbsoluteFile());
chooser.setSelectedFiles(selectedFiles);
int returnValue = chooser.showOpenDialog(owner);
@@ -432,7 +432,7 @@
filter = new StringBuffer().append('(');
}
- filter.append(ListUtil.commaSeparatedString(additionalFilter));
+ filter.append(ListUtil.commaSeparatedString(additionalFilter, true));
}
return filter;
diff --git a/src/proguard/gui/ClassSpecificationDialog.java b/src/proguard/gui/ClassSpecificationDialog.java
index 36d80d4..a9493c9 100644
--- a/src/proguard/gui/ClassSpecificationDialog.java
+++ b/src/proguard/gui/ClassSpecificationDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -63,9 +63,10 @@
private final JRadioButton[] publicRadioButtons;
private final JRadioButton[] finalRadioButtons;
private final JRadioButton[] abstractRadioButtons;
- private final JRadioButton[] enumRadioButtons;
- private final JRadioButton[] annotationRadioButtons;
private final JRadioButton[] interfaceRadioButtons;
+ private final JRadioButton[] annotationRadioButtons;
+ private final JRadioButton[] enumRadioButtons;
+ private final JRadioButton[] syntheticRadioButtons;
private final JTextField annotationTypeTextField = new JTextField(20);
private final JTextField classNameTextField = new JTextField(20);
@@ -199,9 +200,10 @@
publicRadioButtons = addRadioButtonTriplet("Public", accessPanel);
finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
- enumRadioButtons = addRadioButtonTriplet("Enum", accessPanel);
- annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
interfaceRadioButtons = addRadioButtonTriplet("Interface", accessPanel);
+ annotationRadioButtons = addRadioButtonTriplet("Annotation", accessPanel);
+ enumRadioButtons = addRadioButtonTriplet("Enum", accessPanel);
+ syntheticRadioButtons = addRadioButtonTriplet("Synthetic", accessPanel);
// Create the annotation type panel.
final JPanel annotationTypePanel = new JPanel(layout);
@@ -393,9 +395,10 @@
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
- setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
- setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
+ setClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Set the class and annotation text fields.
annotationTypeTextField .setText(annotationType == null ? "" : ClassUtil.externalType(annotationType));
@@ -453,9 +456,10 @@
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_PUBLIC, publicRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
- getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
- getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_INTERFACE, interfaceRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ANNOTATTION, annotationRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_ENUM, enumRadioButtons);
+ getClassSpecificationRadioButtons(classSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
// Get the keep class member option lists.
classSpecification.fieldSpecifications = memberSpecificationsPanel.getMemberSpecifications(true);
diff --git a/src/proguard/gui/ClassSpecificationsPanel.java b/src/proguard/gui/ClassSpecificationsPanel.java
index 2cf0b1d..50fd87b 100644
--- a/src/proguard/gui/ClassSpecificationsPanel.java
+++ b/src/proguard/gui/ClassSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/ExtensionFileFilter.java b/src/proguard/gui/ExtensionFileFilter.java
index d67be40..581e889 100644
--- a/src/proguard/gui/ExtensionFileFilter.java
+++ b/src/proguard/gui/ExtensionFileFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/FilterBuilder.java b/src/proguard/gui/FilterBuilder.java
index e46193f..33a8527 100644
--- a/src/proguard/gui/FilterBuilder.java
+++ b/src/proguard/gui/FilterBuilder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/FilterDialog.java b/src/proguard/gui/FilterDialog.java
index 1567a31..e65620a 100644
--- a/src/proguard/gui/FilterDialog.java
+++ b/src/proguard/gui/FilterDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -182,7 +182,7 @@
*/
public void setFilter(List filter)
{
- filterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_FILTER);
+ filterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_FILTER);
}
@@ -202,7 +202,7 @@
*/
public void setJarFilter(List filter)
{
- jarFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_JAR_FILTER);
+ jarFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_JAR_FILTER);
}
@@ -222,7 +222,7 @@
*/
public void setWarFilter(List filter)
{
- warFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_WAR_FILTER);
+ warFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_WAR_FILTER);
}
@@ -242,7 +242,7 @@
*/
public void setEarFilter(List filter)
{
- earFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_EAR_FILTER);
+ earFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_EAR_FILTER);
}
@@ -262,7 +262,7 @@
*/
public void setZipFilter(List filter)
{
- zipFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter) : DEFAULT_ZIP_FILTER);
+ zipFilterTextField.setText(filter != null ? ListUtil.commaSeparatedString(filter, true) : DEFAULT_ZIP_FILTER);
}
diff --git a/src/proguard/gui/GUIResources.java b/src/proguard/gui/GUIResources.java
index 85d582c..b190119 100644
--- a/src/proguard/gui/GUIResources.java
+++ b/src/proguard/gui/GUIResources.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/GUIResources.properties b/src/proguard/gui/GUIResources.properties
index 86ab7a1..705079e 100644
--- a/src/proguard/gui/GUIResources.properties
+++ b/src/proguard/gui/GUIResources.properties
@@ -1,5 +1,5 @@
# ProGuard -- shrinking, optimization, and obfuscation of Java class files.
-# Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+# Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
#
# Tab names.
@@ -25,7 +25,7 @@
#
# Panel titles.
#
-welcome = Welcome to ProGuard, version 4.4
+welcome = Welcome to ProGuard, version 4.7
options = Options
keepAdditional = Keep additional classes and class members
keepNamesAdditional = Keep additional class names and class member names
@@ -51,20 +51,26 @@
# Info texts.
#
proGuardInfo = \
- ProGuard is a free class file shrinker, optimizer, obfuscator, and preverifier.\
- \n\n\
- With this GUI, you can create, load, modify, and save ProGuard configurations. \
- \n\
+ <html>ProGuard is a free class file shrinker, optimizer, obfuscator, and preverifier.\
+ <p>\
+ With this GUI, you can create, load, modify, and save ProGuard configurations.\
+ <br>\
You can then process your code right away, or you can run ProGuard from the \
- command line using your saved configuration. \
- \n\n\
+ command line using your saved configuration.\
+ <p>\
With the ReTrace part of this GUI you can de-obfuscate your stack traces.\
- \n\n\
+ <p>\
ProGuard and ReTrace are written and maintained by Eric Lafortune.\
- \n\n\
+ <p>\
+ Official site at Sourceforge: \
+ <a href="http://proguard.sourceforge.net/\">http://proguard.sourceforge.net/</a>\
+ <br>\
+ Professional support by Saikoa: \
+ <a href="http://www.saikoa.com/\">http://www.saikoa.com/</a>\
+ <p>\
Distributed under the GNU General Public License.\
- \n\
- Copyright (c) 2002-2009.
+ <br>\
+ Copyright © 2002-2011.</html>
processingInfo = \
You can now start processing your code, \
@@ -105,6 +111,7 @@
repackageClasses = Repackage classes
useMixedCaseClassNames = Use mixed-case class names
keepAttributes = Keep attributes
+keepParameterNames = Keep parameter names
renameSourceFileAttribute = Rename SourceFile attribute
adaptClassStrings = Adapt class strings
adaptResourceFileNames = Adapt resource file names
@@ -115,8 +122,8 @@
verbose = Verbose
note = Note potential mistakes in the configuration
-warn = Warn about possibly erronous input
-ignoreWarnings = Ignore warnings about possibly erronous input
+warn = Warn about possibly erroneous input
+ignoreWarnings = Ignore warnings about possibly erroneous input
skipNonPublicLibraryClasses = Skip non-public library classes
skipNonPublicLibraryClassMembers = Skip non-public library class members
keepDirectories = Keep directories
@@ -209,6 +216,9 @@
<li>"*Annotations*" is necessary for preserving annotations.\
</ul>\
The wildcard <code>*</code> and the negator <code>!</code> are allowed.</html>
+keepParameterNamesTip = \
+ <html>Keep parameter names and types in "LocalVariable*Table" attributes</br>\
+ in methods that are not obfuscated.</html>
renameSourceFileAttributeTip = \
<html>Put the given string in the "SourceFile" attribute of the processed class files.<br>\
It will appear as the file name of the classes in stack traces.</html>
@@ -246,12 +256,12 @@
noteFilterTip = \
A filter matching classes for which no notes should be printed.
warnTip = \
- <html>Print out warnings about possibly erronous input.<br>\
+ <html>Print out warnings about possibly erroneous input.<br>\
<i>Only unset this option if you know what you're doing!</i></html>
warnFilterTip = \
A filter matching classes for which no warnings should be printed.
ignoreWarningsTip = \
- <html>Ignore any warnings about possibly erronous input.<br>\
+ <html>Ignore any warnings about possibly erroneous input.<br>\
<i>Only set this option if you know what you're doing!</i></html>
skipNonPublicLibraryClassesTip = \
<html>Skip reading non-public library classes, for efficiency.<br>\
@@ -495,6 +505,8 @@
Perform peephole optimizations for field loading and storing.
code_simplification_branchTip = \
Perform peephole optimizations for branch instructions.
+code_simplification_stringTip = \
+ Perform peephole optimizations for constant strings.
code_simplification_advancedTip = \
Simplify code based on control flow analysis and data flow analysis.
code_removal_advancedTip = \
@@ -504,7 +516,7 @@
code_removal_variableTip = \
Remove unused variables from the local variable frame.
code_removal_exceptionTip = \
- Remove exceptions with empty catch blocks.
+ Remove exceptions with empty try blocks.
code_allocation_variableTip = \
Optimize variable allocation on the local variable frame.
diff --git a/src/proguard/gui/KeepSpecificationsPanel.java b/src/proguard/gui/KeepSpecificationsPanel.java
index 4c3c953..9834894 100644
--- a/src/proguard/gui/KeepSpecificationsPanel.java
+++ b/src/proguard/gui/KeepSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/ListPanel.java b/src/proguard/gui/ListPanel.java
index 0132340..292b838 100644
--- a/src/proguard/gui/ListPanel.java
+++ b/src/proguard/gui/ListPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/MemberSpecificationDialog.java b/src/proguard/gui/MemberSpecificationDialog.java
index 46a3f6f..f260b8b 100644
--- a/src/proguard/gui/MemberSpecificationDialog.java
+++ b/src/proguard/gui/MemberSpecificationDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -56,6 +56,7 @@
private final JRadioButton[] protectedRadioButtons;
private final JRadioButton[] staticRadioButtons;
private final JRadioButton[] finalRadioButtons;
+ private final JRadioButton[] syntheticRadioButtons;
private JRadioButton[] volatileRadioButtons;
private JRadioButton[] transientRadioButtons;
@@ -64,6 +65,8 @@
private JRadioButton[] nativeRadioButtons;
private JRadioButton[] abstractRadioButtons;
private JRadioButton[] strictRadioButtons;
+ private JRadioButton[] bridgeRadioButtons;
+ private JRadioButton[] varargsRadioButtons;
private final JTextField annotationTypeTextField = new JTextField(20);
private final JTextField nameTextField = new JTextField(20);
@@ -166,6 +169,7 @@
protectedRadioButtons = addRadioButtonTriplet("Protected", accessPanel);
staticRadioButtons = addRadioButtonTriplet("Static", accessPanel);
finalRadioButtons = addRadioButtonTriplet("Final", accessPanel);
+ syntheticRadioButtons = addRadioButtonTriplet("Synthetic", accessPanel);
if (isField)
{
@@ -178,6 +182,8 @@
nativeRadioButtons = addRadioButtonTriplet("Native", accessPanel);
abstractRadioButtons = addRadioButtonTriplet("Abstract", accessPanel);
strictRadioButtons = addRadioButtonTriplet("Strict", accessPanel);
+ bridgeRadioButtons = addRadioButtonTriplet("Bridge", accessPanel);
+ varargsRadioButtons = addRadioButtonTriplet("Varargs", accessPanel);
}
// Create the type panel.
@@ -332,12 +338,15 @@
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_PROTECTED, protectedRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STATIC, staticRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VOLATILE, volatileRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_TRANSIENT, transientRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNCHRONIZED, synchronizedRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_NATIVE, nativeRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STRICT, strictRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_BRIDGE, bridgeRadioButtons);
+ setMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VARARGS, varargsRadioButtons);
// Set the class name text fields.
nameTextField.setText(name == null ? "*" : name);
@@ -403,12 +412,15 @@
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_PROTECTED, protectedRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STATIC, staticRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_FINAL, finalRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNTHETIC, syntheticRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VOLATILE, volatileRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_TRANSIENT, transientRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_SYNCHRONIZED, synchronizedRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_NATIVE, nativeRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_ABSTRACT, abstractRadioButtons);
getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_STRICT, strictRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_BRIDGE, bridgeRadioButtons);
+ getMemberSpecificationRadioButtons(memberSpecification, ClassConstants.INTERNAL_ACC_VARARGS, varargsRadioButtons);
return memberSpecification;
}
diff --git a/src/proguard/gui/MemberSpecificationsPanel.java b/src/proguard/gui/MemberSpecificationsPanel.java
index 20b2f17..4e0a5f4 100644
--- a/src/proguard/gui/MemberSpecificationsPanel.java
+++ b/src/proguard/gui/MemberSpecificationsPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/MessageDialogRunnable.java b/src/proguard/gui/MessageDialogRunnable.java
index e58f1c6..7dddae5 100644
--- a/src/proguard/gui/MessageDialogRunnable.java
+++ b/src/proguard/gui/MessageDialogRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/OptimizationsDialog.java b/src/proguard/gui/OptimizationsDialog.java
index 044c338..1dbbd1c 100644
--- a/src/proguard/gui/OptimizationsDialog.java
+++ b/src/proguard/gui/OptimizationsDialog.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/ProGuardGUI.java b/src/proguard/gui/ProGuardGUI.java
index f27d698..7ff9086 100644
--- a/src/proguard/gui/ProGuardGUI.java
+++ b/src/proguard/gui/ProGuardGUI.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -33,7 +33,6 @@
import java.net.URL;
import java.util.*;
import java.util.List;
-import java.lang.reflect.InvocationTargetException;
/**
@@ -110,6 +109,7 @@
private final JCheckBox flattenPackageHierarchyCheckBox = new JCheckBox(msg("flattenPackageHierarchy"));
private final JCheckBox repackageClassesCheckBox = new JCheckBox(msg("repackageClasses"));
private final JCheckBox keepAttributesCheckBox = new JCheckBox(msg("keepAttributes"));
+ private final JCheckBox keepParameterNamesCheckBox = new JCheckBox(msg("keepParameterNames"));
private final JCheckBox newSourceFileAttributeCheckBox = new JCheckBox(msg("renameSourceFileAttribute"));
private final JCheckBox adaptClassStringsCheckBox = new JCheckBox(msg("adaptClassStrings"));
private final JCheckBox adaptResourceFileNamesCheckBox = new JCheckBox(msg("adaptResourceFileNames"));
@@ -202,13 +202,13 @@
splashPanelConstraints.anchor = GridBagConstraints.NORTHWEST;
//splashPanelConstraints.insets = constraints.insets;
- GridBagConstraints welcomeTextAreaConstraints = new GridBagConstraints();
- welcomeTextAreaConstraints.gridwidth = GridBagConstraints.REMAINDER;
- welcomeTextAreaConstraints.fill = GridBagConstraints.NONE;
- welcomeTextAreaConstraints.weightx = 1.0;
- welcomeTextAreaConstraints.weighty = 0.01;
- welcomeTextAreaConstraints.anchor = GridBagConstraints.CENTER;//NORTHWEST;
- welcomeTextAreaConstraints.insets = new Insets(20, 40, 20, 40);
+ GridBagConstraints welcomePaneConstraints = new GridBagConstraints();
+ welcomePaneConstraints.gridwidth = GridBagConstraints.REMAINDER;
+ welcomePaneConstraints.fill = GridBagConstraints.NONE;
+ welcomePaneConstraints.weightx = 1.0;
+ welcomePaneConstraints.weighty = 0.01;
+ welcomePaneConstraints.anchor = GridBagConstraints.CENTER;//NORTHWEST;
+ welcomePaneConstraints.insets = new Insets(20, 40, 20, 40);
GridBagConstraints panelConstraints = new GridBagConstraints();
panelConstraints.gridwidth = GridBagConstraints.REMAINDER;
@@ -295,18 +295,19 @@
splashPanel = new SplashPanel(splash, 0.5, 5500L);
splashPanel.setPreferredSize(new Dimension(0, 200));
- JTextArea welcomeTextArea = new JTextArea(msg("proGuardInfo"), 18, 50);
- welcomeTextArea.setOpaque(false);
- welcomeTextArea.setEditable(false);
- welcomeTextArea.setLineWrap(true);
- welcomeTextArea.setWrapStyleWord(true);
- welcomeTextArea.setPreferredSize(new Dimension(0, 0));
- welcomeTextArea.setBorder(new EmptyBorder(20, 20, 20, 20));
- addBorder(welcomeTextArea, "welcome");
+ JEditorPane welcomePane = new JEditorPane("text/html", msg("proGuardInfo"));
+ welcomePane.setPreferredSize(new Dimension(640, 350));
+ // The constant HONOR_DISPLAY_PROPERTIES isn't present yet in JDK 1.4.
+ //welcomePane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+ welcomePane.putClientProperty("JEditorPane.honorDisplayProperties", Boolean.TRUE);
+ welcomePane.setOpaque(false);
+ welcomePane.setEditable(false);
+ welcomePane.setBorder(new EmptyBorder(20, 20, 20, 20));
+ addBorder(welcomePane, "welcome");
JPanel proGuardPanel = new JPanel(layout);
proGuardPanel.add(splashPanel, splashPanelConstraints);
- proGuardPanel.add(welcomeTextArea, welcomeTextAreaConstraints);
+ proGuardPanel.add(welcomePane, welcomePaneConstraints);
// Create the input panel.
// TODO: properly clone the ClassPath objects.
@@ -403,6 +404,7 @@
obfuscationOptionsPanel.add(tip(repackageClassesTextField, "packageTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(keepAttributesCheckBox, "keepAttributesTip"), constraints);
obfuscationOptionsPanel.add(tip(keepAttributesTextField, "attributesTip"), constraintsLastStretch);
+ obfuscationOptionsPanel.add(tip(keepParameterNamesCheckBox, "keepParameterNamesTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(newSourceFileAttributeCheckBox, "renameSourceFileAttributeTip"), constraints);
obfuscationOptionsPanel.add(tip(newSourceFileAttributeTextField, "sourceFileAttributeTip"), constraintsLastStretch);
obfuscationOptionsPanel.add(tip(adaptClassStringsCheckBox, "adaptClassStringsTip"), constraints);
@@ -1019,6 +1021,7 @@
flattenPackageHierarchyCheckBox .setSelected(configuration.flattenPackageHierarchy != null);
repackageClassesCheckBox .setSelected(configuration.repackageClasses != null);
keepAttributesCheckBox .setSelected(configuration.keepAttributes != null);
+ keepParameterNamesCheckBox .setSelected(configuration.keepParameterNames);
newSourceFileAttributeCheckBox .setSelected(configuration.newSourceFileAttribute != null);
adaptClassStringsCheckBox .setSelected(configuration.adaptClassStrings != null);
adaptResourceFileNamesCheckBox .setSelected(configuration.adaptResourceFileNames != null);
@@ -1041,21 +1044,26 @@
dumpCheckBox .setSelected(configuration.dump != null);
printUsageTextField .setText(fileName(configuration.printUsage));
- optimizationsTextField .setText(configuration.optimizations == null ? OPTIMIZATIONS_DEFAULT : ListUtil.commaSeparatedString(configuration.optimizations));
+ optimizationsTextField .setText(configuration.optimizations ==
+ null ?
+ OPTIMIZATIONS_DEFAULT :
+ ListUtil.commaSeparatedString(configuration.optimizations, true));
printMappingTextField .setText(fileName(configuration.printMapping));
applyMappingTextField .setText(fileName(configuration.applyMapping));
obfuscationDictionaryTextField .setText(fileName(configuration.obfuscationDictionary));
- keepPackageNamesTextField .setText(configuration.keepPackageNames == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.keepPackageNames)));
+ classObfuscationDictionaryTextField .setText(fileName(configuration.classObfuscationDictionary));
+ packageObfuscationDictionaryTextField .setText(fileName(configuration.packageObfuscationDictionary));
+ keepPackageNamesTextField .setText(configuration.keepPackageNames == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.keepPackageNames, true)));
flattenPackageHierarchyTextField .setText(configuration.flattenPackageHierarchy);
repackageClassesTextField .setText(configuration.repackageClasses);
- keepAttributesTextField .setText(configuration.keepAttributes == null ? KEEP_ATTRIBUTE_DEFAULT : ListUtil.commaSeparatedString(configuration.keepAttributes));
+ keepAttributesTextField .setText(configuration.keepAttributes == null ? KEEP_ATTRIBUTE_DEFAULT : ListUtil.commaSeparatedString(configuration.keepAttributes, true));
newSourceFileAttributeTextField .setText(configuration.newSourceFileAttribute == null ? SOURCE_FILE_ATTRIBUTE_DEFAULT : configuration.newSourceFileAttribute);
- adaptClassStringsTextField .setText(configuration.adaptClassStrings == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.adaptClassStrings)));
- adaptResourceFileNamesTextField .setText(configuration.adaptResourceFileNames == null ? ADAPT_RESOURCE_FILE_NAMES_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileNames));
- adaptResourceFileContentsTextField .setText(configuration.adaptResourceFileContents == null ? ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileContents));
- noteTextField .setText(ListUtil.commaSeparatedString(configuration.note));
- warnTextField .setText(ListUtil.commaSeparatedString(configuration.warn));
- keepDirectoriesTextField .setText(ListUtil.commaSeparatedString(configuration.keepDirectories));
+ adaptClassStringsTextField .setText(configuration.adaptClassStrings == null ? "" : ClassUtil.externalClassName(ListUtil.commaSeparatedString(configuration.adaptClassStrings, true)));
+ adaptResourceFileNamesTextField .setText(configuration.adaptResourceFileNames == null ? ADAPT_RESOURCE_FILE_NAMES_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileNames, true));
+ adaptResourceFileContentsTextField .setText(configuration.adaptResourceFileContents == null ? ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileContents, true));
+ noteTextField .setText(ListUtil.commaSeparatedString(configuration.note, true));
+ warnTextField .setText(ListUtil.commaSeparatedString(configuration.warn, true));
+ keepDirectoriesTextField .setText(ListUtil.commaSeparatedString(configuration.keepDirectories, true));
printSeedsTextField .setText(fileName(configuration.printSeeds));
printConfigurationTextField .setText(fileName(configuration.printConfiguration));
dumpTextField .setText(fileName(configuration.dump));
@@ -1182,6 +1190,7 @@
configuration.flattenPackageHierarchy = flattenPackageHierarchyCheckBox .isSelected() ? ClassUtil.internalClassName(flattenPackageHierarchyTextField .getText()) : null;
configuration.repackageClasses = repackageClassesCheckBox .isSelected() ? ClassUtil.internalClassName(repackageClassesTextField .getText()) : null;
configuration.keepAttributes = keepAttributesCheckBox .isSelected() ? ListUtil.commaSeparatedList(keepAttributesTextField .getText()) : null;
+ configuration.keepParameterNames = keepParameterNamesCheckBox .isSelected();
configuration.newSourceFileAttribute = newSourceFileAttributeCheckBox .isSelected() ? newSourceFileAttributeTextField .getText() : null;
configuration.adaptClassStrings = adaptClassStringsCheckBox .isSelected() ? adaptClassStringsTextField.getText().length() > 0 ? ListUtil.commaSeparatedList(ClassUtil.internalClassName(adaptClassStringsTextField.getText())) : new ArrayList() : null;
configuration.adaptResourceFileNames = adaptResourceFileNamesCheckBox .isSelected() ? ListUtil.commaSeparatedList(adaptResourceFileNamesTextField .getText()) : null;
@@ -1436,13 +1445,13 @@
/**
* Loads the given stack trace into the GUI.
*/
- private void loadStackTrace(String fileName)
+ private void loadStackTrace(File file)
{
try
{
StringBuffer buffer = new StringBuffer(1024);
- Reader reader = new BufferedReader(new FileReader(fileName));
+ Reader reader = new BufferedReader(new FileReader(file));
try
{
while (true)
@@ -1467,7 +1476,7 @@
catch (IOException ex)
{
JOptionPane.showMessageDialog(getContentPane(),
- msg("cantOpenStackTraceFile", fileName),
+ msg("cantOpenStackTraceFile", fileName(file)),
msg("warning"),
JOptionPane.ERROR_MESSAGE);
}
@@ -1600,10 +1609,8 @@
int returnValue = fileChooser.showOpenDialog(ProGuardGUI.this);
if (returnValue == JFileChooser.APPROVE_OPTION)
{
- File selectedFile = fileChooser.getSelectedFile();
- String fileName = selectedFile.getPath();
- loadStackTrace(fileName);
+ loadStackTrace(fileChooser.getSelectedFile());
}
}
}
@@ -1641,11 +1648,37 @@
// Small utility methods.
/**
- * Returns the file name of the given file, if any.
+ * Returns the canonical file name for the given file, or the empty string
+ * if the file name is empty.
*/
- private static String fileName(File file)
+ private String fileName(File file)
{
- return file == null ? "" : file.getAbsolutePath();
+ if (isFile(file))
+ {
+ try
+ {
+ return file.getCanonicalPath();
+ }
+ catch (IOException ex)
+ {
+ return file.getPath();
+ }
+ }
+ else
+ {
+ return "";
+ }
+ }
+
+
+ /**
+ * Returns whether the given file is actually a file, or just a placeholder
+ * for the standard output.
+ */
+ private boolean isFile(File file)
+ {
+ return file != null &&
+ file.getPath().length() > 0;
}
@@ -1693,46 +1726,52 @@
{
public void run()
{
- ProGuardGUI gui = new ProGuardGUI();
- gui.pack();
-
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- Dimension guiSize = gui.getSize();
- gui.setLocation((screenSize.width - guiSize.width) / 2,
- (screenSize.height - guiSize.height) / 2);
- gui.show();
-
- // Start the splash animation, unless specified otherwise.
- int argIndex = 0;
- if (argIndex < args.length &&
- NO_SPLASH_OPTION.startsWith(args[argIndex]))
+ try
{
- gui.skipSplash();
- argIndex++;
- }
- else
- {
- gui.startSplash();
- }
+ ProGuardGUI gui = new ProGuardGUI();
+ gui.pack();
- // Load an initial configuration, if specified.
- if (argIndex < args.length)
- {
- gui.loadConfiguration(new File(args[argIndex]));
- argIndex++;
- }
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension guiSize = gui.getSize();
+ gui.setLocation((screenSize.width - guiSize.width) / 2,
+ (screenSize.height - guiSize.height) / 2);
+ gui.show();
- if (argIndex < args.length)
- {
- System.out.println(gui.getClass().getName() + ": ignoring extra arguments [" + args[argIndex] + "...]");
- }
+ // Start the splash animation, unless specified otherwise.
+ int argIndex = 0;
+ if (argIndex < args.length &&
+ NO_SPLASH_OPTION.startsWith(args[argIndex]))
+ {
+ gui.skipSplash();
+ argIndex++;
+ }
+ else
+ {
+ gui.startSplash();
+ }
+ // Load an initial configuration, if specified.
+ if (argIndex < args.length)
+ {
+ gui.loadConfiguration(new File(args[argIndex]));
+ argIndex++;
+ }
+
+ if (argIndex < args.length)
+ {
+ System.out.println(gui.getClass().getName() + ": ignoring extra arguments [" + args[argIndex] + "...]");
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")");
+ }
}
});
}
catch (Exception e)
{
- // Nothing.
+ System.out.println("Internal problem starting the ProGuard GUI (" + e.getMessage() + ")");
}
}
}
diff --git a/src/proguard/gui/ProGuardRunnable.java b/src/proguard/gui/ProGuardRunnable.java
index c5c5937..2a898d9 100644
--- a/src/proguard/gui/ProGuardRunnable.java
+++ b/src/proguard/gui/ProGuardRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/ReTraceRunnable.java b/src/proguard/gui/ReTraceRunnable.java
index 1ca19ca..fb1f325 100644
--- a/src/proguard/gui/ReTraceRunnable.java
+++ b/src/proguard/gui/ReTraceRunnable.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/SwingUtil.java b/src/proguard/gui/SwingUtil.java
index 75d2f02..f6d2d34 100644
--- a/src/proguard/gui/SwingUtil.java
+++ b/src/proguard/gui/SwingUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/TabbedPane.java b/src/proguard/gui/TabbedPane.java
index a6460f5..033b039 100644
--- a/src/proguard/gui/TabbedPane.java
+++ b/src/proguard/gui/TabbedPane.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/TextAreaOutputStream.java b/src/proguard/gui/TextAreaOutputStream.java
index 57f983d..da263a5 100644
--- a/src/proguard/gui/TextAreaOutputStream.java
+++ b/src/proguard/gui/TextAreaOutputStream.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/BufferedSprite.java b/src/proguard/gui/splash/BufferedSprite.java
index 8427832..c82c511 100644
--- a/src/proguard/gui/splash/BufferedSprite.java
+++ b/src/proguard/gui/splash/BufferedSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/CircleSprite.java b/src/proguard/gui/splash/CircleSprite.java
index 5dc65eb..6512495 100644
--- a/src/proguard/gui/splash/CircleSprite.java
+++ b/src/proguard/gui/splash/CircleSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ClipSprite.java b/src/proguard/gui/splash/ClipSprite.java
index 55f9eac..6a8e5fe 100644
--- a/src/proguard/gui/splash/ClipSprite.java
+++ b/src/proguard/gui/splash/ClipSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ColorSprite.java b/src/proguard/gui/splash/ColorSprite.java
index 3f9bc3b..1e633fa 100644
--- a/src/proguard/gui/splash/ColorSprite.java
+++ b/src/proguard/gui/splash/ColorSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/CompositeSprite.java b/src/proguard/gui/splash/CompositeSprite.java
index 2480ead..e82f524 100644
--- a/src/proguard/gui/splash/CompositeSprite.java
+++ b/src/proguard/gui/splash/CompositeSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantColor.java b/src/proguard/gui/splash/ConstantColor.java
index 94c78df..85ca451 100644
--- a/src/proguard/gui/splash/ConstantColor.java
+++ b/src/proguard/gui/splash/ConstantColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantDouble.java b/src/proguard/gui/splash/ConstantDouble.java
index 0874d6d..e903c9b 100644
--- a/src/proguard/gui/splash/ConstantDouble.java
+++ b/src/proguard/gui/splash/ConstantDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantFont.java b/src/proguard/gui/splash/ConstantFont.java
index 3f1ac03..c7fd8f5 100644
--- a/src/proguard/gui/splash/ConstantFont.java
+++ b/src/proguard/gui/splash/ConstantFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantInt.java b/src/proguard/gui/splash/ConstantInt.java
index 537196d..c9e80a8 100644
--- a/src/proguard/gui/splash/ConstantInt.java
+++ b/src/proguard/gui/splash/ConstantInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantString.java b/src/proguard/gui/splash/ConstantString.java
index 7617c3f..e67db5c 100644
--- a/src/proguard/gui/splash/ConstantString.java
+++ b/src/proguard/gui/splash/ConstantString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ConstantTiming.java b/src/proguard/gui/splash/ConstantTiming.java
index dfde644..9b0a01c 100644
--- a/src/proguard/gui/splash/ConstantTiming.java
+++ b/src/proguard/gui/splash/ConstantTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/FontSprite.java b/src/proguard/gui/splash/FontSprite.java
index 9a554ba..19882d4 100644
--- a/src/proguard/gui/splash/FontSprite.java
+++ b/src/proguard/gui/splash/FontSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ImageSprite.java b/src/proguard/gui/splash/ImageSprite.java
index 6e7c189..28bb05f 100644
--- a/src/proguard/gui/splash/ImageSprite.java
+++ b/src/proguard/gui/splash/ImageSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/LinearColor.java b/src/proguard/gui/splash/LinearColor.java
index 3a7674d..cdd8d11 100644
--- a/src/proguard/gui/splash/LinearColor.java
+++ b/src/proguard/gui/splash/LinearColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/LinearDouble.java b/src/proguard/gui/splash/LinearDouble.java
index 046ae84..249b8de 100644
--- a/src/proguard/gui/splash/LinearDouble.java
+++ b/src/proguard/gui/splash/LinearDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/LinearInt.java b/src/proguard/gui/splash/LinearInt.java
index 8d299bc..7ee7c32 100644
--- a/src/proguard/gui/splash/LinearInt.java
+++ b/src/proguard/gui/splash/LinearInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/LinearTiming.java b/src/proguard/gui/splash/LinearTiming.java
index 9b26644..13799fc 100644
--- a/src/proguard/gui/splash/LinearTiming.java
+++ b/src/proguard/gui/splash/LinearTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/OverrideGraphics2D.java b/src/proguard/gui/splash/OverrideGraphics2D.java
index 4333459..6d70049 100644
--- a/src/proguard/gui/splash/OverrideGraphics2D.java
+++ b/src/proguard/gui/splash/OverrideGraphics2D.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/RectangleSprite.java b/src/proguard/gui/splash/RectangleSprite.java
index d204831..6f702f7 100644
--- a/src/proguard/gui/splash/RectangleSprite.java
+++ b/src/proguard/gui/splash/RectangleSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/SawToothTiming.java b/src/proguard/gui/splash/SawToothTiming.java
index 076d5e2..eef8995 100644
--- a/src/proguard/gui/splash/SawToothTiming.java
+++ b/src/proguard/gui/splash/SawToothTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/ShadowedSprite.java b/src/proguard/gui/splash/ShadowedSprite.java
index c3504f3..e048c9f 100644
--- a/src/proguard/gui/splash/ShadowedSprite.java
+++ b/src/proguard/gui/splash/ShadowedSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/SineTiming.java b/src/proguard/gui/splash/SineTiming.java
index eb0a7cc..56779ef 100644
--- a/src/proguard/gui/splash/SineTiming.java
+++ b/src/proguard/gui/splash/SineTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/SmoothTiming.java b/src/proguard/gui/splash/SmoothTiming.java
index a985712..22e90fc 100644
--- a/src/proguard/gui/splash/SmoothTiming.java
+++ b/src/proguard/gui/splash/SmoothTiming.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/SplashPanel.java b/src/proguard/gui/splash/SplashPanel.java
index 23a9ce4..00ac82a 100644
--- a/src/proguard/gui/splash/SplashPanel.java
+++ b/src/proguard/gui/splash/SplashPanel.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/Sprite.java b/src/proguard/gui/splash/Sprite.java
index ada7a81..79a2747 100644
--- a/src/proguard/gui/splash/Sprite.java
+++ b/src/proguard/gui/splash/Sprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/TextSprite.java b/src/proguard/gui/splash/TextSprite.java
index bbf37d4..131b94c 100644
--- a/src/proguard/gui/splash/TextSprite.java
+++ b/src/proguard/gui/splash/TextSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/TimeSwitchSprite.java b/src/proguard/gui/splash/TimeSwitchSprite.java
index 921bef2..f8501de 100644
--- a/src/proguard/gui/splash/TimeSwitchSprite.java
+++ b/src/proguard/gui/splash/TimeSwitchSprite.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/Timing.java b/src/proguard/gui/splash/Timing.java
index 887d737..1256a6f 100644
--- a/src/proguard/gui/splash/Timing.java
+++ b/src/proguard/gui/splash/Timing.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/TypeWriterString.java b/src/proguard/gui/splash/TypeWriterString.java
index 9f1441e..53540de 100644
--- a/src/proguard/gui/splash/TypeWriterString.java
+++ b/src/proguard/gui/splash/TypeWriterString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableColor.java b/src/proguard/gui/splash/VariableColor.java
index 6a30062..7fc4b4d 100644
--- a/src/proguard/gui/splash/VariableColor.java
+++ b/src/proguard/gui/splash/VariableColor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableDouble.java b/src/proguard/gui/splash/VariableDouble.java
index 39302dd..dcde0bc 100644
--- a/src/proguard/gui/splash/VariableDouble.java
+++ b/src/proguard/gui/splash/VariableDouble.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableFont.java b/src/proguard/gui/splash/VariableFont.java
index a7de8d7..12fe09e 100644
--- a/src/proguard/gui/splash/VariableFont.java
+++ b/src/proguard/gui/splash/VariableFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableInt.java b/src/proguard/gui/splash/VariableInt.java
index 68a33af..148cf56 100644
--- a/src/proguard/gui/splash/VariableInt.java
+++ b/src/proguard/gui/splash/VariableInt.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableSizeFont.java b/src/proguard/gui/splash/VariableSizeFont.java
index e36d28c..eaef2c9 100644
--- a/src/proguard/gui/splash/VariableSizeFont.java
+++ b/src/proguard/gui/splash/VariableSizeFont.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/gui/splash/VariableString.java b/src/proguard/gui/splash/VariableString.java
index 1dec23b..73d01f2 100644
--- a/src/proguard/gui/splash/VariableString.java
+++ b/src/proguard/gui/splash/VariableString.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/CascadingDataEntryWriter.java b/src/proguard/io/CascadingDataEntryWriter.java
index 15719e6..9bd657f 100644
--- a/src/proguard/io/CascadingDataEntryWriter.java
+++ b/src/proguard/io/CascadingDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/ClassFilter.java b/src/proguard/io/ClassFilter.java
index bf591ab..fe35d8f 100644
--- a/src/proguard/io/ClassFilter.java
+++ b/src/proguard/io/ClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/ClassReader.java b/src/proguard/io/ClassReader.java
index e21968c..c049ea0 100644
--- a/src/proguard/io/ClassReader.java
+++ b/src/proguard/io/ClassReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -109,7 +109,7 @@
}
catch (Exception ex)
{
- throw new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")");
+ throw (IOException)new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex);
}
}
}
diff --git a/src/proguard/io/ClassRewriter.java b/src/proguard/io/ClassRewriter.java
index bd19e1d..613bb89 100644
--- a/src/proguard/io/ClassRewriter.java
+++ b/src/proguard/io/ClassRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntry.java b/src/proguard/io/DataEntry.java
index af0e373..bc61704 100644
--- a/src/proguard/io/DataEntry.java
+++ b/src/proguard/io/DataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryClassWriter.java b/src/proguard/io/DataEntryClassWriter.java
new file mode 100644
index 0000000..4cd46ff
--- /dev/null
+++ b/src/proguard/io/DataEntryClassWriter.java
@@ -0,0 +1,85 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.io;
+
+import proguard.classfile.*;
+import proguard.classfile.io.*;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+
+import java.io.*;
+
+/**
+ * This ClassVisitor writes out the ProgramClass objects that it visits to the
+ * given DataEntry, modified to have the correct name.
+ *
+ * @author Eric Lafortune
+ */
+public class DataEntryClassWriter
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ private final DataEntryWriter dataEntryWriter;
+ private final DataEntry templateDataEntry;
+
+
+ /**
+ * Creates a new DataEntryClassWriter for writing to the given
+ * DataEntryWriter, based on the given template DataEntry.
+ */
+ public DataEntryClassWriter(DataEntryWriter dataEntryWriter,
+ DataEntry templateDataEntry)
+ {
+ this.dataEntryWriter = dataEntryWriter;
+ this.templateDataEntry = templateDataEntry;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ // Rename the data entry if necessary.
+ String actualClassName = programClass.getName();
+ DataEntry actualDataEntry =
+ new RenamedDataEntry(templateDataEntry,
+ actualClassName + ClassConstants.CLASS_FILE_EXTENSION);
+
+ try
+ {
+ // Get the output entry corresponding to this input entry.
+ OutputStream outputStream = dataEntryWriter.getOutputStream(actualDataEntry);
+ if (outputStream != null)
+ {
+ // Write the class to the output entry.
+ DataOutputStream classOutputStream = new DataOutputStream(outputStream);
+
+ new ProgramClassWriter(classOutputStream).visitProgramClass(programClass);
+
+ classOutputStream.flush();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("Can't write program class ["+actualClassName+"] to ["+actualDataEntry+"] ("+e.getMessage()+")", e);
+ }
+ }
+}
diff --git a/src/proguard/io/DataEntryCopier.java b/src/proguard/io/DataEntryCopier.java
index faaa555..76d5bdd 100644
--- a/src/proguard/io/DataEntryCopier.java
+++ b/src/proguard/io/DataEntryCopier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryDirectoryFilter.java b/src/proguard/io/DataEntryDirectoryFilter.java
index bb36f3e..036347d 100644
--- a/src/proguard/io/DataEntryDirectoryFilter.java
+++ b/src/proguard/io/DataEntryDirectoryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryFilter.java b/src/proguard/io/DataEntryFilter.java
index ddcd0be..92ff83e 100644
--- a/src/proguard/io/DataEntryFilter.java
+++ b/src/proguard/io/DataEntryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryNameFilter.java b/src/proguard/io/DataEntryNameFilter.java
index d6afd2e..86a736f 100644
--- a/src/proguard/io/DataEntryNameFilter.java
+++ b/src/proguard/io/DataEntryNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryObfuscator.java b/src/proguard/io/DataEntryObfuscator.java
index aa63af1..1009548 100644
--- a/src/proguard/io/DataEntryObfuscator.java
+++ b/src/proguard/io/DataEntryObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -75,7 +75,7 @@
String dataEntryName = dataEntry.getName();
// Try to find a corresponding class name by removing increasingly
- // long suffixes,
+ // long suffixes.
for (int suffixIndex = dataEntryName.length() - 1;
suffixIndex > 0;
suffixIndex--)
@@ -106,25 +106,44 @@
return new RenamedDataEntry(dataEntry, newDataEntryName);
}
-
- // Otherwise stop looking.
- break;
+ else
+ {
+ // Otherwise stop looking.
+ return dataEntry;
+ }
}
}
}
- // Did the package get a new name?
- String packagePrefix = ClassUtil.internalPackagePrefix(dataEntryName);
- String newPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
- if (newPackagePrefix != null &&
- !packagePrefix.equals(newPackagePrefix))
+ // Try to find a corresponding package name by increasingly removing
+ // more subpackages.
+ String packagePrefix = dataEntryName;
+ do
{
- // Return a renamed data entry.
- String newDataEntryName =
- newPackagePrefix + dataEntryName.substring(packagePrefix.length());
+ // Chop off the class name or the last subpackage name.
+ packagePrefix = ClassUtil.internalPackagePrefix(packagePrefix);
- return new RenamedDataEntry(dataEntry, newDataEntryName);
+ // Is there a package corresponding to the package prefix?
+ String newPackagePrefix = (String)packagePrefixMap.get(packagePrefix);
+ if (newPackagePrefix != null)
+ {
+ // Did the package get a new name?
+ if (!packagePrefix.equals(newPackagePrefix))
+ {
+ // Return a renamed data entry.
+ String newDataEntryName =
+ newPackagePrefix + dataEntryName.substring(packagePrefix.length());
+
+ return new RenamedDataEntry(dataEntry, newDataEntryName);
+ }
+ else
+ {
+ // Otherwise stop looking.
+ return dataEntry;
+ }
+ }
}
+ while (packagePrefix.length() > 0);
return dataEntry;
}
diff --git a/src/proguard/io/DataEntryParentFilter.java b/src/proguard/io/DataEntryParentFilter.java
index fbeac4f..cf44b65 100644
--- a/src/proguard/io/DataEntryParentFilter.java
+++ b/src/proguard/io/DataEntryParentFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryPump.java b/src/proguard/io/DataEntryPump.java
index bfe22a3..a54038b 100644
--- a/src/proguard/io/DataEntryPump.java
+++ b/src/proguard/io/DataEntryPump.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryReader.java b/src/proguard/io/DataEntryReader.java
index e77f7bf..6d24b42 100644
--- a/src/proguard/io/DataEntryReader.java
+++ b/src/proguard/io/DataEntryReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryRenamer.java b/src/proguard/io/DataEntryRenamer.java
index 45c61ee..89e006a 100644
--- a/src/proguard/io/DataEntryRenamer.java
+++ b/src/proguard/io/DataEntryRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -87,7 +87,7 @@
String newName = (String)nameMap.get(name);
if (newName != null)
{
- // Add remove the directory separator if necessary.
+ // Remove the directory separator if necessary.
if (dataEntry.isDirectory() &&
newName.length() > 0)
{
@@ -101,4 +101,4 @@
missingDataEntryReader.read(dataEntry);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/proguard/io/DataEntryRewriter.java b/src/proguard/io/DataEntryRewriter.java
index eefced4..d7852a5 100644
--- a/src/proguard/io/DataEntryRewriter.java
+++ b/src/proguard/io/DataEntryRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DataEntryWriter.java b/src/proguard/io/DataEntryWriter.java
index 9ecf79b..6db918e 100644
--- a/src/proguard/io/DataEntryWriter.java
+++ b/src/proguard/io/DataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DirectoryFilter.java b/src/proguard/io/DirectoryFilter.java
index a45d1aa..f99a6c2 100644
--- a/src/proguard/io/DirectoryFilter.java
+++ b/src/proguard/io/DirectoryFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DirectoryPump.java b/src/proguard/io/DirectoryPump.java
index cab2ff3..35d5a76 100644
--- a/src/proguard/io/DirectoryPump.java
+++ b/src/proguard/io/DirectoryPump.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/DirectoryWriter.java b/src/proguard/io/DirectoryWriter.java
index c6605df..c74d503 100644
--- a/src/proguard/io/DirectoryWriter.java
+++ b/src/proguard/io/DirectoryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/FileDataEntry.java b/src/proguard/io/FileDataEntry.java
index d0449ee..1a2d2d3 100644
--- a/src/proguard/io/FileDataEntry.java
+++ b/src/proguard/io/FileDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/FilteredDataEntryReader.java b/src/proguard/io/FilteredDataEntryReader.java
index 11da0d4..b03dd6f 100644
--- a/src/proguard/io/FilteredDataEntryReader.java
+++ b/src/proguard/io/FilteredDataEntryReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/FilteredDataEntryWriter.java b/src/proguard/io/FilteredDataEntryWriter.java
index 40a8c64..795e8c8 100644
--- a/src/proguard/io/FilteredDataEntryWriter.java
+++ b/src/proguard/io/FilteredDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/Finisher.java b/src/proguard/io/Finisher.java
index 8c4cc1e..164ef58 100644
--- a/src/proguard/io/Finisher.java
+++ b/src/proguard/io/Finisher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/JarReader.java b/src/proguard/io/JarReader.java
index f96b4aa..60a1d6d 100644
--- a/src/proguard/io/JarReader.java
+++ b/src/proguard/io/JarReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/JarWriter.java b/src/proguard/io/JarWriter.java
index 3e40cdf..946b5b8 100644
--- a/src/proguard/io/JarWriter.java
+++ b/src/proguard/io/JarWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/ManifestRewriter.java b/src/proguard/io/ManifestRewriter.java
index f10307e..b28dd8d 100644
--- a/src/proguard/io/ManifestRewriter.java
+++ b/src/proguard/io/ManifestRewriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/NameFilter.java b/src/proguard/io/NameFilter.java
index 2a9fbc3..f36d663 100644
--- a/src/proguard/io/NameFilter.java
+++ b/src/proguard/io/NameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/ParentDataEntryWriter.java b/src/proguard/io/ParentDataEntryWriter.java
index 4f16d12..528bb39 100644
--- a/src/proguard/io/ParentDataEntryWriter.java
+++ b/src/proguard/io/ParentDataEntryWriter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/RenamedDataEntry.java b/src/proguard/io/RenamedDataEntry.java
index ae2d267..71b7fac 100644
--- a/src/proguard/io/RenamedDataEntry.java
+++ b/src/proguard/io/RenamedDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/io/ZipDataEntry.java b/src/proguard/io/ZipDataEntry.java
index 5779fd8..3e19db1 100644
--- a/src/proguard/io/ZipDataEntry.java
+++ b/src/proguard/io/ZipDataEntry.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/AttributeShrinker.java b/src/proguard/obfuscate/AttributeShrinker.java
index a8bc36b..ee9bc4b 100644
--- a/src/proguard/obfuscate/AttributeShrinker.java
+++ b/src/proguard/obfuscate/AttributeShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,6 +26,8 @@
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
/**
* This ClassVisitor removes attributes that are not marked as being used or
* required.
@@ -111,10 +113,7 @@
}
// Clear the remaining array elements.
- for (int index = counter; index < length; index++)
- {
- array[index] = null;
- }
+ Arrays.fill(array, counter, length, null);
return counter;
}
diff --git a/src/proguard/obfuscate/AttributeUsageMarker.java b/src/proguard/obfuscate/AttributeUsageMarker.java
index e772324..297b540 100644
--- a/src/proguard/obfuscate/AttributeUsageMarker.java
+++ b/src/proguard/obfuscate/AttributeUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -26,7 +26,7 @@
import proguard.classfile.util.SimplifiedVisitor;
/**
- * This ClassVisitor marks all attributes that it visits.
+ * This AttributeVisitor marks all attributes that it visits.
*
* @see AttributeShrinker
*
diff --git a/src/proguard/obfuscate/ClassObfuscator.java b/src/proguard/obfuscate/ClassObfuscator.java
index 9af0c82..446b158 100644
--- a/src/proguard/obfuscate/ClassObfuscator.java
+++ b/src/proguard/obfuscate/ClassObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -469,13 +469,25 @@
{
// Come up with class names until we get an original one.
String newClassName;
+ String newMixedCaseClassName;
do
{
// Let the factory produce a class name.
newClassName = newPackagePrefix +
classNameFactory.nextName();
+
+ newMixedCaseClassName = mixedCaseClassName(newClassName);
}
- while (classNamesToAvoid.contains(mixedCaseClassName(newClassName)));
+ while (classNamesToAvoid.contains(newMixedCaseClassName));
+
+ // Explicitly make sure the name isn't used again if we have a
+ // user-specified dictionary and we're not allowed to have mixed case
+ // class names -- just to protect against problematic dictionaries.
+ if (this.classNameFactory != null &&
+ !useMixedCaseClassNames)
+ {
+ classNamesToAvoid.add(newMixedCaseClassName);
+ }
return newClassName;
}
diff --git a/src/proguard/obfuscate/ClassRenamer.java b/src/proguard/obfuscate/ClassRenamer.java
index 143e3fb..a967d36 100644
--- a/src/proguard/obfuscate/ClassRenamer.java
+++ b/src/proguard/obfuscate/ClassRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/DictionaryNameFactory.java b/src/proguard/obfuscate/DictionaryNameFactory.java
index f262664..393c648 100644
--- a/src/proguard/obfuscate/DictionaryNameFactory.java
+++ b/src/proguard/obfuscate/DictionaryNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MapCleaner.java b/src/proguard/obfuscate/MapCleaner.java
index fdefec5..d6ca5f6 100644
--- a/src/proguard/obfuscate/MapCleaner.java
+++ b/src/proguard/obfuscate/MapCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MappingKeeper.java b/src/proguard/obfuscate/MappingKeeper.java
index c9d6aa6..d02d7bc 100644
--- a/src/proguard/obfuscate/MappingKeeper.java
+++ b/src/proguard/obfuscate/MappingKeeper.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MappingPrinter.java b/src/proguard/obfuscate/MappingPrinter.java
index aa8b13e..c004b73 100644
--- a/src/proguard/obfuscate/MappingPrinter.java
+++ b/src/proguard/obfuscate/MappingPrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MappingProcessor.java b/src/proguard/obfuscate/MappingProcessor.java
index 01c1809..7c9103a 100644
--- a/src/proguard/obfuscate/MappingProcessor.java
+++ b/src/proguard/obfuscate/MappingProcessor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MappingReader.java b/src/proguard/obfuscate/MappingReader.java
index 24fd26c..0798a4d 100644
--- a/src/proguard/obfuscate/MappingReader.java
+++ b/src/proguard/obfuscate/MappingReader.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MemberNameCleaner.java b/src/proguard/obfuscate/MemberNameCleaner.java
index c41c59d..0d5a519 100644
--- a/src/proguard/obfuscate/MemberNameCleaner.java
+++ b/src/proguard/obfuscate/MemberNameCleaner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MemberNameCollector.java b/src/proguard/obfuscate/MemberNameCollector.java
index c248820..92ec589 100644
--- a/src/proguard/obfuscate/MemberNameCollector.java
+++ b/src/proguard/obfuscate/MemberNameCollector.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MemberNameConflictFixer.java b/src/proguard/obfuscate/MemberNameConflictFixer.java
index b9093a6..22de855 100644
--- a/src/proguard/obfuscate/MemberNameConflictFixer.java
+++ b/src/proguard/obfuscate/MemberNameConflictFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MemberNameFilter.java b/src/proguard/obfuscate/MemberNameFilter.java
new file mode 100644
index 0000000..1447a25
--- /dev/null
+++ b/src/proguard/obfuscate/MemberNameFilter.java
@@ -0,0 +1,120 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.obfuscate;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This <code>MemberVisitor</code> delegates its visits to another given
+ * <code>MemberVisitor</code>, but only when the visited member has a new name.
+ * Constructors are judged based on the class name.
+ *
+ * @see ClassObfuscator
+ * @see MemberObfuscator
+ *
+ * @author Eric Lafortune
+ */
+public class MemberNameFilter implements MemberVisitor
+{
+ private final MemberVisitor memberVisitor;
+
+
+ /**
+ * Creates a new MemberSpecialNameFilter.
+ * @param memberVisitor the <code>MemberVisitor</code> to which
+ * visits will be delegated.
+ */
+ public MemberNameFilter(MemberVisitor memberVisitor)
+ {
+ this.memberVisitor = memberVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ if (hasName(programField))
+ {
+ memberVisitor.visitProgramField(programClass, programField);
+ }
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (hasName(programClass, programMethod))
+ {
+ memberVisitor.visitProgramMethod(programClass, programMethod);
+ }
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ if (hasName(libraryField))
+ {
+ memberVisitor.visitLibraryField(libraryClass, libraryField);
+ }
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ if (hasName(libraryClass, libraryMethod))
+ {
+ memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
+ }
+ }
+
+
+ // Small utility methods.
+
+ /**
+ * Returns whether the given class has a new name.
+ */
+ private boolean hasName(Clazz clazz)
+ {
+ return ClassObfuscator.newClassName(clazz) != null;
+ }
+
+
+ /**
+ * Returns whether the given method has a new name.
+ */
+ private boolean hasName(Clazz clazz, Method method)
+ {
+ return
+ hasName(method) ||
+ (hasName(clazz) &&
+ method.getName(clazz).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT));
+ }
+
+
+ /**
+ * Returns whether the given class member has a new name.
+ */
+ private boolean hasName(Member member)
+ {
+ return MemberObfuscator.newMemberName(member) != null;
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/obfuscate/MemberObfuscator.java b/src/proguard/obfuscate/MemberObfuscator.java
index 332b849..7b30596 100644
--- a/src/proguard/obfuscate/MemberObfuscator.java
+++ b/src/proguard/obfuscate/MemberObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/MemberSpecialNameFilter.java b/src/proguard/obfuscate/MemberSpecialNameFilter.java
index f83374b..6da56da 100644
--- a/src/proguard/obfuscate/MemberSpecialNameFilter.java
+++ b/src/proguard/obfuscate/MemberSpecialNameFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -54,7 +54,7 @@
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- if (isSpecialName(programField))
+ if (hasSpecialName(programField))
{
memberVisitor.visitProgramField(programClass, programField);
}
@@ -63,7 +63,7 @@
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- if (isSpecialName(programMethod))
+ if (hasSpecialName(programMethod))
{
memberVisitor.visitProgramMethod(programClass, programMethod);
}
@@ -72,7 +72,7 @@
public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
{
- if (isSpecialName(libraryField))
+ if (hasSpecialName(libraryField))
{
memberVisitor.visitLibraryField(libraryClass, libraryField);
}
@@ -81,7 +81,7 @@
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
- if (isSpecialName(libraryMethod))
+ if (hasSpecialName(libraryMethod))
{
memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
}
@@ -94,7 +94,7 @@
* Returns whether the given class member has a special new name.
* @param member the class member.
*/
- private static boolean isSpecialName(Member member)
+ private static boolean hasSpecialName(Member member)
{
return SpecialNameFactory.isSpecialName(MemberObfuscator.newMemberName(member));
}
diff --git a/src/proguard/obfuscate/MultiMappingProcessor.java b/src/proguard/obfuscate/MultiMappingProcessor.java
index 4074ff8..8b67bb6 100644
--- a/src/proguard/obfuscate/MultiMappingProcessor.java
+++ b/src/proguard/obfuscate/MultiMappingProcessor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/NameAndTypeShrinker.java b/src/proguard/obfuscate/NameAndTypeShrinker.java
deleted file mode 100644
index 1284c82..0000000
--- a/src/proguard/obfuscate/NameAndTypeShrinker.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 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.obfuscate;
-
-import proguard.classfile.*;
-import proguard.classfile.constant.Constant;
-import proguard.classfile.editor.ConstantPoolRemapper;
-import proguard.classfile.visitor.ClassVisitor;
-
-
-/**
- * This ClassVisitor removes NameAndType constant pool entries
- * that are not marked as being used.
- *
- * @see NameAndTypeUsageMarker
- *
- * @author Eric Lafortune
- */
-public class NameAndTypeShrinker implements ClassVisitor
-{
- private int[] constantIndexMap;
- private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
-
-
- // Implementations for ClassVisitor.
-
- public void visitProgramClass(ProgramClass programClass)
- {
- // Shift the used constant pool entries together, filling out the
- // index map.
- programClass.u2constantPoolCount =
- shrinkConstantPool(programClass.constantPool,
- programClass.u2constantPoolCount);
-
-
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
- }
-
-
- public void visitLibraryClass(LibraryClass libraryClass)
- {
- }
-
-
- // Small utility methods.
-
- /**
- * Removes all NameAndType entries that are not marked as being used
- * from the given constant pool.
- * @return the new number of entries.
- */
- private int shrinkConstantPool(Constant[] constantPool, int length)
- {
- // Create a new index map, if necessary.
- if (constantIndexMap == null ||
- constantIndexMap.length < length)
- {
- constantIndexMap = new int[length];
- }
-
- int counter = 1;
- boolean isUsed = false;
-
- // Shift the used constant pool entries together.
- for (int index = 1; index < length; index++)
- {
- constantIndexMap[index] = counter;
-
- Constant constant = constantPool[index];
-
- // Don't update the flag if this is the second half of a long entry.
- if (constant != null)
- {
- isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
- NameAndTypeUsageMarker.isUsed(constant);
- }
-
- if (isUsed)
- {
- constantPool[counter++] = constant;
- }
- }
-
- // Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
-
- return counter;
- }
-}
diff --git a/src/proguard/obfuscate/NameAndTypeUsageMarker.java b/src/proguard/obfuscate/NameAndTypeUsageMarker.java
deleted file mode 100644
index cc779f0..0000000
--- a/src/proguard/obfuscate/NameAndTypeUsageMarker.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 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.obfuscate;
-
-import proguard.classfile.*;
-import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.ClassVisitor;
-
-/**
- * This ClassVisitor marks all NameAndType constant pool entries that are
- * being used in the program classes it visits.
- *
- * @see NameAndTypeShrinker
- *
- * @author Eric Lafortune
- */
-public class NameAndTypeUsageMarker
-extends SimplifiedVisitor
-implements ClassVisitor,
- ConstantVisitor,
- AttributeVisitor
-{
- // A visitor info flag to indicate the NameAndType constant pool entry is being used.
- private static final Object USED = new Object();
-
-
- // Implementations for ClassVisitor.
-
- public void visitProgramClass(ProgramClass programClass)
- {
- // Mark the NameAndType entries referenced by all other constant pool
- // entries.
- programClass.constantPoolEntriesAccept(this);
-
- // Mark the NameAndType entries referenced by all EnclosingMethod
- // attributes.
- programClass.attributesAccept(this);
- }
-
-
- // Implementations for ConstantVisitor.
-
- public void visitAnyConstant(Clazz clazz, Constant constant) {}
-
-
- public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
- {
- visitRefConstant(clazz, fieldrefConstant);
- }
-
-
- public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
- {
- visitRefConstant(clazz, interfaceMethodrefConstant);
- }
-
-
- public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
- {
- visitRefConstant(clazz, methodrefConstant);
- }
-
-
- private void visitRefConstant(Clazz clazz, RefConstant refConstant)
- {
- markNameAndTypeConstant(clazz, refConstant.u2nameAndTypeIndex);
- }
-
-
- // Implementations for AttributeVisitor.
-
- public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
-
-
- public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
- {
- if (enclosingMethodAttribute.u2nameAndTypeIndex != 0)
- {
- markNameAndTypeConstant(clazz, enclosingMethodAttribute.u2nameAndTypeIndex);
- }
- }
-
-
- // Small utility methods.
-
- /**
- * Marks the given UTF-8 constant pool entry of the given class.
- */
- private void markNameAndTypeConstant(Clazz clazz, int index)
- {
- markAsUsed((NameAndTypeConstant)((ProgramClass)clazz).getConstant(index));
- }
-
-
- /**
- * Marks the given VisitorAccepter as being used.
- * In this context, the VisitorAccepter will be a NameAndTypeConstant object.
- */
- private static void markAsUsed(VisitorAccepter visitorAccepter)
- {
- visitorAccepter.setVisitorInfo(USED);
- }
-
-
- /**
- * Returns whether the given VisitorAccepter has been marked as being used.
- * In this context, the VisitorAccepter will be a NameAndTypeConstant object.
- */
- static boolean isUsed(VisitorAccepter visitorAccepter)
- {
- return visitorAccepter.getVisitorInfo() == USED;
- }
-}
diff --git a/src/proguard/obfuscate/NameFactory.java b/src/proguard/obfuscate/NameFactory.java
index c64d1ad..9585381 100644
--- a/src/proguard/obfuscate/NameFactory.java
+++ b/src/proguard/obfuscate/NameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/NameFactoryResetter.java b/src/proguard/obfuscate/NameFactoryResetter.java
index b6ba6ad..f3e889d 100644
--- a/src/proguard/obfuscate/NameFactoryResetter.java
+++ b/src/proguard/obfuscate/NameFactoryResetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/NameMarker.java b/src/proguard/obfuscate/NameMarker.java
index 2ce0ee9..130260c 100644
--- a/src/proguard/obfuscate/NameMarker.java
+++ b/src/proguard/obfuscate/NameMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/NumericNameFactory.java b/src/proguard/obfuscate/NumericNameFactory.java
index cc21c4b..5a6e3b4 100644
--- a/src/proguard/obfuscate/NumericNameFactory.java
+++ b/src/proguard/obfuscate/NumericNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/Obfuscator.java b/src/proguard/obfuscate/Obfuscator.java
index dce563a..5f58a83 100644
--- a/src/proguard/obfuscate/Obfuscator.java
+++ b/src/proguard/obfuscate/Obfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -99,19 +99,30 @@
libraryClassPool.classesAccept(new AllMemberVisitor(nameMarker));
// Mark attributes that have to be kept.
- AttributeUsageMarker requiredAttributeUsageMarker =
- new AttributeUsageMarker();
+ AttributeVisitor attributeUsageMarker =
+ new NonEmptyAttributeFilter(
+ new AttributeUsageMarker());
AttributeVisitor optionalAttributeUsageMarker =
configuration.keepAttributes == null ? null :
new AttributeNameFilter(new ListParser(new NameParser()).parse(configuration.keepAttributes),
- requiredAttributeUsageMarker);
+ attributeUsageMarker);
programClassPool.classesAccept(
new AllAttributeVisitor(true,
- new RequiredAttributeFilter(requiredAttributeUsageMarker,
+ new RequiredAttributeFilter(attributeUsageMarker,
optionalAttributeUsageMarker)));
+ // Keep parameter names and types if specified.
+ if (configuration.keepParameterNames)
+ {
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new MemberNameFilter(
+ new AllAttributeVisitor(true,
+ new ParameterNameMarker(attributeUsageMarker)))));
+ }
+
// Remove the attributes that can be discarded. Note that the attributes
// may only be discarded after the seeds have been marked, since the
// configuration may rely on annotations.
@@ -398,23 +409,28 @@
programClassPool.classesAccept(
new AllConstantVisitor(
new AccessFixer()));
+
+ // Fix the access flags of the inner classes information.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllInnerClassesInfoVisitor(
+ new InnerClassesAccessFixer())));
}
+ // Fix the bridge method flags.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new BridgeMethodFixer()));
+
// Rename the source file attributes, if requested.
if (configuration.newSourceFileAttribute != null)
{
programClassPool.classesAccept(new SourceFileRenamer(configuration.newSourceFileAttribute));
}
- // Mark NameAndType constant pool entries that have to be kept
- // and remove the other ones.
- programClassPool.classesAccept(new NameAndTypeUsageMarker());
- programClassPool.classesAccept(new NameAndTypeShrinker());
-
- // Mark Utf8 constant pool entries that have to be kept
- // and remove the other ones.
- programClassPool.classesAccept(new Utf8UsageMarker());
- programClassPool.classesAccept(new Utf8Shrinker());
+ // Remove unused constants.
+ programClassPool.classesAccept(
+ new ConstantPoolShrinker());
}
diff --git a/src/proguard/obfuscate/ParameterNameMarker.java b/src/proguard/obfuscate/ParameterNameMarker.java
new file mode 100644
index 0000000..2c3a3db
--- /dev/null
+++ b/src/proguard/obfuscate/ParameterNameMarker.java
@@ -0,0 +1,128 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.obfuscate;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.util.*;
+
+/**
+ * This AttributeVisitor trims and marks all local variable (type) table
+ * attributes that it visits. It keeps parameter names and types and removes
+ * the ordinary local variable names and types.
+ *
+ * @author Eric Lafortune
+ */
+public class ParameterNameMarker
+extends SimplifiedVisitor
+implements AttributeVisitor
+{
+ private final AttributeVisitor attributeUsageMarker;
+
+
+ /**
+ * Constructs a new ParameterNameMarker.
+ * @param attributeUsageMarker the marker that will be used to mark
+ * attributes containing local variable info.
+ */
+ public ParameterNameMarker(AttributeVisitor attributeUsageMarker)
+ {
+ this.attributeUsageMarker = attributeUsageMarker;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ if (!AttributeUsageMarker.isUsed(localVariableTableAttribute) &&
+ hasParameters(clazz, method))
+ {
+ // Shift the entries that start at offset 0 to the front.
+ int newIndex = 0;
+
+ for (int index = 0; index < localVariableTableAttribute.u2localVariableTableLength; index++)
+ {
+ LocalVariableInfo localVariableInfo =
+ localVariableTableAttribute.localVariableTable[index];
+
+ if (localVariableInfo.u2startPC == 0)
+ {
+ localVariableTableAttribute.localVariableTable[newIndex++] =
+ localVariableInfo;
+ }
+ }
+
+ // Trim the table.
+ localVariableTableAttribute.u2localVariableTableLength = newIndex;
+
+ // Mark the table if there are any entries.
+ if (newIndex > 0)
+ {
+ attributeUsageMarker.visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute);
+ }
+ }
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ if (!AttributeUsageMarker.isUsed(localVariableTypeTableAttribute) &&
+ hasParameters(clazz, method))
+ {
+ // Shift the entries that start at offset 0 to the front.
+ int newIndex = 0;
+
+ for (int index = 0; index < localVariableTypeTableAttribute.u2localVariableTypeTableLength; index++)
+ {
+ LocalVariableTypeInfo localVariableTypeInfo =
+ localVariableTypeTableAttribute.localVariableTypeTable[index];
+
+ if (localVariableTypeInfo.u2startPC == 0)
+ {
+ localVariableTypeTableAttribute.localVariableTypeTable[newIndex++] =
+ localVariableTypeInfo;
+ }
+ }
+
+ // Trim the table.
+ localVariableTypeTableAttribute.u2localVariableTypeTableLength = newIndex;
+
+ // Mark the table if there are any entries.
+ if (newIndex > 0)
+ {
+ attributeUsageMarker.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute);
+ }
+ }
+ }
+
+
+ // Small utility methods.
+
+ private boolean hasParameters(Clazz clazz, Method method)
+ {
+ return method.getDescriptor(clazz).charAt(1) != ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE;
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/obfuscate/SimpleNameFactory.java b/src/proguard/obfuscate/SimpleNameFactory.java
index bce22de..d9b770b 100644
--- a/src/proguard/obfuscate/SimpleNameFactory.java
+++ b/src/proguard/obfuscate/SimpleNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/SourceFileRenamer.java b/src/proguard/obfuscate/SourceFileRenamer.java
index cbf1b63..8805b08 100644
--- a/src/proguard/obfuscate/SourceFileRenamer.java
+++ b/src/proguard/obfuscate/SourceFileRenamer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/SpecialNameFactory.java b/src/proguard/obfuscate/SpecialNameFactory.java
index a5431ca..07c1674 100644
--- a/src/proguard/obfuscate/SpecialNameFactory.java
+++ b/src/proguard/obfuscate/SpecialNameFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/obfuscate/Utf8Shrinker.java b/src/proguard/obfuscate/Utf8Shrinker.java
deleted file mode 100644
index 87ada80..0000000
--- a/src/proguard/obfuscate/Utf8Shrinker.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * ProGuard -- shrinking, optimization, obfuscation, and preverification
- * of Java bytecode.
- *
- * Copyright (c) 2002-2009 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.obfuscate;
-
-import proguard.classfile.*;
-import proguard.classfile.constant.Constant;
-import proguard.classfile.editor.ConstantPoolRemapper;
-import proguard.classfile.visitor.ClassVisitor;
-
-
-/**
- * This ClassVisitor removes UTF-8 constant pool entries that are not marked
- * as being used.
- *
- * @see Utf8UsageMarker
- *
- * @author Eric Lafortune
- */
-public class Utf8Shrinker implements ClassVisitor
-{
- private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
- private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
-
-
- // Implementations for ClassVisitor.
-
- public void visitProgramClass(ProgramClass programClass)
- {
- // Shift the used constant pool entries together, filling out the
- // index map.
- programClass.u2constantPoolCount =
- shrinkConstantPool(programClass.constantPool,
- programClass.u2constantPoolCount);
-
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
- }
-
-
- public void visitLibraryClass(LibraryClass libraryClass)
- {
- }
-
-
- // Small utility methods.
-
- /**
- * Removes all UTF-8 entries that are not marked as being used
- * from the given constant pool.
- * @return the new number of entries.
- */
- private int shrinkConstantPool(Constant[] constantPool, int length)
- {
- // Create a new index map, if necessary.
- if (constantIndexMap.length < length)
- {
- constantIndexMap = new int[length];
- }
-
- int counter = 1;
- boolean isUsed = false;
-
- // Shift the used constant pool entries together.
- for (int index = 1; index < length; index++)
- {
- constantIndexMap[index] = counter;
-
- Constant constant = constantPool[index];
-
- // Don't update the flag if this is the second half of a long entry.
- if (constant != null)
- {
- isUsed = constant.getTag() != ClassConstants.CONSTANT_Utf8 ||
- Utf8UsageMarker.isUsed(constant);
- }
-
- if (isUsed)
- {
- constantPool[counter++] = constant;
- }
- }
-
- // Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
-
- return counter;
- }
-}
diff --git a/src/proguard/optimize/BootstrapMethodArgumentShrinker.java b/src/proguard/optimize/BootstrapMethodArgumentShrinker.java
new file mode 100644
index 0000000..70d031d
--- /dev/null
+++ b/src/proguard/optimize/BootstrapMethodArgumentShrinker.java
@@ -0,0 +1,103 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.constant.*;
+import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.editor.ConstantPoolEditor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.MemberVisitor;
+import proguard.optimize.info.*;
+import proguard.optimize.peephole.VariableShrinker;
+
+/**
+ * This BootstrapMethodInfoVisitor removes unused constant arguments from
+ * bootstrap method entries that it visits.
+ *
+ * @see ParameterUsageMarker
+ * @see VariableUsageMarker
+ * @see VariableShrinker
+ * @author Eric Lafortune
+ */
+public class BootstrapMethodArgumentShrinker
+extends SimplifiedVisitor
+implements BootstrapMethodInfoVisitor,
+ ConstantVisitor,
+ MemberVisitor
+{
+ private long usedParameters;
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ // Check which method parameters are used.
+ usedParameters = -1L;
+ clazz.constantPoolEntryAccept(bootstrapMethodInfo.u2methodHandleIndex, this);
+
+ // Remove the unused arguments.
+ int methodArgumentCount = bootstrapMethodInfo.u2methodArgumentCount;
+ int[] methodArguments = bootstrapMethodInfo.u2methodArguments;
+
+ int newArgumentIndex = 0;
+
+ for (int argumentIndex = 0; argumentIndex < methodArgumentCount; argumentIndex++)
+ {
+ if (argumentIndex >= 64 ||
+ (usedParameters & (1L << argumentIndex)) != 0L)
+ {
+ methodArguments[newArgumentIndex++] = methodArguments[argumentIndex];
+ }
+ }
+
+ // Update the number of arguments.
+ bootstrapMethodInfo.u2methodArgumentCount = newArgumentIndex;
+ }
+
+
+ // Implementations for ConstantVisitor.
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the referenced bootstrap method.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
+ public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
+ {
+ // Check the referenced class member itself.
+ refConstant.referencedMemberAccept(this);
+ }
+
+
+ // Implementations for MemberVisitor.
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ usedParameters = ParameterUsageMarker.getUsedParameters(programMethod);
+ }
+}
diff --git a/src/proguard/optimize/ChangedCodePrinter.java b/src/proguard/optimize/ChangedCodePrinter.java
index 67a79ab..e0d00b8 100644
--- a/src/proguard/optimize/ChangedCodePrinter.java
+++ b/src/proguard/optimize/ChangedCodePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -54,6 +54,12 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute);
diff --git a/src/proguard/optimize/ConstantMemberFilter.java b/src/proguard/optimize/ConstantMemberFilter.java
index 56437c3..d3a8207 100644
--- a/src/proguard/optimize/ConstantMemberFilter.java
+++ b/src/proguard/optimize/ConstantMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/ConstantParameterFilter.java b/src/proguard/optimize/ConstantParameterFilter.java
index 24a7040..6920990 100644
--- a/src/proguard/optimize/ConstantParameterFilter.java
+++ b/src/proguard/optimize/ConstantParameterFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/DuplicateInitializerFixer.java b/src/proguard/optimize/DuplicateInitializerFixer.java
index 746d182..07b7d82 100644
--- a/src/proguard/optimize/DuplicateInitializerFixer.java
+++ b/src/proguard/optimize/DuplicateInitializerFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -86,7 +86,7 @@
if (!programMethod.equals(similarMethod))
{
// Should this initializer be preserved?
- if (!KeepMarker.isKept(programMethod))
+ if (KeepMarker.isKept(programMethod))
{
// Fix the other initializer.
programMethod = (ProgramMethod)similarMethod;
@@ -95,12 +95,23 @@
int index = descriptor.indexOf(ClassConstants.INTERNAL_METHOD_ARGUMENTS_CLOSE);
// Try to find a new, unique descriptor.
- for (int typeIndex = 0; typeIndex < TYPES.length; typeIndex++)
+ int typeCounter = 0;
+ while (true)
{
- String newDescriptor =
- descriptor.substring(0, index) +
- TYPES[typeIndex] +
- descriptor.substring(index);
+ // Construct the new descriptor by inserting a new type
+ // as an additional last argument.
+ StringBuffer newDescriptorBuffer =
+ new StringBuffer(descriptor.substring(0, index));
+
+ for (int arrayDimension = 0; arrayDimension < typeCounter / TYPES.length; arrayDimension++)
+ {
+ newDescriptorBuffer.append(ClassConstants.INTERNAL_TYPE_ARRAY);
+ }
+
+ newDescriptorBuffer.append(TYPES[typeCounter % TYPES.length]);
+ newDescriptorBuffer.append(descriptor.substring(index));
+
+ String newDescriptor = newDescriptorBuffer.toString();
// Is the new initializer descriptor unique?
if (programClass.findMethod(name, newDescriptor) == null)
@@ -108,7 +119,7 @@
if (DEBUG)
{
System.out.println("DuplicateInitializerFixer:");
- System.out.println(" ["+programClass.getName()+"]: "+name+descriptor+" -> "+newDescriptor);
+ System.out.println(" ["+programClass.getName()+"."+name+descriptor+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") -> ["+newDescriptor+"]");
}
// Update the descriptor.
@@ -130,12 +141,9 @@
// We're done with this constructor.
return;
}
- }
- throw new IllegalStateException("Can't find unique constructor descriptor for ["+
- programClass.getName()+"."+
- programMethod.getName(programClass)+
- programMethod.getDescriptor(programClass)+"]");
+ typeCounter++;
+ }
}
}
}
diff --git a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java b/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
index ca24481..e900232 100644
--- a/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
+++ b/src/proguard/optimize/DuplicateInitializerInvocationFixer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,7 +28,7 @@
import proguard.classfile.editor.CodeAttributeEditor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
/**
@@ -48,12 +48,12 @@
private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
- private String descriptor;
- private boolean hasBeenFixed;
+ private String descriptor;
+ private int descriptorLengthDelta;
/**
- * Creates a new EvaluationSimplifier.
+ * Creates a new DuplicateInitializerInvocationFixer.
*/
public DuplicateInitializerInvocationFixer()
{
@@ -62,7 +62,7 @@
/**
- * Creates a new EvaluationSimplifier.
+ * Creates a new DuplicateInitializerInvocationFixer.
* @param extraAddedInstructionVisitor an optional extra visitor for all
* added instructions.
*/
@@ -102,21 +102,22 @@
{
if (constantInstruction.opcode == InstructionConstants.OP_INVOKESPECIAL)
{
- hasBeenFixed = false;
+ descriptorLengthDelta = 0;
clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
- if (hasBeenFixed)
+ if (descriptorLengthDelta > 0)
{
Instruction extraInstruction =
- new SimpleInstruction(InstructionConstants.OP_ICONST_0);
+ new SimpleInstruction(descriptorLengthDelta == 1 ?
+ InstructionConstants.OP_ICONST_0 :
+ InstructionConstants.OP_ACONST_NULL);
codeAttributeEditor.insertBeforeInstruction(offset,
extraInstruction);
if (DEBUG)
{
- System.out.println("DuplicateInitializerInvocationFixer:");
- System.out.println(" Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset));
+ System.out.println(" ["+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"] Inserting "+extraInstruction.toString()+" before "+constantInstruction.toString(offset));
}
if (extraAddedInstructionVisitor != null)
@@ -145,6 +146,16 @@
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- hasBeenFixed = !descriptor.equals(programMethod.getDescriptor(programClass));
+ descriptorLengthDelta =
+ programMethod.getDescriptor(programClass).length() - descriptor.length();
+
+ if (DEBUG)
+ {
+ if (descriptorLengthDelta > 0)
+ {
+ System.out.println("DuplicateInitializerInvocationFixer:");
+ System.out.println(" ["+programClass.getName()+"."+programMethod.getName(programClass)+programMethod.getDescriptor(programClass)+"] ("+ClassUtil.externalClassAccessFlags(programMethod.getAccessFlags())+") referenced by:");
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/src/proguard/optimize/KeepMarker.java b/src/proguard/optimize/KeepMarker.java
index 4297996..f8087be 100644
--- a/src/proguard/optimize/KeepMarker.java
+++ b/src/proguard/optimize/KeepMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/KeptClassFilter.java b/src/proguard/optimize/KeptClassFilter.java
new file mode 100644
index 0000000..4b9d090
--- /dev/null
+++ b/src/proguard/optimize/KeptClassFilter.java
@@ -0,0 +1,69 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor delegates all its method calls to another ClassVisitor,
+ * but only for Clazz objects that are marked as kept.
+ *
+ * @see KeepMarker
+ *
+ * @author Eric Lafortune
+ */
+public class KeptClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ /**
+ * Creates a new KeptClassFilter.
+ * @param classVisitor the class visitor to which the visiting will be
+ * delegated.
+ */
+ public KeptClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (KeepMarker.isKept(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (KeepMarker.isKept(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/optimize/KeptMemberFilter.java b/src/proguard/optimize/KeptMemberFilter.java
new file mode 100644
index 0000000..5b25425
--- /dev/null
+++ b/src/proguard/optimize/KeptMemberFilter.java
@@ -0,0 +1,88 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.optimize;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.MemberVisitor;
+
+/**
+ * This MemberVisitor delegates all its method calls to another MemberVisitor,
+ * but only for Member objects that are marked as kept.
+ *
+ * @see KeepMarker
+ *
+ * @author Eric Lafortune
+ */
+public class KeptMemberFilter
+implements MemberVisitor
+{
+ private final MemberVisitor memberVisitor;
+
+
+ /**
+ * Creates a new KeptMemberFilter.
+ * @param memberVisitor the member visitor to which the visiting will be
+ * delegated.
+ */
+ public KeptMemberFilter(MemberVisitor memberVisitor)
+ {
+ this.memberVisitor = memberVisitor;
+ }
+
+
+ // Implementations for MemberVisitor.
+
+
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ if (KeepMarker.isKept(programField))
+ {
+ memberVisitor.visitProgramField(programClass, programField);
+ }
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (KeepMarker.isKept(programMethod))
+ {
+ memberVisitor.visitProgramMethod(programClass, programMethod);
+ }
+ }
+
+
+ public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
+ {
+ if (KeepMarker.isKept(libraryField))
+ {
+ memberVisitor.visitLibraryField(libraryClass, libraryField);
+ }
+ }
+
+
+ public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
+ {
+ if (KeepMarker.isKept(libraryMethod))
+ {
+ memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/optimize/MemberDescriptorSpecializer.java b/src/proguard/optimize/MemberDescriptorSpecializer.java
index 0d0b841..7f051f5 100644
--- a/src/proguard/optimize/MemberDescriptorSpecializer.java
+++ b/src/proguard/optimize/MemberDescriptorSpecializer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -39,7 +39,7 @@
extends SimplifiedVisitor
implements MemberVisitor
{
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
private final MemberVisitor extraParameterMemberVisitor;
diff --git a/src/proguard/optimize/MethodDescriptorShrinker.java b/src/proguard/optimize/MethodDescriptorShrinker.java
index 48374e7..f4667ee 100644
--- a/src/proguard/optimize/MethodDescriptorShrinker.java
+++ b/src/proguard/optimize/MethodDescriptorShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -23,7 +23,7 @@
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.editor.ConstantPoolEditor;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
@@ -95,11 +95,9 @@
if (DEBUG)
{
System.out.println("MethodDescriptorShrinker:");
- System.out.println(" Class file = "+programClass.getName());
- System.out.println(" Method name = "+name);
- System.out.println(" -> "+newName);
- System.out.println(" Method descriptor = "+descriptor);
- System.out.println(" -> "+newDescriptor);
+ System.out.println(" ["+programClass.getName()+"."+
+ name+descriptor+"] -> ["+
+ newName+newDescriptor+"]");
}
ConstantPoolEditor constantPoolEditor =
diff --git a/src/proguard/optimize/MethodStaticizer.java b/src/proguard/optimize/MethodStaticizer.java
index 8dd11e1..9bd7b2a 100644
--- a/src/proguard/optimize/MethodStaticizer.java
+++ b/src/proguard/optimize/MethodStaticizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/OptimizationInfoMemberFilter.java b/src/proguard/optimize/OptimizationInfoMemberFilter.java
index 8760aee..a6d3cc7 100644
--- a/src/proguard/optimize/OptimizationInfoMemberFilter.java
+++ b/src/proguard/optimize/OptimizationInfoMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/Optimizer.java b/src/proguard/optimize/Optimizer.java
index a3e8a6e..c5db18b 100644
--- a/src/proguard/optimize/Optimizer.java
+++ b/src/proguard/optimize/Optimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -23,7 +23,8 @@
import proguard.*;
import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
-import proguard.classfile.constant.visitor.AllConstantVisitor;
+import proguard.classfile.constant.Constant;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.editor.*;
import proguard.classfile.instruction.visitor.*;
import proguard.classfile.util.MethodLinker;
@@ -66,6 +67,7 @@
private static final String CODE_SIMPLIFICATION_CAST = "code/simplification/cast";
private static final String CODE_SIMPLIFICATION_FIELD = "code/simplification/field";
private static final String CODE_SIMPLIFICATION_BRANCH = "code/simplification/branch";
+ private static final String CODE_SIMPLIFICATION_STRING = "code/simplification/string";
private static final String CODE_SIMPLIFICATION_ADVANCED = "code/simplification/advanced";
private static final String CODE_REMOVAL_ADVANCED = "code/removal/advanced";
private static final String CODE_REMOVAL_SIMPLE = "code/removal/simple";
@@ -80,6 +82,7 @@
CLASS_MERGING_VERTICAL,
CLASS_MERGING_HORIZONTAL,
FIELD_REMOVAL_WRITEONLY,
+ FIELD_MARKING_PRIVATE,
FIELD_PROPAGATION_VALUE,
METHOD_MARKING_PRIVATE,
METHOD_MARKING_STATIC,
@@ -96,6 +99,7 @@
CODE_SIMPLIFICATION_CAST,
CODE_SIMPLIFICATION_FIELD,
CODE_SIMPLIFICATION_BRANCH,
+ CODE_SIMPLIFICATION_STRING,
CODE_SIMPLIFICATION_ADVANCED,
CODE_REMOVAL_ADVANCED,
CODE_REMOVAL_SIMPLE,
@@ -157,6 +161,7 @@
boolean codeSimplificationCast = filter.matches(CODE_SIMPLIFICATION_CAST);
boolean codeSimplificationField = filter.matches(CODE_SIMPLIFICATION_FIELD);
boolean codeSimplificationBranch = filter.matches(CODE_SIMPLIFICATION_BRANCH);
+ boolean codeSimplificationString = filter.matches(CODE_SIMPLIFICATION_STRING);
boolean codeSimplificationAdvanced = filter.matches(CODE_SIMPLIFICATION_ADVANCED);
boolean codeRemovalAdvanced = filter.matches(CODE_REMOVAL_ADVANCED);
boolean codeRemovalSimple = filter.matches(CODE_REMOVAL_SIMPLE);
@@ -186,13 +191,15 @@
InstructionCounter codeSimplificationCastCounter = new InstructionCounter();
InstructionCounter codeSimplificationFieldCounter = new InstructionCounter();
InstructionCounter codeSimplificationBranchCounter = new InstructionCounter();
+ InstructionCounter codeSimplificationStringCounter = new InstructionCounter();
InstructionCounter codeSimplificationAdvancedCounter = new InstructionCounter();
InstructionCounter deletedCounter = new InstructionCounter();
InstructionCounter addedCounter = new InstructionCounter();
MemberCounter codeRemovalVariableCounter = new MemberCounter();
ExceptionCounter codeRemovalExceptionCounter = new ExceptionCounter();
MemberCounter codeAllocationVariableCounter = new MemberCounter();
- MemberCounter initializerFixCounter = new MemberCounter();
+ MemberCounter initializerFixCounter1 = new MemberCounter();
+ MemberCounter initializerFixCounter2 = new MemberCounter();
// Some optimizations are required by other optimizations.
codeSimplificationAdvanced =
@@ -250,10 +257,27 @@
new AllInstructionVisitor(
new DotClassClassVisitor(keepMarker)))));
- // We also keep all classes that are involved in Class.forName constructs.
+ // We also keep all classes that are accessed dynamically.
programClassPool.classesAccept(
new AllConstantVisitor(
- new ClassForNameClassVisitor(keepMarker)));
+ new ConstantTagFilter(ClassConstants.CONSTANT_String,
+ new ReferencedClassVisitor(keepMarker))));
+
+ // We also keep all class members that are accessed dynamically.
+ programClassPool.classesAccept(
+ new AllConstantVisitor(
+ new ConstantTagFilter(ClassConstants.CONSTANT_String,
+ new ReferencedMemberVisitor(keepMarker))));
+
+ // We also keep all bootstrap method signatures.
+ programClassPool.classesAccept(
+ new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_7,
+ new AllAttributeVisitor(
+ new AttributeNameFilter(ClassConstants.ATTR_BootstrapMethods,
+ new AllBootstrapMethodInfoVisitor(
+ new BootstrapMethodHandleTraveler(
+ new MethodrefTraveler(
+ new ReferencedMemberVisitor(keepMarker))))))));
// Attach some optimization info to all classes and class members, so
// it can be filled out later.
@@ -320,6 +344,9 @@
new ParameterUsageMarker(!methodMarkingStatic,
!methodRemovalParameter))));
+ // Mark all classes that have static initializers.
+ programClassPool.classesAccept(new StaticInitializerContainingClassMarker());
+
// Mark all methods that have side effects.
programClassPool.accept(new SideEffectMethodMarker());
@@ -347,18 +374,29 @@
new AllAttributeVisitor(
new PartialEvaluator(valueFactory, storingInvocationUnit, false))));
- // Count the constant fields and methods.
- programClassPool.classesAccept(
- new MultiClassVisitor(
- new ClassVisitor[]
- {
+ if (fieldPropagationValue)
+ {
+ // Count the constant fields.
+ programClassPool.classesAccept(
new AllFieldVisitor(
- new ConstantMemberFilter(fieldPropagationValueCounter)),
+ new ConstantMemberFilter(fieldPropagationValueCounter)));
+ }
+
+ if (methodPropagationParameter)
+ {
+ // Count the constant method parameters.
+ programClassPool.classesAccept(
new AllMethodVisitor(
- new ConstantParameterFilter(methodPropagationParameterCounter)),
+ new ConstantParameterFilter(methodPropagationParameterCounter)));
+ }
+
+ if (methodPropagationReturnvalue)
+ {
+ // Count the constant method return values.
+ programClassPool.classesAccept(
new AllMethodVisitor(
- new ConstantMemberFilter(methodPropagationReturnvalueCounter)),
- }));
+ new ConstantMemberFilter(methodPropagationReturnvalueCounter)));
+ }
}
InvocationUnit loadingInvocationUnit =
@@ -418,6 +456,12 @@
// This operation also updates the stack sizes.
programClassPool.classesAccept(
new MemberReferenceFixer());
+
+ // Remove unused bootstrap method arguments.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllBootstrapMethodInfoVisitor(
+ new BootstrapMethodArgumentShrinker())));
}
if (methodRemovalParameter ||
@@ -441,17 +485,39 @@
new StackSizeUpdater())));
}
-// // Specializing the class member descriptors seems to increase the
-// // class file size, on average.
-// // Specialize all class member descriptors.
-// programClassPool.classesAccept(new AllMemberVisitor(
-// new OptimizationInfoMemberFilter(
-// new MemberDescriptorSpecializer())));
-//
-// // Fix all references to classes, for MemberDescriptorSpecializer.
-// programClassPool.classesAccept(new AllMemberVisitor(
-// new OptimizationInfoMemberFilter(
-// new ClassReferenceFixer(true))));
+ if (methodRemovalParameter &&
+ methodRemovalParameterCounter.getCount() > 0)
+ {
+ // Tweak the descriptors of duplicate initializers, due to removed
+ // method parameters.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new DuplicateInitializerFixer(initializerFixCounter1)));
+
+ if (initializerFixCounter1.getCount() > 0)
+ {
+ // Fix all invocations of tweaked initializers.
+ programClassPool.classesAccept(
+ new AllMethodVisitor(
+ new AllAttributeVisitor(
+ new DuplicateInitializerInvocationFixer(addedCounter))));
+
+ // Fix all references to tweaked initializers.
+ programClassPool.classesAccept(new MemberReferenceFixer());
+ }
+ }
+
+ //// Specializing the class member descriptors seems to increase the
+ //// class file size, on average.
+ //// Specialize all class member descriptors.
+ //programClassPool.classesAccept(new AllMemberVisitor(
+ // new OptimizationInfoMemberFilter(
+ // new MemberDescriptorSpecializer())));
+ //
+ //// Fix all references to classes, for MemberDescriptorSpecializer.
+ //programClassPool.classesAccept(new AllMemberVisitor(
+ // new OptimizationInfoMemberFilter(
+ // new ClassReferenceFixer(true))));
// Mark all classes with package visible members.
// Mark all exception catches of methods.
@@ -461,13 +527,13 @@
new MultiClassVisitor(
new ClassVisitor[]
{
+ new PackageVisibleMemberContainingClassMarker(),
new AllConstantVisitor(
new PackageVisibleMemberInvokingClassMarker()),
new AllMethodVisitor(
new MultiMemberVisitor(
new MemberVisitor[]
{
- new PackageVisibleMemberContainingClassMarker(),
new AllAttributeVisitor(
new MultiAttributeVisitor(
new AttributeVisitor[]
@@ -511,8 +577,8 @@
classMergingHorizontalCounter));
}
- if (classMergingVertical ||
- classMergingHorizontal)
+ if (classMergingVerticalCounter .getCount() > 0 ||
+ classMergingHorizontalCounter.getCount() > 0)
{
// Clean up inner class attributes to avoid loops.
programClassPool.classesAccept(new RetargetedInnerClassAttributeRemover());
@@ -530,18 +596,20 @@
new AllConstantVisitor(
new AccessFixer()));
}
- }
- if (methodRemovalParameter ||
- classMergingVertical ||
- classMergingHorizontal)
- {
- // Tweak the descriptors of duplicate initializers.
+ // Fix the access flags of the inner classes information.
+ programClassPool.classesAccept(
+ new AllAttributeVisitor(
+ new AllInnerClassesInfoVisitor(
+ new InnerClassesAccessFixer())));
+
+ // Tweak the descriptors of duplicate initializers, due to merged
+ // parameter classes.
programClassPool.classesAccept(
new AllMethodVisitor(
- new DuplicateInitializerFixer(initializerFixCounter)));
+ new DuplicateInitializerFixer(initializerFixCounter2)));
- if (initializerFixCounter.getCount() > 0)
+ if (initializerFixCounter2.getCount() > 0)
{
// Fix all invocations of tweaked initializers.
programClassPool.classesAccept(
@@ -595,14 +663,14 @@
new NonPrivateMemberMarker());
}
- if (fieldMarkingPrivate ||
- methodMarkingPrivate)
+ if (fieldMarkingPrivate)
{
// Make all non-private fields private, whereever possible.
programClassPool.classesAccept(
+ new ClassAccessFilter(0, ClassConstants.INTERNAL_ACC_INTERFACE,
new AllFieldVisitor(
new MemberAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
- new MemberPrivatizer(fieldMarkingPrivateCounter))));
+ new MemberPrivatizer(fieldMarkingPrivateCounter)))));
}
if (methodMarkingPrivate)
@@ -615,9 +683,9 @@
new MemberPrivatizer(methodMarkingPrivateCounter)))));
}
- if ((methodInliningUnique ||
- methodInliningShort ||
- methodInliningTailrecursion) &&
+ if ((methodInliningUniqueCounter .getCount() > 0 ||
+ methodInliningShortCounter .getCount() > 0 ||
+ methodInliningTailrecursionCounter.getCount() > 0) &&
configuration.allowAccessModification)
{
// Fix the access flags of referenced classes and class members,
@@ -627,10 +695,10 @@
new AccessFixer()));
}
- if (methodRemovalParameter ||
- classMergingVertical ||
- classMergingHorizontal ||
- methodMarkingPrivate)
+ if (methodRemovalParameterCounter .getCount() > 0 ||
+ classMergingVerticalCounter .getCount() > 0 ||
+ classMergingHorizontalCounter .getCount() > 0 ||
+ methodMarkingPrivateCounter .getCount() > 0 )
{
// Fix invocations of interface methods, of methods that have become
// non-abstract or private, and of methods that have moved to a
@@ -707,6 +775,15 @@
new GotoReturnReplacer(codeAttributeEditor, codeSimplificationBranchCounter));
}
+ if (codeSimplificationString)
+ {
+ // Peephole optimizations involving branches.
+ peepholeOptimizations.add(
+ new InstructionSequencesReplacer(InstructionSequenceConstants.CONSTANTS,
+ InstructionSequenceConstants.STRING,
+ branchTargetFinder, codeAttributeEditor, codeSimplificationStringCounter));
+ }
+
if (!peepholeOptimizations.isEmpty())
{
// Convert the list into an array.
@@ -749,14 +826,6 @@
new AllAttributeVisitor(
new VariableShrinker(codeRemovalVariableCounter))));
}
- else
- {
- // Clean up all unused local variables.
- programClassPool.classesAccept(
- new AllMethodVisitor(
- new AllAttributeVisitor(
- new VariableCleaner())));
- }
if (codeAllocationVariable)
{
@@ -767,6 +836,11 @@
new VariableOptimizer(false, codeAllocationVariableCounter))));
}
+
+ // Remove unused constants.
+ programClassPool.classesAccept(
+ new ConstantPoolShrinker());
+
int classMarkingFinalCount = classMarkingFinalCounter .getCount();
int classMergingVerticalCount = classMergingVerticalCounter .getCount();
int classMergingHorizontalCount = classMergingHorizontalCounter .getCount();
@@ -776,7 +850,7 @@
int methodMarkingPrivateCount = methodMarkingPrivateCounter .getCount();
int methodMarkingStaticCount = methodMarkingStaticCounter .getCount();
int methodMarkingFinalCount = methodMarkingFinalCounter .getCount();
- int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter.getCount();
+ int methodRemovalParameterCount = methodRemovalParameterCounter .getCount() - methodMarkingStaticCounter.getCount() - initializerFixCounter1.getCount() - initializerFixCounter2.getCount();
int methodPropagationParameterCount = methodPropagationParameterCounter .getCount();
int methodPropagationReturnvalueCount = methodPropagationReturnvalueCounter.getCount();
int methodInliningShortCount = methodInliningShortCounter .getCount();
@@ -788,12 +862,23 @@
int codeSimplificationCastCount = codeSimplificationCastCounter .getCount();
int codeSimplificationFieldCount = codeSimplificationFieldCounter .getCount();
int codeSimplificationBranchCount = codeSimplificationBranchCounter .getCount();
+ int codeSimplificationStringCount = codeSimplificationStringCounter .getCount();
int codeSimplificationAdvancedCount = codeSimplificationAdvancedCounter .getCount();
int codeRemovalCount = deletedCounter .getCount() - addedCounter.getCount();
int codeRemovalVariableCount = codeRemovalVariableCounter .getCount();
int codeRemovalExceptionCount = codeRemovalExceptionCounter .getCount();
int codeAllocationVariableCount = codeAllocationVariableCounter .getCount();
+ // Forget about constant fields, parameters, and return values, if they
+ // didn't lead to any useful optimizations. We want to avoid fruitless
+ // additional optimization passes.
+ if (codeSimplificationAdvancedCount == 0)
+ {
+ fieldPropagationValueCount = 0;
+ methodPropagationParameterCount = 0;
+ methodPropagationReturnvalueCount = 0;
+ }
+
if (configuration.verbose)
{
System.out.println(" Number of finalized classes: " + classMarkingFinalCount + disabled(classMarkingFinal));
@@ -817,6 +902,7 @@
System.out.println(" Number of cast peephole optimizations: " + codeSimplificationCastCount + disabled(codeSimplificationCast));
System.out.println(" Number of field peephole optimizations: " + codeSimplificationFieldCount + disabled(codeSimplificationField));
System.out.println(" Number of branch peephole optimizations: " + codeSimplificationBranchCount + disabled(codeSimplificationBranch));
+ System.out.println(" Number of string peephole optimizations: " + codeSimplificationStringCount + disabled(codeSimplificationString));
System.out.println(" Number of simplified instructions: " + codeSimplificationAdvancedCount + disabled(codeSimplificationAdvanced));
System.out.println(" Number of removed instructions: " + codeRemovalCount + disabled(codeRemovalAdvanced));
System.out.println(" Number of removed local variables: " + codeRemovalVariableCount + disabled(codeRemovalVariable));
@@ -845,6 +931,7 @@
codeSimplificationCastCount > 0 ||
codeSimplificationFieldCount > 0 ||
codeSimplificationBranchCount > 0 ||
+ codeSimplificationStringCount > 0 ||
codeSimplificationAdvancedCount > 0 ||
codeRemovalCount > 0 ||
codeRemovalVariableCount > 0 ||
diff --git a/src/proguard/optimize/ParameterShrinker.java b/src/proguard/optimize/ParameterShrinker.java
index a2bc6d3..2021861 100644
--- a/src/proguard/optimize/ParameterShrinker.java
+++ b/src/proguard/optimize/ParameterShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -23,7 +23,7 @@
import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.editor.*;
+import proguard.classfile.editor.VariableRemapper;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.optimize.info.ParameterUsageMarker;
diff --git a/src/proguard/optimize/TailRecursionSimplifier.java b/src/proguard/optimize/TailRecursionSimplifier.java
index 0946b6a..f01dcd9 100644
--- a/src/proguard/optimize/TailRecursionSimplifier.java
+++ b/src/proguard/optimize/TailRecursionSimplifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -54,9 +54,9 @@
private final CodeAttributeComposer codeAttributeComposer = new CodeAttributeComposer();
+ private final MyRecursionChecker recursionChecker = new MyRecursionChecker();
private Method targetMethod;
- private boolean recursive;
private boolean inlinedAny;
@@ -105,41 +105,34 @@
// clazz.getName().equals("abc/Def") &&
// method.getName(clazz).equals("abc");
- targetMethod = method;
- inlinedAny = false;
+ targetMethod = method;
+ inlinedAny = false;
codeAttributeComposer.reset();
- // Append the body of the code.
- copyCode(clazz, method, codeAttribute);
+ // The code may expand, due to expanding constant and variable
+ // instructions.
+ codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
+
+ // Copy the instructions.
+ codeAttribute.instructionsAccept(clazz, method, this);
// Update the code attribute if any code has been inlined.
if (inlinedAny)
{
+ // Copy the exceptions.
+ codeAttribute.exceptionsAccept(clazz, method, this);
+
+ // Append a label just after the code.
+ codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
+
+ codeAttributeComposer.endCodeFragment();
+
codeAttributeComposer.visitCodeAttribute(clazz, method, codeAttribute);
}
}
}
- /**
- * Appends the code of the given code attribute.
- */
- private void copyCode(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
- // The code may expand, due to expanding constant and variable
- // instructions.
- codeAttributeComposer.beginCodeFragment(codeAttribute.u4codeLength);
-
- // Copy the instructions.
- codeAttribute.instructionsAccept(clazz, method, this);
-
- // Append a label just after the code.
- codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
-
- codeAttributeComposer.endCodeFragment();
- }
-
-
// Implementations for InstructionVisitor.
public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
@@ -159,9 +152,9 @@
case InstructionConstants.OP_INVOKESTATIC:
{
// Is it a recursive call?
- clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex, recursionChecker);
- if (recursive)
+ if (recursionChecker.isRecursive())
{
// Is the next instruction a return?
int nextOffset =
@@ -180,13 +173,13 @@
case InstructionConstants.OP_RETURN:
{
// Isn't the recursive call inside a try/catch block?
- codeAttribute.exceptionsAccept(clazz, method, offset, this);
+ codeAttribute.exceptionsAccept(clazz, method, offset, recursionChecker);
- if (recursive)
+ if (recursionChecker.isRecursive())
{
if (DEBUG)
{
- System.out.println("TailRecursionSimplifier.visitConstantInstruction: ["+
+ System.out.println("TailRecursionSimplifier: ["+
clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz)+"], inlining "+constantInstruction.toString(offset));
}
@@ -227,19 +220,52 @@
}
- // Implementations for ConstantVisitor.
-
- public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
- {
- recursive = targetMethod.equals(methodrefConstant.referencedMember);
- }
-
-
// Implementations for ExceptionInfoVisitor.
public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
{
- recursive = false;
+ codeAttributeComposer.appendException(new ExceptionInfo(exceptionInfo.u2startPC,
+ exceptionInfo.u2endPC,
+ exceptionInfo.u2handlerPC,
+ exceptionInfo.u2catchType));
+ }
+
+
+ /**
+ * This ConstantVisitor and ExceptionInfoVisitor returns whether a method
+ * invocation can be treated as tail-recursive.
+ */
+ private class MyRecursionChecker
+ extends SimplifiedVisitor
+ implements ConstantVisitor,
+ ExceptionInfoVisitor
+ {
+ private boolean recursive;
+
+
+ /**
+ * Returns whether the method invocation can be treated as
+ * tail-recursive.
+ */
+ public boolean isRecursive()
+ {
+ return recursive;
+ }
+
+ // Implementations for ConstantVisitor.
+
+ public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
+ {
+ recursive = targetMethod.equals(methodrefConstant.referencedMember);
+ }
+
+
+ // Implementations for ExceptionInfoVisitor.
+
+ public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
+ {
+ recursive = false;
+ }
}
@@ -257,7 +283,6 @@
(method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;
// Count the number of parameters, taking into account their categories.
- int parameterCount = ClassUtil.internalMethodParameterCount(descriptor);
int parameterSize = ClassUtil.internalMethodParameterSize(descriptor);
int parameterOffset = isStatic ? 0 : 1;
diff --git a/src/proguard/optimize/WriteOnlyFieldFilter.java b/src/proguard/optimize/WriteOnlyFieldFilter.java
index 578beb2..4a0e095 100644
--- a/src/proguard/optimize/WriteOnlyFieldFilter.java
+++ b/src/proguard/optimize/WriteOnlyFieldFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/evaluation/EvaluationShrinker.java b/src/proguard/optimize/evaluation/EvaluationShrinker.java
index 1463feb..bc5f658 100644
--- a/src/proguard/optimize/evaluation/EvaluationShrinker.java
+++ b/src/proguard/optimize/evaluation/EvaluationShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -34,6 +34,8 @@
import proguard.evaluation.value.*;
import proguard.optimize.info.*;
+import java.util.Arrays;
+
/**
* This AttributeVisitor simplifies the code attributes that it visits, based
* on partial evaluation.
@@ -55,13 +57,14 @@
private final InstructionVisitor extraDeletedInstructionVisitor;
private final InstructionVisitor extraAddedInstructionVisitor;
- private final PartialEvaluator partialEvaluator;
- private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
- private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
- private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
- private final MyProducerMarker producerMarker = new MyProducerMarker();
- private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
- private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
+ private final PartialEvaluator partialEvaluator;
+ private final PartialEvaluator simplePartialEvaluator = new PartialEvaluator();
+ private final SideEffectInstructionChecker sideEffectInstructionChecker = new SideEffectInstructionChecker(true);
+ private final MyUnusedParameterSimplifier unusedParameterSimplifier = new MyUnusedParameterSimplifier();
+ private final MyProducerMarker producerMarker = new MyProducerMarker();
+ private final MyVariableInitializationMarker variableInitializationMarker = new MyVariableInitializationMarker();
+ private final MyStackConsistencyFixer stackConsistencyFixer = new MyStackConsistencyFixer();
+ private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);
private boolean[][] variablesNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_VARIABLES_SIZE];
private boolean[][] stacksNecessaryAfter = new boolean[ClassConstants.TYPICAL_CODE_LENGTH][ClassConstants.TYPICAL_STACK_SIZE];
@@ -276,18 +279,10 @@
if (partialEvaluator.isTraced(offset) &&
!isInstructionNecessary(offset))
{
- // Is the corresponding variable necessary anywhere in the code,
- // accoriding to a simple partial evaluation?
- int variableIndex = partialEvaluator.initializedVariable(offset);
- if (variableIndex >= 0 &&
- isVariableInitializationNecessary(clazz,
- method,
- codeAttribute,
- offset,
- variableIndex))
- {
- markInstruction(offset);
- }
+ Instruction instruction = InstructionFactory.create(codeAttribute.code,
+ offset);
+
+ instruction.accept(clazz, method, codeAttribute, offset, variableInitializationMarker);
}
}
if (DEBUG) System.out.println();
@@ -467,7 +462,9 @@
*/
private class MyUnusedParameterSimplifier
extends SimplifiedVisitor
- implements InstructionVisitor, ConstantVisitor, MemberVisitor
+ implements InstructionVisitor,
+ ConstantVisitor,
+ MemberVisitor
{
private int invocationOffset;
private ConstantInstruction invocationInstruction;
@@ -657,6 +654,40 @@
/**
+ * This InstructionVisitor marks variable initializations that are
+ * necessary to appease the JVM.
+ */
+ private class MyVariableInitializationMarker
+ extends SimplifiedVisitor
+ implements InstructionVisitor
+ {
+ // Implementations for InstructionVisitor.
+
+ public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}
+
+
+ public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction)
+ {
+ if (!variableInstruction.isLoad())
+ {
+ int variableIndex = variableInstruction.variableIndex;
+
+ if (isVariableInitialization(offset,
+ variableIndex) &&
+ isVariableInitializationNecessary(clazz,
+ method,
+ codeAttribute,
+ offset,
+ variableIndex))
+ {
+ markInstruction(offset);
+ }
+ }
+ }
+ }
+
+
+ /**
* This InstructionVisitor fixes instructions locally, popping any unused
* produced stack entries after marked instructions, and popping produced
* stack entries and pushing missing stack entries instead of unmarked
@@ -687,12 +718,23 @@
int requiredPushCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- // Is the stack entry required by other consumers?
- if (!isStackSimplifiedBefore(offset, top - stackIndex) &&
- !isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
+ InstructionOffsetValue producerOffsets =
+ tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
+
+ if (!isStackSimplifiedBefore(offset, top - stackIndex))
{
- // Remember to push it.
- requiredPushCount++;
+ // Is the stack entry pushed by any producer,
+ // because it is required by other consumers?
+ if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
+ {
+ // Make sure it is pushed after all producers.
+ markStackEntriesAfter(producerOffsets, top - stackIndex);
+ }
+ else
+ {
+ // Remember to push it.
+ requiredPushCount++;
+ }
}
}
@@ -757,9 +799,16 @@
int expectedPopCount = 0;
for (int stackIndex = 0; stackIndex < popCount; stackIndex++)
{
- // Is the stack entry required by other consumers?
- if (isAnyStackEntryNecessaryAfter(tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue(), top - stackIndex))
+ InstructionOffsetValue producerOffsets =
+ tracedStack.getTopProducerValue(stackIndex).instructionOffsetValue();
+
+ // Is the stack entry pushed by any producer,
+ // because it is required by other consumers?
+ if (isAnyStackEntryNecessaryAfter(producerOffsets, top - stackIndex))
{
+ // Make sure it is pushed after all producers.
+ markStackEntriesAfter(producerOffsets, top - stackIndex);
+
// Remember to pop it.
expectedPopCount++;
}
@@ -1052,6 +1101,7 @@
byte oldOpcode = instruction.opcode;
byte newOpcode = 0;
+ byte addOpcode = 0;
// Simplify the popping instruction if possible.
switch (oldOpcode)
@@ -1232,9 +1282,20 @@
stackEntryPresent1)
{
// Will both elements be present?
- if (stackEntryPresent0 &&
- stackEntryPresent1)
+ if (!stackEntryPresent1)
{
+ // Pop the original top element (later bottom element).
+ newOpcode = InstructionConstants.OP_POP;
+ }
+ else if (!stackEntryPresent0)
+ {
+ // Swap both elements and pop the top one.
+ newOpcode = InstructionConstants.OP_SWAP;
+ addOpcode = InstructionConstants.OP_POP;
+ }
+ else
+ {
+ // Just swap both elements.
newOpcode = InstructionConstants.OP_SWAP;
}
}
@@ -1242,6 +1303,7 @@
}
}
+ // Is there a replacement opcode?
if (newOpcode == 0)
{
// Delete the instruction.
@@ -1270,6 +1332,21 @@
if (DEBUG) System.out.println(" Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString());
}
+
+ // Is there an additional opcode?
+ if (addOpcode != 0)
+ {
+ // Add the instruction.
+ Instruction additionalInstruction = new SimpleInstruction(addOpcode);
+ codeAttributeEditor.insertAfterInstruction(dupOffset, additionalInstruction);
+
+ if (extraAddedInstructionVisitor != null)
+ {
+ extraAddedInstructionVisitor.visitSimpleInstruction(null, null, null, dupOffset, null);
+ }
+
+ if (DEBUG) System.out.println(" Adding instruction "+additionalInstruction.toString(dupOffset));
+ }
}
@@ -1596,10 +1673,7 @@
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxLocals; index++)
- {
- variablesNecessaryAfter[offset][index] = false;
- }
+ Arrays.fill(variablesNecessaryAfter[offset], 0, maxLocals, false);
}
}
@@ -1612,10 +1686,7 @@
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxStack; index++)
- {
- stacksNecessaryAfter[offset][index] = false;
- }
+ Arrays.fill(stacksNecessaryAfter[offset], 0, maxStack, false);
}
}
@@ -1628,10 +1699,7 @@
{
for (int offset = 0; offset < codeLength; offset++)
{
- for (int index = 0; index < maxStack; index++)
- {
- stacksSimplifiedBefore[offset][index] = false;
- }
+ Arrays.fill(stacksSimplifiedBefore[offset], 0, maxStack, false);
}
}
@@ -1641,10 +1709,7 @@
}
else
{
- for (int index = 0; index < codeLength; index++)
- {
- instructionsNecessary[index] = false;
- }
+ Arrays.fill(instructionsNecessary, 0, codeLength, false);
}
}
@@ -1670,6 +1735,34 @@
/**
+ * Returns whether the specified variable is initialized at the specified
+ * offset.
+ */
+ private boolean isVariableInitialization(int instructionOffset,
+ int variableIndex)
+ {
+ // Wasn't the variable set yet?
+ Value valueBefore = partialEvaluator.getVariablesBefore(instructionOffset).getValue(variableIndex);
+ if (valueBefore == null)
+ {
+ return true;
+ }
+
+ // Is the computational type different now?
+ Value valueAfter = partialEvaluator.getVariablesAfter(instructionOffset).getValue(variableIndex);
+ if (valueAfter.computationalType() != valueBefore.computationalType())
+ {
+ return true;
+ }
+
+ // Was the producer an argument (which may be removed)?
+ Value producersBefore = partialEvaluator.getVariablesBefore(instructionOffset).getProducerValue(variableIndex);
+ return producersBefore.instructionOffsetValue().instructionOffsetCount() == 1 &&
+ producersBefore.instructionOffsetValue().instructionOffset(0) == PartialEvaluator.AT_METHOD_ENTRY;
+ }
+
+
+ /**
* Returns whether the specified variable must be initialized at the
* specified offset, according to the verifier of the JVM.
*/
@@ -1686,8 +1779,8 @@
{
if (DEBUG) System.out.println("Simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
- // Lazily compute perform simple partial evaluation, the way the
- // JVM preverifier would do it.
+ // Lazily perform simple partial evaluation, the way the JVM
+ // verifier would do it.
simplePartialEvaluator.visitCodeAttribute(clazz, method, codeAttribute);
if (DEBUG) System.out.println("End of simple partial evaluation for initialization of variable v"+variableIndex+" at ["+initializationOffset+"]");
@@ -1695,7 +1788,7 @@
// Check if the variable is necessary elsewhere.
for (int offset = 0; offset < codeLength; offset++)
{
- if (isInstructionNecessary(offset))
+ if (partialEvaluator.isTraced(offset))
{
Value producer = partialEvaluator.getVariablesBefore(offset).getProducerValue(variableIndex);
if (producer != null)
@@ -1708,16 +1801,22 @@
InstructionOffsetValue simpleProducerOffsets =
simpleProducer.instructionOffsetValue();
- // Does the sophisticated partial evaluation have fewer
- // producers than the simple one?
- // And does the simple partial evaluation point to an
- // initialization of the variable?
- if (producerOffsets.instructionOffsetCount() <
- simpleProducerOffsets.instructionOffsetCount() &&
- isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
- simpleProducerOffsets.contains(initializationOffset))
+ if (DEBUG)
{
- // Then the initialization is necessary.
+ System.out.println(" ["+offset+"] producers ["+producerOffsets+"], simple producers ["+simpleProducerOffsets+"]");
+ }
+
+ // Is the variable being used without all of its
+ // immediate simple producers being marked?
+ if (isVariableNecessaryAfterAny(producerOffsets, variableIndex) &&
+ !isVariableNecessaryAfterAll(simpleProducerOffsets, variableIndex))
+ {
+ if (DEBUG)
+ {
+ System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] necessary");
+ }
+
+ // Then the initialization may be necessary.
return true;
}
}
@@ -1726,6 +1825,11 @@
}
}
+ if (DEBUG)
+ {
+ System.out.println(" => initialization of variable v"+variableIndex+" at ["+initializationOffset+"] not necessary");
+ }
+
return false;
}
@@ -1749,7 +1853,7 @@
/**
* Returns whether the specified variable is ever necessary after any
- * instruction in the specified block.
+ * instructions in the specified block.
*/
private boolean isVariableNecessaryAfterAny(int startOffset,
int endOffset,
@@ -1769,7 +1873,7 @@
/**
* Returns whether the specified variable is ever necessary after any
- * instruction in the specified set of instructions offsets.
+ * instructions in the specified set of instructions offsets.
*/
private boolean isVariableNecessaryAfterAny(InstructionOffsetValue instructionOffsetValue,
int variableIndex)
@@ -1789,6 +1893,28 @@
}
+ /**
+ * Returns whether the specified variable is ever necessary after all
+ * instructions in the specified set of instructions offsets.
+ */
+ private boolean isVariableNecessaryAfterAll(InstructionOffsetValue instructionOffsetValue,
+ int variableIndex)
+ {
+ int count = instructionOffsetValue.instructionOffsetCount();
+
+ for (int index = 0; index < count; index++)
+ {
+ if (!isVariableNecessaryAfter(instructionOffsetValue.instructionOffset(index),
+ variableIndex))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
private boolean isVariableNecessaryAfter(int instructionOffset,
int variableIndex)
{
@@ -1797,6 +1923,36 @@
}
+ /**
+ * Marks the stack entries after the given offsets.
+ * @param instructionOffsets the offsets of the stack entries to be marked.
+ * @param stackIndex the index of the stack entries to be marked
+ * (counting from the bottom).
+ */
+ private void markStackEntriesAfter(InstructionOffsetValue instructionOffsets,
+ int stackIndex)
+ {
+ if (instructionOffsets != null)
+ {
+ int offsetCount = instructionOffsets.instructionOffsetCount();
+ for (int offsetIndex = 0; offsetIndex < offsetCount; offsetIndex++)
+ {
+ // Make sure the stack entry and the instruction are marked
+ // at the producing offset.
+ int offset = instructionOffsets.instructionOffset(offsetIndex);
+
+ markStackEntryAfter(offset, stackIndex);
+ }
+ }
+ }
+
+
+ /**
+ * Marks the stack entry after the given offset.
+ * @param instructionOffset the offset of the stack entry to be marked.
+ * @param stackIndex the index of the stack entry to be marked
+ * (counting from the bottom).
+ */
private void markStackEntryAfter(int instructionOffset,
int stackIndex)
{
@@ -1814,6 +1970,13 @@
}
+ /**
+ * Returns whether any of the stack entries after the given offsets are
+ * necessary.
+ * @param instructionOffsets the offsets of the stack entries to be checked.
+ * @param stackIndex the index of the stack entries to be checked
+ * (counting from the bottom).
+ */
private boolean isAnyStackEntryNecessaryAfter(InstructionOffsetValue instructionOffsets,
int stackIndex)
{
@@ -1831,6 +1994,13 @@
}
+ /**
+ * Returns whether any of the stack entries after the given offset are
+ * necessary.
+ * @param instructionOffset the offset of the stack entry to be checked.
+ * @param stackIndex the index of the stack entry to be checked
+ * (counting from the bottom).
+ */
private boolean isStackEntryNecessaryAfter(int instructionOffset,
int stackIndex)
{
diff --git a/src/proguard/optimize/evaluation/EvaluationSimplifier.java b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
index 0c3a9c7..b207108 100644
--- a/src/proguard/optimize/evaluation/EvaluationSimplifier.java
+++ b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -43,6 +43,9 @@
implements AttributeVisitor,
InstructionVisitor
{
+ private static int POS_ZERO_FLOAT_BITS = Float.floatToIntBits(0.0f);
+ private static long POS_ZERO_DOUBLE_BITS = Double.doubleToLongBits(0.0);
+
//*
private static final boolean DEBUG = false;
/*/
@@ -559,10 +562,11 @@
Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0);
if (pushedValue.isParticular())
{
+ // Make sure to distinguish between +0.0 and -0.0.
float value = pushedValue.floatValue().value();
- if (value == 0f ||
- value == 1f ||
- value == 2f)
+ if (value == 0.0f && Float.floatToIntBits(value) == POS_ZERO_FLOAT_BITS ||
+ value == 1.0f ||
+ value == 2.0f)
{
replaceConstantPushInstruction(clazz,
offset,
@@ -627,8 +631,9 @@
Value pushedValue = partialEvaluator.getStackAfter(offset).getTop(0);
if (pushedValue.isParticular())
{
+ // Make sure to distinguish between +0.0 and -0.0.
double value = pushedValue.doubleValue().value();
- if (value == 0.0 ||
+ if (value == 0.0 && Double.doubleToLongBits(value) == POS_ZERO_DOUBLE_BITS ||
value == 1.0)
{
replaceConstantPushInstruction(clazz,
diff --git a/src/proguard/optimize/evaluation/LivenessAnalyzer.java b/src/proguard/optimize/evaluation/LivenessAnalyzer.java
index 9915027..747f993 100644
--- a/src/proguard/optimize/evaluation/LivenessAnalyzer.java
+++ b/src/proguard/optimize/evaluation/LivenessAnalyzer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -79,6 +79,16 @@
/**
+ * Returns whether the instruction at the given offset has ever been
+ * executed during the partial evaluation.
+ */
+ public boolean isTraced(int instructionOffset)
+ {
+ return partialEvaluator.isTraced(instructionOffset);
+ }
+
+
+ /**
* Returns whether the specified variable is alive before the instruction
* at the given offset.
*/
diff --git a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java b/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
index 8379c57..578ece5 100644
--- a/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
+++ b/src/proguard/optimize/evaluation/LoadingInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -35,9 +35,9 @@
public class LoadingInvocationUnit
extends BasicInvocationUnit
{
- private boolean loadFieldValues;
- private boolean loadMethodParameterValues;
- private boolean loadMethodReturnValues;
+ private final boolean loadFieldValues;
+ private final boolean loadMethodParameterValues;
+ private final boolean loadMethodReturnValues;
/**
@@ -84,8 +84,6 @@
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -110,8 +108,6 @@
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -134,8 +130,6 @@
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
@@ -163,8 +157,6 @@
value.isParticular())
{
return value;
-// // Make sure the value is refreshed.
-// return refresh(value);
}
}
}
@@ -173,8 +165,8 @@
refConstant,
type);
}
-//
-//
+
+
// // Small utility methods.
//
// private Value refresh(Value value)
diff --git a/src/proguard/optimize/evaluation/PartialEvaluator.java b/src/proguard/optimize/evaluation/PartialEvaluator.java
index 5790a36..b2776d1 100644
--- a/src/proguard/optimize/evaluation/PartialEvaluator.java
+++ b/src/proguard/optimize/evaluation/PartialEvaluator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -31,6 +31,8 @@
import proguard.evaluation.value.*;
import proguard.optimize.peephole.BranchTargetFinder;
+import java.util.Arrays;
+
/**
* This AttributeVisitor performs partial evaluation on the code attributes
* that it visits.
@@ -68,7 +70,6 @@
private TracedStack[] stacksAfter = new TracedStack[ClassConstants.TYPICAL_CODE_LENGTH];
private boolean[] generalizedContexts = new boolean[ClassConstants.TYPICAL_CODE_LENGTH];
private int[] evaluationCounts = new int[ClassConstants.TYPICAL_CODE_LENGTH];
- private int[] initializedVariables = new int[ClassConstants.TYPICAL_CODE_LENGTH];
private boolean evaluateExceptions;
private final BasicBranchUnit branchUnit;
@@ -189,6 +190,47 @@
if (DEBUG)
{
method.accept(clazz, new ClassPrinter());
+
+ System.out.println("Evaluation results:");
+
+ int offset = 0;
+ do
+ {
+ if (isBranchOrExceptionTarget(offset))
+ {
+ System.out.println("Branch target from ["+branchOriginValues[offset]+"]:");
+ if (isTraced(offset))
+ {
+ System.out.println(" Vars: "+variablesBefore[offset]);
+ System.out.println(" Stack: "+stacksBefore[offset]);
+ }
+ }
+
+ Instruction instruction = InstructionFactory.create(codeAttribute.code,
+ offset);
+ System.out.println(instruction.toString(offset));
+
+ if (isTraced(offset))
+ {
+ int initializationOffset = branchTargetFinder.initializationOffset(offset);
+ if (initializationOffset != NONE)
+ {
+ System.out.println(" is to be initialized at ["+initializationOffset+"]");
+ }
+
+ InstructionOffsetValue branchTargets = branchTargets(offset);
+ if (branchTargets != null)
+ {
+ System.out.println(" has overall been branching to "+branchTargets);
+ }
+
+ System.out.println(" Vars: "+variablesAfter[offset]);
+ System.out.println(" Stack: "+stacksAfter[offset]);
+ }
+
+ offset += instruction.length(offset);
+ }
+ while (offset < codeAttribute.u4codeLength);
}
throw ex;
@@ -212,7 +254,8 @@
TracedStack stack = new TracedStack(codeAttribute.u2maxStack);
// Initialize the reusable arrays and variables.
- initializeVariables(clazz, method, codeAttribute, variables, stack);
+ initializeArrays(codeAttribute);
+ initializeParameters(clazz, method, codeAttribute, variables);
// Find all instruction offsets,...
codeAttribute.accept(clazz, method, branchTargetFinder);
@@ -249,12 +292,6 @@
if (isTraced(offset))
{
- int variableIndex = initializedVariable(offset);
- if (variableIndex >= 0)
- {
- System.out.println(" is initializing variable v"+variableIndex);
- }
-
int initializationOffset = branchTargetFinder.initializationOffset(offset);
if (initializationOffset != NONE)
{
@@ -479,16 +516,6 @@
}
- /**
- * Returns the variable that is initialized at the given instruction offset,
- * or <code>NONE</code> if no variable was initialized.
- */
- public int initializedVariable(int instructionOffset)
- {
- return initializedVariables[instructionOffset];
- }
-
-
// Utility methods to evaluate instruction blocks.
/**
@@ -702,9 +729,6 @@
// Reset the trace value.
InstructionOffsetValue traceValue = InstructionOffsetValue.EMPTY_VALUE;
- // Reset the initialization flag.
- variables.resetInitialization();
-
// Note that the instruction is only volatile.
Instruction instruction = InstructionFactory.create(code, instructionOffset);
@@ -743,9 +767,6 @@
throw ex;
}
- // Collect the offsets of the instructions whose results were used.
- initializedVariables[instructionOffset] = variables.getInitializationIndex();
-
// Collect the branch targets from the branch unit.
InstructionOffsetValue branchTargets = branchUnit.getTraceBranchTargets();
int branchTargetCount = branchTargets.instructionOffsetCount();
@@ -896,11 +917,7 @@
subroutinePartialEvaluator = new PartialEvaluator(this);
- subroutinePartialEvaluator.initializeVariables(clazz,
- method,
- codeAttribute,
- variables,
- stack);
+ subroutinePartialEvaluator.initializeArrays(codeAttribute);
}
// Evaluate the subroutine.
@@ -952,13 +969,12 @@
if (evaluationCounts[offset] == 0)
{
- variablesBefore[offset] = other.variablesBefore[offset];
- stacksBefore[offset] = other.stacksBefore[offset];
- variablesAfter[offset] = other.variablesAfter[offset];
- stacksAfter[offset] = other.stacksAfter[offset];
- generalizedContexts[offset] = other.generalizedContexts[offset];
- evaluationCounts[offset] = other.evaluationCounts[offset];
- initializedVariables[offset] = other.initializedVariables[offset];
+ variablesBefore[offset] = other.variablesBefore[offset];
+ stacksBefore[offset] = other.stacksBefore[offset];
+ variablesAfter[offset] = other.variablesAfter[offset];
+ stacksAfter[offset] = other.stacksAfter[offset];
+ generalizedContexts[offset] = other.generalizedContexts[offset];
+ evaluationCounts[offset] = other.evaluationCounts[offset];
}
else
{
@@ -968,7 +984,6 @@
stacksAfter[offset] .generalize(other.stacksAfter[offset]);
//generalizedContexts[offset]
evaluationCounts[offset] += other.evaluationCounts[offset];
- //initializedVariables[offset]
}
}
}
@@ -1094,11 +1109,7 @@
/**
* Initializes the data structures for the variables, stack, etc.
*/
- private void initializeVariables(Clazz clazz,
- Method method,
- CodeAttribute codeAttribute,
- TracedVariables variables,
- TracedStack stack)
+ private void initializeArrays(CodeAttribute codeAttribute)
{
int codeLength = codeAttribute.u4codeLength;
@@ -1106,33 +1117,25 @@
if (variablesAfter.length < codeLength)
{
// Create new arrays.
- branchOriginValues = new InstructionOffsetValue[codeLength];
- branchTargetValues = new InstructionOffsetValue[codeLength];
- variablesBefore = new TracedVariables[codeLength];
- stacksBefore = new TracedStack[codeLength];
- variablesAfter = new TracedVariables[codeLength];
- stacksAfter = new TracedStack[codeLength];
- generalizedContexts = new boolean[codeLength];
- evaluationCounts = new int[codeLength];
- initializedVariables = new int[codeLength];
-
- // Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- initializedVariables[index] = NONE;
- }
+ branchOriginValues = new InstructionOffsetValue[codeLength];
+ branchTargetValues = new InstructionOffsetValue[codeLength];
+ variablesBefore = new TracedVariables[codeLength];
+ stacksBefore = new TracedStack[codeLength];
+ variablesAfter = new TracedVariables[codeLength];
+ stacksAfter = new TracedStack[codeLength];
+ generalizedContexts = new boolean[codeLength];
+ evaluationCounts = new int[codeLength];
}
else
{
// Reset the arrays.
+ Arrays.fill(branchOriginValues, null);
+ Arrays.fill(branchTargetValues, null);
+ Arrays.fill(generalizedContexts, false);
+ Arrays.fill(evaluationCounts, 0);
+
for (int index = 0; index < codeLength; index++)
{
- branchOriginValues[index] = null;
- branchTargetValues[index] = null;
- generalizedContexts[index] = false;
- evaluationCounts[index] = 0;
- initializedVariables[index] = NONE;
-
if (variablesBefore[index] != null)
{
variablesBefore[index].reset(codeAttribute.u2maxLocals);
@@ -1154,7 +1157,17 @@
}
}
}
+ }
+
+ /**
+ * Initializes the data structures for the variables, stack, etc.
+ */
+ private void initializeParameters(Clazz clazz,
+ Method method,
+ CodeAttribute codeAttribute,
+ TracedVariables variables)
+ {
// Create the method parameters.
TracedVariables parameters = new TracedVariables(codeAttribute.u2maxLocals);
diff --git a/src/proguard/optimize/evaluation/StoringInvocationUnit.java b/src/proguard/optimize/evaluation/StoringInvocationUnit.java
index bcbb69f..010dab0 100644
--- a/src/proguard/optimize/evaluation/StoringInvocationUnit.java
+++ b/src/proguard/optimize/evaluation/StoringInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/evaluation/TracedBranchUnit.java b/src/proguard/optimize/evaluation/TracedBranchUnit.java
index fa5bb79..b7dd469 100644
--- a/src/proguard/optimize/evaluation/TracedBranchUnit.java
+++ b/src/proguard/optimize/evaluation/TracedBranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/evaluation/VariableOptimizer.java b/src/proguard/optimize/evaluation/VariableOptimizer.java
index b3ae81c..a824481 100644
--- a/src/proguard/optimize/evaluation/VariableOptimizer.java
+++ b/src/proguard/optimize/evaluation/VariableOptimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,10 +21,10 @@
package proguard.optimize.evaluation;
import proguard.classfile.*;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.editor.*;
import proguard.classfile.visitor.MemberVisitor;
import proguard.classfile.attribute.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.editor.VariableRemapper;
import proguard.classfile.util.*;
/**
@@ -35,7 +35,9 @@
*/
public class VariableOptimizer
extends SimplifiedVisitor
-implements AttributeVisitor
+implements AttributeVisitor,
+ LocalVariableInfoVisitor,
+ LocalVariableTypeInfoVisitor
{
//*
private static final boolean DEBUG = false;
@@ -51,6 +53,7 @@
private final LivenessAnalyzer livenessAnalyzer = new LivenessAnalyzer();
private final VariableRemapper variableRemapper = new VariableRemapper();
+ private VariableCleaner variableCleaner = new VariableCleaner();
private int[] variableMap = new int[ClassConstants.TYPICAL_VARIABLES_SIZE];
@@ -101,6 +104,11 @@
// Analyze the liveness of the variables in the code.
livenessAnalyzer.visitCodeAttribute(clazz, method, codeAttribute);
+ // Trim the variables in the local variable tables, because even
+ // clipping the tables individually may leave some inconsistencies
+ // between them.
+ codeAttribute.attributesAccept(clazz, method, this);
+
int startIndex =
(method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0 ||
reuseThis ? 0 : 1;
@@ -142,23 +150,19 @@
}
}
- // Remap the variables.
+ // Have we been able to remap any variables?
if (remapping)
{
if (DEBUG)
{
- System.out.println("Remapping variables:");
- System.out.println(" Class "+ ClassUtil.externalClassName(clazz.getName()));
- System.out.println(" Method "+ClassUtil.externalFullMethodDescription(clazz.getName(),
- 0,
- method.getName(clazz),
- method.getDescriptor(clazz)));
- for (int index = 0; index < variableSize; index++)
+ System.out.println("VariableOptimizer: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
+ for (int index= 0; index < variableSize; index++)
{
- System.out.println(" ["+index+"] -> ["+variableMap[index]+"]");
+ System.out.println(" v"+index+" -> "+variableMap[index]);
}
}
+ // Remap the variables.
variableRemapper.setVariableMap(variableMap);
variableRemapper.visitCodeAttribute(clazz, method, codeAttribute);
@@ -168,6 +172,59 @@
method.accept(clazz, extraVariableMemberVisitor);
}
}
+ else
+ {
+ // Just clean up any empty variables.
+ variableCleaner.visitCodeAttribute(clazz, method, codeAttribute);
+ }
+ }
+
+
+ public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
+ {
+ // Trim the variables in the local variable table.
+ localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
+ {
+ // Trim the variables in the local variable type table.
+ localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
+ }
+
+
+ // Implementations for LocalVariableInfoVisitor.
+
+ public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
+ {
+ // Trim the local variable to the instructions at which it is alive.
+ int variable = localVariableInfo.u2index;
+ int startPC = localVariableInfo.u2startPC;
+ int endPC = startPC + localVariableInfo.u2length;
+
+ startPC = firstLiveness(startPC, endPC, variable);
+ endPC = lastLiveness(startPC, endPC, variable);
+
+ localVariableInfo.u2startPC = startPC;
+ localVariableInfo.u2length = endPC - startPC;
+ }
+
+
+ // Implementations for LocalVariableTypeInfoVisitor.
+
+ public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
+ {
+ // Trim the local variable type to the instructions at which it is alive.
+ int variable = localVariableTypeInfo.u2index;
+ int startPC = localVariableTypeInfo.u2startPC;
+ int endPC = startPC + localVariableTypeInfo.u2length;
+
+ startPC = firstLiveness(startPC, endPC, variable);
+ endPC = lastLiveness(startPC, endPC, variable);
+
+ localVariableTypeInfo.u2startPC = startPC;
+ localVariableTypeInfo.u2length = endPC - startPC;
}
@@ -241,4 +298,48 @@
}
}
}
+
+
+ /**
+ * Returns the first instruction offset between the given offsets at which
+ * the given variable goes alive.
+ */
+ private int firstLiveness(int startOffset, int endOffset, int variableIndex)
+ {
+ for (int offset = startOffset; offset < endOffset; offset++)
+ {
+ if (livenessAnalyzer.isTraced(offset) &&
+ livenessAnalyzer.isAliveBefore(offset, variableIndex))
+ {
+ return offset;
+ }
+ }
+
+ return endOffset;
+ }
+
+
+ /**
+ * Returns the last instruction offset between the given offsets before
+ * which the given variable is still alive.
+ */
+ private int lastLiveness(int startOffset, int endOffset, int variableIndex)
+ {
+ int previousOffset = endOffset;
+
+ for (int offset = endOffset-1; offset >= startOffset; offset--)
+ {
+ if (livenessAnalyzer.isTraced(offset))
+ {
+ if (livenessAnalyzer.isAliveBefore(offset, variableIndex))
+ {
+ return previousOffset;
+ }
+
+ previousOffset = offset;
+ }
+ }
+
+ return endOffset;
+ }
}
diff --git a/src/proguard/optimize/info/AccessMethodMarker.java b/src/proguard/optimize/info/AccessMethodMarker.java
index 6965cec..8d758ce 100644
--- a/src/proguard/optimize/info/AccessMethodMarker.java
+++ b/src/proguard/optimize/info/AccessMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,7 +21,8 @@
package proguard.optimize.info;
import proguard.classfile.*;
-import proguard.classfile.attribute.CodeAttribute;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
@@ -71,6 +72,20 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // Check the bootstrap method.
+ invokeDynamicConstant.bootstrapMethodHandleAccept(clazz, this);
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ // Check the method reference.
+ clazz.constantPoolEntryAccept(methodHandleConstant.u2referenceIndex, this);
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
// Check the referenced class.
diff --git a/src/proguard/optimize/info/BackwardBranchMarker.java b/src/proguard/optimize/info/BackwardBranchMarker.java
index 9e09b0f..d53a5b2 100644
--- a/src/proguard/optimize/info/BackwardBranchMarker.java
+++ b/src/proguard/optimize/info/BackwardBranchMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/CatchExceptionMarker.java b/src/proguard/optimize/info/CatchExceptionMarker.java
index 3f2a06f..5d74047 100644
--- a/src/proguard/optimize/info/CatchExceptionMarker.java
+++ b/src/proguard/optimize/info/CatchExceptionMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/CaughtClassFilter.java b/src/proguard/optimize/info/CaughtClassFilter.java
index 5e17763..4f7caff 100644
--- a/src/proguard/optimize/info/CaughtClassFilter.java
+++ b/src/proguard/optimize/info/CaughtClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/CaughtClassMarker.java b/src/proguard/optimize/info/CaughtClassMarker.java
index 0cc350e..5a60aaf 100644
--- a/src/proguard/optimize/info/CaughtClassMarker.java
+++ b/src/proguard/optimize/info/CaughtClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -25,8 +25,9 @@
import proguard.classfile.visitor.ClassVisitor;
/**
- * This InstructionVisitor marks all classes that are used in an 'instanceof'
- * test by any of the instructions that it visits.
+ * This ClassVisitor marks all program classes that it visits as caught.
+ * This means that these classes are exception classes that occur in exception
+ * handlers.
*
* @author Eric Lafortune
*/
diff --git a/src/proguard/optimize/info/ClassOptimizationInfo.java b/src/proguard/optimize/info/ClassOptimizationInfo.java
index 99b6e7b..e440eef 100644
--- a/src/proguard/optimize/info/ClassOptimizationInfo.java
+++ b/src/proguard/optimize/info/ClassOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -34,6 +34,7 @@
private boolean isInstanceofed = false;
private boolean isDotClassed = false;
private boolean isCaught = false;
+ private boolean containsStaticInitializer = false;
private boolean containsPackageVisibleMembers = false;
private boolean invokesPackageVisibleMembers = false;
private Clazz targetClass;
@@ -87,6 +88,18 @@
}
+ public void setContainsStaticInitializer()
+ {
+ containsStaticInitializer = true;
+ }
+
+
+ public boolean containsStaticInitializer()
+ {
+ return containsStaticInitializer;
+ }
+
+
public void setContainsPackageVisibleMembers()
{
containsPackageVisibleMembers = true;
@@ -129,6 +142,7 @@
this.isInstanceofed |= other.isInstanceofed;
this.isDotClassed |= other.isDotClassed;
this.isCaught |= other.isCaught;
+ this.containsStaticInitializer |= other.containsStaticInitializer;
this.containsPackageVisibleMembers |= other.containsPackageVisibleMembers;
this.invokesPackageVisibleMembers |= other.invokesPackageVisibleMembers;
}
diff --git a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java b/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
index 9cb167c..bc58f2d 100644
--- a/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
+++ b/src/proguard/optimize/info/ClassOptimizationInfoSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/DotClassFilter.java b/src/proguard/optimize/info/DotClassFilter.java
index 8cbe7f0..c55925c 100644
--- a/src/proguard/optimize/info/DotClassFilter.java
+++ b/src/proguard/optimize/info/DotClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/DotClassMarker.java b/src/proguard/optimize/info/DotClassMarker.java
index b5f12a7..2819441 100644
--- a/src/proguard/optimize/info/DotClassMarker.java
+++ b/src/proguard/optimize/info/DotClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/ExceptionInstructionChecker.java b/src/proguard/optimize/info/ExceptionInstructionChecker.java
index 2792d90..40287f3 100644
--- a/src/proguard/optimize/info/ExceptionInstructionChecker.java
+++ b/src/proguard/optimize/info/ExceptionInstructionChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -67,34 +67,39 @@
byte opcode = simpleInstruction.opcode;
// Check for instructions that may throw exceptions.
- if (opcode == InstructionConstants.OP_IDIV ||
- opcode == InstructionConstants.OP_LDIV ||
- opcode == InstructionConstants.OP_IREM ||
- opcode == InstructionConstants.OP_LREM ||
- opcode == InstructionConstants.OP_IALOAD ||
- opcode == InstructionConstants.OP_LALOAD ||
- opcode == InstructionConstants.OP_FALOAD ||
- opcode == InstructionConstants.OP_DALOAD ||
- opcode == InstructionConstants.OP_AALOAD ||
- opcode == InstructionConstants.OP_BALOAD ||
- opcode == InstructionConstants.OP_CALOAD ||
- opcode == InstructionConstants.OP_SALOAD ||
- opcode == InstructionConstants.OP_IASTORE ||
- opcode == InstructionConstants.OP_LASTORE ||
- opcode == InstructionConstants.OP_FASTORE ||
- opcode == InstructionConstants.OP_DASTORE ||
- opcode == InstructionConstants.OP_AASTORE ||
- opcode == InstructionConstants.OP_BASTORE ||
- opcode == InstructionConstants.OP_CASTORE ||
- opcode == InstructionConstants.OP_SASTORE ||
- opcode == InstructionConstants.OP_NEWARRAY ||
- opcode == InstructionConstants.OP_ARRAYLENGTH ||
- opcode == InstructionConstants.OP_ATHROW ||
- opcode == InstructionConstants.OP_MONITORENTER ||
- opcode == InstructionConstants.OP_MONITOREXIT)
+ // Note that monitorexit can not sensibly throw exceptions, except the
+ // broken and deprecated asynchronous ThreadDeath. Removing the
+ // artificial infinite looping exception blocks that recent compilers
+ // add does not strictly follow the JVM specs, but it does have the
+ // additional benefit of avoiding a bug in the JVM in JDK 1.1.
+ switch (opcode)
{
- // These instructions may throw exceptions.
- mayThrowExceptions = true;
+ case InstructionConstants.OP_IDIV:
+ case InstructionConstants.OP_LDIV:
+ case InstructionConstants.OP_IREM:
+ case InstructionConstants.OP_LREM:
+ case InstructionConstants.OP_IALOAD:
+ case InstructionConstants.OP_LALOAD:
+ case InstructionConstants.OP_FALOAD:
+ case InstructionConstants.OP_DALOAD:
+ case InstructionConstants.OP_AALOAD:
+ case InstructionConstants.OP_BALOAD:
+ case InstructionConstants.OP_CALOAD:
+ case InstructionConstants.OP_SALOAD:
+ case InstructionConstants.OP_IASTORE:
+ case InstructionConstants.OP_LASTORE:
+ case InstructionConstants.OP_FASTORE:
+ case InstructionConstants.OP_DASTORE:
+ case InstructionConstants.OP_AASTORE:
+ case InstructionConstants.OP_BASTORE:
+ case InstructionConstants.OP_CASTORE:
+ case InstructionConstants.OP_SASTORE:
+ case InstructionConstants.OP_NEWARRAY:
+ case InstructionConstants.OP_ARRAYLENGTH:
+ case InstructionConstants.OP_ATHROW:
+ case InstructionConstants.OP_MONITORENTER:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
}
}
@@ -105,31 +110,32 @@
byte opcode = constantInstruction.opcode;
// Check for instructions that may throw exceptions.
- if (opcode == InstructionConstants.OP_GETSTATIC ||
- opcode == InstructionConstants.OP_PUTSTATIC ||
- opcode == InstructionConstants.OP_GETFIELD ||
- opcode == InstructionConstants.OP_PUTFIELD ||
- opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
- opcode == InstructionConstants.OP_INVOKESPECIAL ||
- opcode == InstructionConstants.OP_INVOKESTATIC ||
- opcode == InstructionConstants.OP_INVOKEINTERFACE ||
- opcode == InstructionConstants.OP_NEW ||
- opcode == InstructionConstants.OP_ANEWARRAY ||
- opcode == InstructionConstants.OP_CHECKCAST ||
- opcode == InstructionConstants.OP_MULTIANEWARRAY)
+ switch (opcode)
{
- // These instructions may throw exceptions.
- mayThrowExceptions = true;
+ case InstructionConstants.OP_GETSTATIC:
+ case InstructionConstants.OP_PUTSTATIC:
+ case InstructionConstants.OP_GETFIELD:
+ case InstructionConstants.OP_PUTFIELD:
+ case InstructionConstants.OP_INVOKEVIRTUAL:
+ case InstructionConstants.OP_INVOKESPECIAL:
+ case InstructionConstants.OP_INVOKESTATIC:
+ case InstructionConstants.OP_INVOKEINTERFACE:
+ case InstructionConstants.OP_INVOKEDYNAMIC:
+ case InstructionConstants.OP_NEW:
+ case InstructionConstants.OP_ANEWARRAY:
+ case InstructionConstants.OP_CHECKCAST:
+ case InstructionConstants.OP_INSTANCEOF:
+ case InstructionConstants.OP_MULTIANEWARRAY:
+ // These instructions may throw exceptions.
+ mayThrowExceptions = true;
}
-// else
-// if (opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
-// opcode == InstructionConstants.OP_INVOKESPECIAL ||
-// opcode == InstructionConstants.OP_INVOKESTATIC ||
-// opcode == InstructionConstants.OP_INVOKEINTERFACE)
-// {
+
+// case InstructionConstants.OP_INVOKEVIRTUAL:
+// case InstructionConstants.OP_INVOKESPECIAL:
+// case InstructionConstants.OP_INVOKESTATIC:
+// case InstructionConstants.OP_INVOKEINTERFACE:
// // Check if the invoking the method may throw an exception.
// clazz.constantPoolEntryAccept(constantInstruction.constantIndex, this);
-// }
}
diff --git a/src/proguard/optimize/info/FieldOptimizationInfo.java b/src/proguard/optimize/info/FieldOptimizationInfo.java
index 7a2d068..6797a14 100644
--- a/src/proguard/optimize/info/FieldOptimizationInfo.java
+++ b/src/proguard/optimize/info/FieldOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,8 +21,11 @@
package proguard.optimize.info;
import proguard.classfile.*;
-import proguard.classfile.util.MethodLinker;
+import proguard.classfile.attribute.visitor.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.util.*;
import proguard.evaluation.value.*;
+import proguard.evaluation.ConstantValueFactory;
/**
* This class stores some optimization information that can be attached to
@@ -31,8 +34,11 @@
* @author Eric Lafortune
*/
public class FieldOptimizationInfo
+extends SimplifiedVisitor
+implements AttributeVisitor
{
- private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory();
+ private static final SpecificValueFactory VALUE_FACTORY = new SpecificValueFactory();
+ private static final ConstantValueFactory CONSTANT_VALUE_FACTORY = new ConstantValueFactory(VALUE_FACTORY);
private boolean isWritten;
private boolean isRead;
@@ -43,9 +49,33 @@
public FieldOptimizationInfo(Clazz clazz, Field field)
{
+ int accessFlags = field.getAccessFlags();
+
isWritten =
- isRead = (field.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0;
- value = initialValue(field.getDescriptor(clazz));
+ isRead = (accessFlags & ClassConstants.INTERNAL_ACC_VOLATILE) != 0;
+
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_STATIC) != 0)
+ {
+ // See if we can initialize the static field with a constant value.
+ field.accept(clazz, new AllAttributeVisitor(this));
+ }
+
+ if ((accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
+ value == null)
+ {
+ // Otherwise initialize the non-final field with the default value.
+ value = initialValue(field.getDescriptor(clazz));
+ }
+ }
+
+
+ public FieldOptimizationInfo(FieldOptimizationInfo FieldOptimizationInfo)
+ {
+ this.isWritten = FieldOptimizationInfo.isWritten;
+ this.isRead = FieldOptimizationInfo.isRead;
+ this.canBeMadePrivate = FieldOptimizationInfo.canBeMadePrivate;
+ this.referencedClass = FieldOptimizationInfo.referencedClass;
+ this.value = FieldOptimizationInfo.value;
}
@@ -113,6 +143,18 @@
}
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
+ {
+ // Retrieve the initial static field value.
+ value = CONSTANT_VALUE_FACTORY.constantValue(clazz, constantValueAttribute.u2constantValueIndex);
+ }
+
+
// Small utility methods.
private Value initialValue(String type)
@@ -147,13 +189,13 @@
public static void setFieldOptimizationInfo(Clazz clazz, Field field)
{
- MethodLinker.lastMember(field).setVisitorInfo(new FieldOptimizationInfo(clazz, field));
+ field.setVisitorInfo(new FieldOptimizationInfo(clazz, field));
}
public static FieldOptimizationInfo getFieldOptimizationInfo(Field field)
{
- Object visitorInfo = MethodLinker.lastMember(field).getVisitorInfo();
+ Object visitorInfo = field.getVisitorInfo();
return visitorInfo instanceof FieldOptimizationInfo ?
(FieldOptimizationInfo)visitorInfo :
diff --git a/src/proguard/optimize/info/InstanceofClassFilter.java b/src/proguard/optimize/info/InstanceofClassFilter.java
index 35e1d77..955fe9e 100644
--- a/src/proguard/optimize/info/InstanceofClassFilter.java
+++ b/src/proguard/optimize/info/InstanceofClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/InstanceofClassMarker.java b/src/proguard/optimize/info/InstanceofClassMarker.java
index c60e1f8..6d2f8aa 100644
--- a/src/proguard/optimize/info/InstanceofClassMarker.java
+++ b/src/proguard/optimize/info/InstanceofClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/InstantiationClassFilter.java b/src/proguard/optimize/info/InstantiationClassFilter.java
index a24e617..e67e0b5 100644
--- a/src/proguard/optimize/info/InstantiationClassFilter.java
+++ b/src/proguard/optimize/info/InstantiationClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/InstantiationClassMarker.java b/src/proguard/optimize/info/InstantiationClassMarker.java
index 124c23b..dc623c2 100644
--- a/src/proguard/optimize/info/InstantiationClassMarker.java
+++ b/src/proguard/optimize/info/InstantiationClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java b/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
index a170a8e..d222d81 100644
--- a/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
+++ b/src/proguard/optimize/info/MemberOptimizationInfoSetter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -38,16 +38,6 @@
{
// Implementations for MemberVisitor.
- public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
- {
- if (!KeepMarker.isKept(programMethod))
- {
- MethodOptimizationInfo.setMethodOptimizationInfo(programClass,
- programMethod);
- }
- }
-
-
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
if (!KeepMarker.isKept(programField))
@@ -56,4 +46,14 @@
programField);
}
}
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ if (!KeepMarker.isKept(programMethod))
+ {
+ MethodOptimizationInfo.setMethodOptimizationInfo(programClass,
+ programMethod);
+ }
+ }
}
diff --git a/src/proguard/optimize/info/MethodInvocationMarker.java b/src/proguard/optimize/info/MethodInvocationMarker.java
index 2528c94..9d573b7 100644
--- a/src/proguard/optimize/info/MethodInvocationMarker.java
+++ b/src/proguard/optimize/info/MethodInvocationMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/MethodOptimizationInfo.java b/src/proguard/optimize/info/MethodOptimizationInfo.java
index d3b1bde..dd76f97 100644
--- a/src/proguard/optimize/info/MethodOptimizationInfo.java
+++ b/src/proguard/optimize/info/MethodOptimizationInfo.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -204,7 +204,7 @@
public void setParameterUsed(int parameterIndex)
{
- usedParameters |= 1 << parameterIndex;
+ usedParameters |= 1L << parameterIndex;
}
@@ -216,7 +216,7 @@
public boolean isParameterUsed(int parameterIndex)
{
- return parameterIndex >= 64 || (usedParameters & (1 << parameterIndex)) != 0;
+ return parameterIndex >= 64 || (usedParameters & (1L << parameterIndex)) != 0;
}
diff --git a/src/proguard/optimize/info/NoSideEffectMethodMarker.java b/src/proguard/optimize/info/NoSideEffectMethodMarker.java
index 5c78408..2e0516b 100644
--- a/src/proguard/optimize/info/NoSideEffectMethodMarker.java
+++ b/src/proguard/optimize/info/NoSideEffectMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/NonPrivateMemberMarker.java b/src/proguard/optimize/info/NonPrivateMemberMarker.java
index d451643..23e33a9 100644
--- a/src/proguard/optimize/info/NonPrivateMemberMarker.java
+++ b/src/proguard/optimize/info/NonPrivateMemberMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -77,15 +77,9 @@
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
- Clazz referencedClass = stringConstant.referencedClass;
-
- // Is it refering to another class or class member?
- if (referencedClass != null &&
- !referencedClass.equals(clazz))
- {
- // The referenced class member, if any, can never be made private.
- stringConstant.referencedMemberAccept(this);
- }
+ // The referenced class member, if any, can never be made private,
+ // even if it's in the same class.
+ stringConstant.referencedMemberAccept(this);
}
@@ -93,7 +87,7 @@
{
Clazz referencedClass = refConstant.referencedClass;
- // Is it refering to a class member in another class?
+ // Is it referring to a class member in another class?
// The class member might be in another class, or
// it may be referenced through another class.
if (referencedClass != null &&
diff --git a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
index d40bc6b..85ff4b9 100644
--- a/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
+++ b/src/proguard/optimize/info/PackageVisibleMemberContainingClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,18 +22,36 @@
import proguard.classfile.*;
import proguard.classfile.util.SimplifiedVisitor;
-import proguard.classfile.visitor.MemberVisitor;
+import proguard.classfile.visitor.*;
/**
- * This MemberVisitor marks all classes that contain visited package visible
- * members.
+ * This ClassVisitor marks all classes that contain package visible members.
*
* @author Eric Lafortune
*/
public class PackageVisibleMemberContainingClassMarker
extends SimplifiedVisitor
-implements MemberVisitor
+implements ClassVisitor,
+ MemberVisitor
{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ // Check the class itself.
+ if ((clazz.getAccessFlags() & ClassConstants.INTERNAL_ACC_PUBLIC) == 0)
+ {
+ setPackageVisibleMembers(clazz);
+ }
+ else
+ {
+ // Check the members.
+ clazz.fieldsAccept(this);
+ clazz.methodsAccept(this);
+ }
+ }
+
+
// Implementations for MemberVisitor.
public void visitAnyMember(Clazz clazz, Member member)
diff --git a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
index 9ec8ec6..42cc14f 100644
--- a/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
+++ b/src/proguard/optimize/info/PackageVisibleMemberInvokingClassMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -24,39 +24,87 @@
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.constant.*;
import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
/**
- * This ConstantVisitor marks all classes that invoke package visible members
- * in other classes.
+ * This ConstantVisitor marks all classes that refer to package visible classes
+ * or class members.
*
* @author Eric Lafortune
*/
public class PackageVisibleMemberInvokingClassMarker
extends SimplifiedVisitor
-implements ConstantVisitor
+implements ConstantVisitor,
+ ClassVisitor,
+ MemberVisitor
{
+ private Clazz referencingClass;
+
+
// Implementations for ConstantVisitor.
public void visitAnyConstant(Clazz clazz, Constant constant) {}
+ public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
+ {
+ // Check the referenced class and class member, if any.
+ if (stringConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ stringConstant.referencedClassAccept(this);
+ stringConstant.referencedMemberAccept(this);
+ }
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
- Clazz referencedClass = refConstant.referencedClass;
- if (referencedClass != null &&
- (referencedClass.getAccessFlags() &
+ // Check the referenced class and class member.
+ if (refConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ refConstant.referencedClassAccept(this);
+ refConstant.referencedMemberAccept(this);
+ }
+ }
+
+
+ public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
+ {
+ // Check the referenced class.
+ if (classConstant.referencedClass != clazz)
+ {
+ referencingClass = clazz;
+
+ classConstant.referencedClassAccept(this);
+ }
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if ((clazz.getAccessFlags() &
ClassConstants.INTERNAL_ACC_PUBLIC) == 0)
{
- setInvokesPackageVisibleMembers(clazz);
+ setInvokesPackageVisibleMembers(referencingClass);
}
+ }
- Member referencedMember = refConstant.referencedMember;
- if (referencedMember != null &&
- (referencedMember.getAccessFlags() &
+
+ // Implementations for MemberVisitor.
+
+ public void visitAnyMember(Clazz clazz, Member member)
+ {
+ if ((member.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_PUBLIC |
ClassConstants.INTERNAL_ACC_PRIVATE)) == 0)
{
- setInvokesPackageVisibleMembers(clazz);
+ setInvokesPackageVisibleMembers(referencingClass);
}
}
diff --git a/src/proguard/optimize/info/ParameterUsageMarker.java b/src/proguard/optimize/info/ParameterUsageMarker.java
index 15ce88a..abae946 100644
--- a/src/proguard/optimize/info/ParameterUsageMarker.java
+++ b/src/proguard/optimize/info/ParameterUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,14 +21,14 @@
package proguard.optimize.info;
import proguard.classfile.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.visitor.AttributeVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
-import proguard.classfile.attribute.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.MemberVisitor;
+import proguard.evaluation.value.Value;
import proguard.optimize.evaluation.PartialEvaluator;
-import proguard.evaluation.value.*;
/**
* This MemberVisitor counts the parameters and marks the used parameters
diff --git a/src/proguard/optimize/info/ReadWriteFieldMarker.java b/src/proguard/optimize/info/ReadWriteFieldMarker.java
index 57d8561..236cb17 100644
--- a/src/proguard/optimize/info/ReadWriteFieldMarker.java
+++ b/src/proguard/optimize/info/ReadWriteFieldMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/SideEffectInstructionChecker.java b/src/proguard/optimize/info/SideEffectInstructionChecker.java
index 8be9dc1..1444e5a 100644
--- a/src/proguard/optimize/info/SideEffectInstructionChecker.java
+++ b/src/proguard/optimize/info/SideEffectInstructionChecker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,11 +29,14 @@
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;
+import java.util.*;
+
/**
* This class can tell whether an instruction has any side effects. Return
* instructions can be included or not.
*
* @see ReadWriteFieldMarker
+ * @see StaticInitializerContainingClassMarker
* @see NoSideEffectMethodMarker
* @see SideEffectMethodMarker
* @author Eric Lafortune
@@ -47,6 +50,7 @@
private final boolean includeReturnInstructions;
// A return value for the visitor methods.
+ private Clazz referencingClass;
private boolean hasSideEffects;
@@ -60,7 +64,7 @@
{
hasSideEffects = false;
- instruction.accept(clazz, method, codeAttribute, offset, this);
+ instruction.accept(clazz, method, codeAttribute, offset, this);
return hasSideEffects;
}
@@ -118,14 +122,16 @@
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
byte opcode = constantInstruction.opcode;
-
// Check for instructions that might cause side effects.
- if (opcode == InstructionConstants.OP_PUTSTATIC ||
- opcode == InstructionConstants.OP_PUTFIELD ||
- opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
- opcode == InstructionConstants.OP_INVOKESPECIAL ||
- opcode == InstructionConstants.OP_INVOKESTATIC ||
- opcode == InstructionConstants.OP_INVOKEINTERFACE)
+ if (opcode == InstructionConstants.OP_GETSTATIC ||
+ opcode == InstructionConstants.OP_PUTSTATIC ||
+ opcode == InstructionConstants.OP_GETFIELD ||
+ opcode == InstructionConstants.OP_PUTFIELD ||
+ opcode == InstructionConstants.OP_INVOKEVIRTUAL ||
+ opcode == InstructionConstants.OP_INVOKESPECIAL ||
+ opcode == InstructionConstants.OP_INVOKESTATIC ||
+ opcode == InstructionConstants.OP_INVOKEINTERFACE ||
+ opcode == InstructionConstants.OP_INVOKEDYNAMIC)
{
// Check if the field is write-only or volatile, or if the invoked
// method is causing any side effects.
@@ -150,48 +156,36 @@
// Implementations for ConstantVisitor.
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
+ }
+
+
public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
{
+ // Pass the referencing class.
+ referencingClass = clazz;
+
// We'll have to assume accessing an unknown field has side effects.
hasSideEffects = true;
- // Check the referenced field.
+ // Check the referenced field, if known.
fieldrefConstant.referencedMemberAccept(this);
}
public void visitAnyMethodrefConstant(Clazz clazz, RefConstant refConstant)
{
- Member referencedMember = refConstant.referencedMember;
+ // Pass the referencing class.
+ referencingClass = clazz;
- // Do we have a reference to the method?
- if (referencedMember == null)
- {
- // We'll have to assume invoking the unknown method has side effects.
- hasSideEffects = true;
- }
- else
- {
- // First check the referenced method itself.
- refConstant.referencedMemberAccept(this);
+ // We'll have to assume invoking an unknown method has side effects.
+ hasSideEffects = true;
- // If the result isn't conclusive, check down the hierarchy.
- if (!hasSideEffects)
- {
- Clazz referencedClass = refConstant.referencedClass;
- Method referencedMethod = (Method)referencedMember;
-
- // Check all other implementations of the method down the class
- // hierarchy.
- if ((referencedMethod.getAccessFlags() & ClassConstants.INTERNAL_ACC_PRIVATE) == 0)
- {
- clazz.hierarchyAccept(false, false, false, true,
- new NamedMethodVisitor(referencedMethod.getName(referencedClass),
- referencedMethod.getDescriptor(referencedClass),
- this));
- }
- }
- }
+ // Check the referenced method, if known.
+ refConstant.referencedMemberAccept(this);
}
@@ -199,14 +193,24 @@
public void visitProgramField(ProgramClass programClass, ProgramField programField)
{
- hasSideEffects = ReadWriteFieldMarker.isRead(programField);
+ hasSideEffects =
+ (ReadWriteFieldMarker.isRead(programField) &&
+ ReadWriteFieldMarker.isWritten(programField)) ||
+ ((programField.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0) ||
+ (!programClass.equals(referencingClass) &&
+ !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass)));
}
public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
{
- hasSideEffects = hasSideEffects ||
- SideEffectMethodMarker.hasSideEffects(programMethod);
+ // Note that side effects already include synchronization of some
+ // implementation of the method.
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(programMethod) &&
+ (SideEffectMethodMarker.hasSideEffects(programMethod) ||
+ (!programClass.equals(referencingClass) &&
+ !initializedSuperClasses(referencingClass).containsAll(initializedSuperClasses(programClass))));
}
@@ -218,7 +222,24 @@
public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
{
- hasSideEffects = hasSideEffects ||
- !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod);
+ hasSideEffects =
+ !NoSideEffectMethodMarker.hasNoSideEffects(libraryMethod);
+ }
+
+
+ /**
+ * Returns the set of superclasses and interfaces that are initialized.
+ */
+ private Set initializedSuperClasses(Clazz clazz)
+ {
+ Set set = new HashSet();
+
+ // Visit all superclasses and interfaces, collecting the ones that have
+ // static initializers.
+ clazz.hierarchyAccept(true, true, true, false,
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
+
+ return set;
}
}
diff --git a/src/proguard/optimize/info/SideEffectMethodMarker.java b/src/proguard/optimize/info/SideEffectMethodMarker.java
index 25fda72..d73179e 100644
--- a/src/proguard/optimize/info/SideEffectMethodMarker.java
+++ b/src/proguard/optimize/info/SideEffectMethodMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java b/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
new file mode 100644
index 0000000..197668d
--- /dev/null
+++ b/src/proguard/optimize/info/StaticInitializerContainingClassFilter.java
@@ -0,0 +1,62 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.visitor.ClassVisitor;
+
+/**
+ * This ClassVisitor delegates all its method calls to another ClassVisitor,
+ * but only for Clazz objects that are instantiated.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassFilter
+implements ClassVisitor
+{
+ private final ClassVisitor classVisitor;
+
+
+ public StaticInitializerContainingClassFilter(ClassVisitor classVisitor)
+ {
+ this.classVisitor = classVisitor;
+ }
+
+
+ // Implementations for ClassVisitor.
+
+ public void visitProgramClass(ProgramClass programClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(programClass))
+ {
+ classVisitor.visitProgramClass(programClass);
+ }
+ }
+
+
+ public void visitLibraryClass(LibraryClass libraryClass)
+ {
+ if (StaticInitializerContainingClassMarker.containsStaticInitializer(libraryClass))
+ {
+ classVisitor.visitLibraryClass(libraryClass);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java b/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
new file mode 100644
index 0000000..a121250
--- /dev/null
+++ b/src/proguard/optimize/info/StaticInitializerContainingClassMarker.java
@@ -0,0 +1,65 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2011 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.optimize.info;
+
+import proguard.classfile.*;
+import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.visitor.*;
+
+/**
+ * This ClassVisitor marks all classes that contain static initializers.
+ *
+ * @author Eric Lafortune
+ */
+public class StaticInitializerContainingClassMarker
+extends SimplifiedVisitor
+implements ClassVisitor
+{
+ // Implementations for ClassVisitor.
+
+ public void visitAnyClass(Clazz clazz)
+ {
+ if (clazz.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) != null)
+ {
+ setStaticInitializer(clazz);
+ }
+ }
+
+
+ // Small utility methods.
+
+ private static void setStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ if (info != null)
+ {
+ info.setContainsStaticInitializer();
+ }
+ }
+
+
+ public static boolean containsStaticInitializer(Clazz clazz)
+ {
+ ClassOptimizationInfo info = ClassOptimizationInfo.getClassOptimizationInfo(clazz);
+ return info == null || info.containsStaticInitializer();
+ }
+}
\ No newline at end of file
diff --git a/src/proguard/optimize/info/SuperInvocationMarker.java b/src/proguard/optimize/info/SuperInvocationMarker.java
index 6f3d3bd..07e33bb 100644
--- a/src/proguard/optimize/info/SuperInvocationMarker.java
+++ b/src/proguard/optimize/info/SuperInvocationMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/info/VariableUsageMarker.java b/src/proguard/optimize/info/VariableUsageMarker.java
index 660c4ba..a1c6a9a 100644
--- a/src/proguard/optimize/info/VariableUsageMarker.java
+++ b/src/proguard/optimize/info/VariableUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -27,6 +27,8 @@
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor marks the local variables that are used in the code
* attributes that it visits.
@@ -62,14 +64,13 @@
// Try to reuse the previous array.
if (variableUsed.length < maxLocals)
{
+ // Create a new array.
variableUsed = new boolean[maxLocals];
}
else
{
- for (int index = 0; index < maxLocals; index++)
- {
- variableUsed[index] = false;
- }
+ // Reset the array.
+ Arrays.fill(variableUsed, 0, maxLocals, false);
}
codeAttribute.instructionsAccept(clazz, method, this);
diff --git a/src/proguard/optimize/peephole/BranchTargetFinder.java b/src/proguard/optimize/peephole/BranchTargetFinder.java
index 8f650bb..7e5a11f 100644
--- a/src/proguard/optimize/peephole/BranchTargetFinder.java
+++ b/src/proguard/optimize/peephole/BranchTargetFinder.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,6 +29,8 @@
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor finds all instruction offsets, branch targets, and
* exception targets in the CodeAttribute objects that it visits.
@@ -312,25 +314,19 @@
initializationOffsets = new int[codeLength];
// Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- subroutineStarts[index] = NONE;
- subroutineEnds[index] = NONE;
- creationOffsets[index] = NONE;
- initializationOffsets[index] = NONE;
- }
+ Arrays.fill(subroutineStarts, 0, codeLength, NONE);
+ Arrays.fill(subroutineEnds, 0, codeLength, NONE);
+ Arrays.fill(creationOffsets, 0, codeLength, NONE);
+ Arrays.fill(initializationOffsets, 0, codeLength, NONE);
}
else
{
// Reset the arrays.
- for (int index = 0; index < codeLength; index++)
- {
- instructionMarks[index] = 0;
- subroutineStarts[index] = NONE;
- subroutineEnds[index] = NONE;
- creationOffsets[index] = NONE;
- initializationOffsets[index] = NONE;
- }
+ Arrays.fill(instructionMarks, 0, codeLength, (short)0);
+ Arrays.fill(subroutineStarts, 0, codeLength, NONE);
+ Arrays.fill(subroutineEnds, 0, codeLength, NONE);
+ Arrays.fill(creationOffsets, 0, codeLength, NONE);
+ Arrays.fill(initializationOffsets, 0, codeLength, NONE);
instructionMarks[codeLength] = 0;
}
diff --git a/src/proguard/optimize/peephole/ClassFinalizer.java b/src/proguard/optimize/peephole/ClassFinalizer.java
index b5e54f8..063f254 100644
--- a/src/proguard/optimize/peephole/ClassFinalizer.java
+++ b/src/proguard/optimize/peephole/ClassFinalizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/ClassMerger.java b/src/proguard/optimize/peephole/ClassMerger.java
index 1e1a950..4971cab 100644
--- a/src/proguard/optimize/peephole/ClassMerger.java
+++ b/src/proguard/optimize/peephole/ClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,6 +21,7 @@
package proguard.optimize.peephole;
import proguard.classfile.*;
+import proguard.classfile.constant.ClassConstant;
import proguard.classfile.constant.visitor.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
@@ -59,6 +60,8 @@
private final boolean mergeInterfacesAggressively;
private final ClassVisitor extraClassVisitor;
+ private final MemberVisitor fieldOptimizationInfoCopier = new FieldOptimizationInfoCopier();
+
/**
* Creates a new ClassMerger that will merge classes into the given target
@@ -151,7 +154,7 @@
// infinite recursion.
(programClass.getAccessFlags() & ClassConstants.INTERNAL_ACC_ANNOTATTION) == 0 &&
- // Only merge classes if we can change the access permissioms, or
+ // Only merge classes if we can change the access permissions, or
// if they are in the same package, or
// if they are public and don't contain or invoke package visible
// class members.
@@ -235,11 +238,12 @@
targetClass.u2accessFlags =
((targetAccessFlags &
sourceAccessFlags) &
- (ClassConstants.INTERNAL_ACC_INTERFACE |
+ (ClassConstants.INTERNAL_ACC_INTERFACE |
ClassConstants.INTERNAL_ACC_ABSTRACT)) |
((targetAccessFlags |
sourceAccessFlags) &
- (ClassConstants.INTERNAL_ACC_PUBLIC |
+ (ClassConstants.INTERNAL_ACC_PUBLIC |
+ ClassConstants.INTERNAL_ACC_SUPER |
ClassConstants.INTERNAL_ACC_ANNOTATTION |
ClassConstants.INTERNAL_ACC_ENUM));
@@ -260,7 +264,7 @@
// Copy over the class members.
MemberAdder memberAdder =
- new MemberAdder(targetClass);
+ new MemberAdder(targetClass, fieldOptimizationInfoCopier);
programClass.fieldsAccept(memberAdder);
programClass.methodsAccept(memberAdder);
@@ -336,10 +340,8 @@
// Visit all superclasses and interfaces, collecting the ones that have
// static initializers.
clazz.hierarchyAccept(true, true, true, false,
- new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
- ClassConstants.INTERNAL_METHOD_TYPE_INIT,
- new MemberToClassVisitor(
- new ClassCollector(set))));
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
return set;
}
@@ -368,12 +370,19 @@
*/
private Set caughtSuperClasses(Clazz clazz)
{
+ // Don't bother if this isn't an exception at all.
+ if (!clazz.extends_(ClassConstants.INTERNAL_NAME_JAVA_LANG_THROWABLE))
+ {
+ return Collections.EMPTY_SET;
+ }
+
+ // Visit all superclasses, collecting the ones that are caught
+ // (plus java.lang.Object, in the current implementation).
Set set = new HashSet();
- // Visit all superclasses, collecting the ones that are caught.
clazz.hierarchyAccept(true, true, false, false,
new CaughtClassFilter(
- new ClassCollector(set)));
+ new ClassCollector(set)));
return set;
}
@@ -538,4 +547,30 @@
targetClass = clazz;
}
}
+
+
+ /**
+ * This MemberVisitor copies field optimization info from copied fields.
+ */
+ private static class FieldOptimizationInfoCopier
+ extends SimplifiedVisitor
+ implements MemberVisitor
+ {
+ public void visitProgramField(ProgramClass programClass, ProgramField programField)
+ {
+ // Copy the optimization info from the field that was just copied.
+ ProgramField copiedField = (ProgramField)programField.getVisitorInfo();
+ Object info = copiedField.getVisitorInfo();
+
+ programField.setVisitorInfo(info instanceof FieldOptimizationInfo ?
+ new FieldOptimizationInfo((FieldOptimizationInfo)info) :
+ info);
+ }
+
+
+ public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
+ {
+ // Linked methods share their optimization info.
+ }
+ }
}
\ No newline at end of file
diff --git a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
index 4833275..0dd93b1 100644
--- a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
+++ b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/GotoGotoReplacer.java b/src/proguard/optimize/peephole/GotoGotoReplacer.java
index 7d7e66c..d05d7b6 100644
--- a/src/proguard/optimize/peephole/GotoGotoReplacer.java
+++ b/src/proguard/optimize/peephole/GotoGotoReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -84,8 +84,9 @@
int branchOffset = branchInstruction.branchOffset;
int targetOffset = offset + branchOffset;
- if (branchOffset != branchInstruction.length(offset) &&
- !codeAttributeEditor.isModified(offset) &&
+ if (branchOffset != 0 &&
+ branchOffset != branchInstruction.length(offset) &&
+ !codeAttributeEditor.isModified(offset) &&
!codeAttributeEditor.isModified(targetOffset))
{
Instruction targetInstruction =
diff --git a/src/proguard/optimize/peephole/GotoReturnReplacer.java b/src/proguard/optimize/peephole/GotoReturnReplacer.java
index 5c3eb77..cafda92 100644
--- a/src/proguard/optimize/peephole/GotoReturnReplacer.java
+++ b/src/proguard/optimize/peephole/GotoReturnReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/HorizontalClassMerger.java b/src/proguard/optimize/peephole/HorizontalClassMerger.java
index a37b9a5..d12c2c0 100644
--- a/src/proguard/optimize/peephole/HorizontalClassMerger.java
+++ b/src/proguard/optimize/peephole/HorizontalClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/InstructionSequenceConstants.java b/src/proguard/optimize/peephole/InstructionSequenceConstants.java
index b33204b..eb24061 100644
--- a/src/proguard/optimize/peephole/InstructionSequenceConstants.java
+++ b/src/proguard/optimize/peephole/InstructionSequenceConstants.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -20,81 +20,179 @@
*/
package proguard.optimize.peephole;
+import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.instruction.*;
-import proguard.classfile.util.InstructionSequenceMatcher;
+import proguard.classfile.visitor.ClassPrinter;
/**
* This class contains a set of instruction sequences and their suggested
* replacements.
*
* @see InstructionSequencesReplacer
+ * @see InstructionSequenceReplacer
* @author Eric Lafortune
*/
public class InstructionSequenceConstants
{
- public static final int X = InstructionSequenceMatcher.X;
- public static final int Y = InstructionSequenceMatcher.Y;
- public static final int Z = InstructionSequenceMatcher.Z;
+ private static final int X = InstructionSequenceReplacer.X;
+ private static final int Y = InstructionSequenceReplacer.Y;
+ private static final int Z = InstructionSequenceReplacer.Z;
- public static final int A = InstructionSequenceMatcher.A;
- public static final int B = InstructionSequenceMatcher.B;
- public static final int C = InstructionSequenceMatcher.C;
- public static final int D = InstructionSequenceMatcher.D;
+ private static final int A = InstructionSequenceReplacer.A;
+ private static final int B = InstructionSequenceReplacer.B;
+ private static final int C = InstructionSequenceReplacer.C;
+ private static final int D = InstructionSequenceReplacer.D;
+ private static final int STRING_A_LENGTH = InstructionSequenceReplacer.STRING_A_LENGTH;
+ private static final int BOOLEAN_A_STRING = InstructionSequenceReplacer.BOOLEAN_A_STRING;
+ private static final int CHAR_A_STRING = InstructionSequenceReplacer.CHAR_A_STRING;
+ private static final int INT_A_STRING = InstructionSequenceReplacer.INT_A_STRING;
+ private static final int LONG_A_STRING = InstructionSequenceReplacer.LONG_A_STRING;
+ private static final int FLOAT_A_STRING = InstructionSequenceReplacer.FLOAT_A_STRING;
+ private static final int DOUBLE_A_STRING = InstructionSequenceReplacer.DOUBLE_A_STRING;
+ private static final int STRING_A_STRING = InstructionSequenceReplacer.STRING_A_STRING;
+ private static final int BOOLEAN_B_STRING = InstructionSequenceReplacer.BOOLEAN_B_STRING;
+ private static final int CHAR_B_STRING = InstructionSequenceReplacer.CHAR_B_STRING;
+ private static final int INT_B_STRING = InstructionSequenceReplacer.INT_B_STRING;
+ private static final int LONG_B_STRING = InstructionSequenceReplacer.LONG_B_STRING;
+ private static final int FLOAT_B_STRING = InstructionSequenceReplacer.FLOAT_B_STRING;
+ private static final int DOUBLE_B_STRING = InstructionSequenceReplacer.DOUBLE_B_STRING;
+ private static final int STRING_B_STRING = InstructionSequenceReplacer.STRING_B_STRING;
- private static final int I_32768 = 0;
- private static final int I_65536 = 1;
- private static final int I_16777216 = 2;
+ private static final int I_32768 = 0;
+ private static final int I_65536 = 1;
+ private static final int I_16777216 = 2;
// private static final int I_0x000000ff
- private static final int I_0x0000ff00 = 3;
- private static final int I_0x00ff0000 = 4;
- private static final int I_0xff000000 = 5;
- private static final int I_0x0000ffff = 6;
- private static final int I_0xffff0000 = 7;
+ private static final int I_0x0000ff00 = 3;
+ private static final int I_0x00ff0000 = 4;
+ private static final int I_0xff000000 = 5;
+ private static final int I_0x0000ffff = 6;
+ private static final int I_0xffff0000 = 7;
- private static final int L_M1 = 8;
- private static final int L_2 = 9;
- private static final int L_4 = 10;
- private static final int L_8 = 11;
- private static final int L_16 = 12;
- private static final int L_32 = 13;
- private static final int L_64 = 14;
- private static final int L_128 = 15;
- private static final int L_256 = 16;
- private static final int L_512 = 17;
- private static final int L_1024 = 18;
- private static final int L_2048 = 19;
- private static final int L_4096 = 20;
- private static final int L_8192 = 21;
- private static final int L_16384 = 22;
- private static final int L_32768 = 23;
- private static final int L_65536 = 24;
- private static final int L_16777216 = 25;
- private static final int L_4294967296 = 26;
+ private static final int L_M1 = 8;
+ private static final int L_2 = 9;
+ private static final int L_4 = 10;
+ private static final int L_8 = 11;
+ private static final int L_16 = 12;
+ private static final int L_32 = 13;
+ private static final int L_64 = 14;
+ private static final int L_128 = 15;
+ private static final int L_256 = 16;
+ private static final int L_512 = 17;
+ private static final int L_1024 = 18;
+ private static final int L_2048 = 19;
+ private static final int L_4096 = 20;
+ private static final int L_8192 = 21;
+ private static final int L_16384 = 22;
+ private static final int L_32768 = 23;
+ private static final int L_65536 = 24;
+ private static final int L_16777216 = 25;
+ private static final int L_4294967296 = 26;
- private static final int L_0x00000000ffffffff = 27;
- private static final int L_0xffffffff00000000 = 28;
+ private static final int L_0x00000000ffffffff = 27;
+ private static final int L_0xffffffff00000000 = 28;
- private static final int F_M1 = 29;
+ private static final int F_M1 = 29;
- private static final int D_M1 = 30;
+ private static final int D_M1 = 30;
- private static final int FIELD_I = 31;
- private static final int FIELD_L = 32;
- private static final int FIELD_F = 33;
- private static final int FIELD_D = 34;
+ private static final int STRING_EMPTY = 31;
- private static final int NAME_AND_TYPE_I = 35;
- private static final int NAME_AND_TYPE_L = 36;
- private static final int NAME_AND_TYPE_F = 37;
- private static final int NAME_AND_TYPE_D = 38;
+ private static final int FIELD_I = 32;
+ private static final int FIELD_L = 33;
+ private static final int FIELD_F = 34;
+ private static final int FIELD_D = 35;
- private static final int TYPE_I = 39;
- private static final int TYPE_L = 40;
- private static final int TYPE_F = 41;
- private static final int TYPE_D = 42;
+ private static final int METHOD_STRING_EQUALS = 36;
+ private static final int METHOD_STRING_LENGTH = 37;
+ private static final int METHOD_STRINGBUFFER_INIT = 38;
+ private static final int METHOD_STRINGBUFFER_INIT_STRING = 39;
+ private static final int METHOD_STRINGBUFFER_APPEND_BOOLEAN = 40;
+ private static final int METHOD_STRINGBUFFER_APPEND_CHAR = 41;
+ private static final int METHOD_STRINGBUFFER_APPEND_INTEGER = 42;
+ private static final int METHOD_STRINGBUFFER_APPEND_LONG = 43;
+ private static final int METHOD_STRINGBUFFER_APPEND_FLOAT = 44;
+ private static final int METHOD_STRINGBUFFER_APPEND_DOUBLE = 45;
+ private static final int METHOD_STRINGBUFFER_APPEND_STRING = 46;
+ private static final int METHOD_STRINGBUFFER_LENGTH = 47;
+ private static final int METHOD_STRINGBUFFER_TOSTRING = 48;
+ private static final int METHOD_STRINGBUILDER_INIT = 49;
+ private static final int METHOD_STRINGBUILDER_INIT_STRING = 50;
+ private static final int METHOD_STRINGBUILDER_APPEND_BOOLEAN = 51;
+ private static final int METHOD_STRINGBUILDER_APPEND_CHAR = 52;
+ private static final int METHOD_STRINGBUILDER_APPEND_INTEGER = 53;
+ private static final int METHOD_STRINGBUILDER_APPEND_LONG = 54;
+ private static final int METHOD_STRINGBUILDER_APPEND_FLOAT = 55;
+ private static final int METHOD_STRINGBUILDER_APPEND_DOUBLE = 56;
+ private static final int METHOD_STRINGBUILDER_APPEND_STRING = 57;
+ private static final int METHOD_STRINGBUILDER_LENGTH = 58;
+ private static final int METHOD_STRINGBUILDER_TOSTRING = 59;
+
+ private static final int CLASS_STRING = 60;
+ private static final int CLASS_STRINGBUFFER = 61;
+ private static final int CLASS_STRINGBUILDER = 62;
+
+ private static final int NAME_AND_TYPE_I = 63;
+ private static final int NAME_AND_TYPE_L = 64;
+ private static final int NAME_AND_TYPE_F = 65;
+ private static final int NAME_AND_TYPE_D = 66;
+
+ private static final int NAME_AND_TYPE_EQUALS = 67;
+ private static final int NAME_AND_TYPE_LENGTH = 68;
+ private static final int NAME_AND_TYPE_INIT = 69;
+ private static final int NAME_AND_TYPE_INIT_STRING = 70;
+ private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUFFER = 71;
+ private static final int NAME_AND_TYPE_APPEND_C_STRINGBUFFER = 72;
+ private static final int NAME_AND_TYPE_APPEND_I_STRINGBUFFER = 73;
+ private static final int NAME_AND_TYPE_APPEND_J_STRINGBUFFER = 74;
+ private static final int NAME_AND_TYPE_APPEND_F_STRINGBUFFER = 75;
+ private static final int NAME_AND_TYPE_APPEND_D_STRINGBUFFER = 76;
+ private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER = 77;
+ private static final int NAME_AND_TYPE_APPEND_Z_STRINGBUILDER = 78;
+ private static final int NAME_AND_TYPE_APPEND_C_STRINGBUILDER = 79;
+ private static final int NAME_AND_TYPE_APPEND_I_STRINGBUILDER = 80;
+ private static final int NAME_AND_TYPE_APPEND_J_STRINGBUILDER = 81;
+ private static final int NAME_AND_TYPE_APPEND_F_STRINGBUILDER = 82;
+ private static final int NAME_AND_TYPE_APPEND_D_STRINGBUILDER = 83;
+ private static final int NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER = 84;
+ private static final int NAME_AND_TYPE_TOSTRING = 85;
+
+ private static final int UTF8_EMPTY = 86;
+ private static final int UTF8_I = 87;
+ private static final int UTF8_L = 88;
+ private static final int UTF8_F = 89;
+ private static final int UTF8_D = 90;
+ private static final int UTF8_STRING = 91;
+ private static final int UTF8_STRINGBUFFER = 92;
+ private static final int UTF8_STRINGBUILDER = 93;
+ private static final int UTF8_EQUALS = 94;
+ private static final int UTF8_OBJECT_Z = 95;
+ private static final int UTF8_LENGTH = 96;
+ private static final int UTF8__I = 97;
+ private static final int UTF8_INIT = 98;
+ private static final int UTF8__VOID = 99;
+ private static final int UTF8_STRING_VOID = 100;
+ private static final int UTF8_TOSTRING = 101;
+ private static final int UTF8__STRING = 102;
+ private static final int UTF8_APPEND = 103;
+ private static final int UTF8_Z_STRINGBUFFER = 104;
+ private static final int UTF8_C_STRINGBUFFER = 105;
+ private static final int UTF8_I_STRINGBUFFER = 106;
+ private static final int UTF8_J_STRINGBUFFER = 107;
+ private static final int UTF8_F_STRINGBUFFER = 108;
+ private static final int UTF8_D_STRINGBUFFER = 109;
+ private static final int UTF8_STRING_STRINGBUFFER = 110;
+ private static final int UTF8_Z_STRINGBUILDER = 111;
+ private static final int UTF8_C_STRINGBUILDER = 112;
+ private static final int UTF8_I_STRINGBUILDER = 113;
+ private static final int UTF8_J_STRINGBUILDER = 114;
+ private static final int UTF8_F_STRINGBUILDER = 115;
+ private static final int UTF8_D_STRINGBUILDER = 116;
+ private static final int UTF8_STRING_STRINGBUILDER = 117;
+
+ private static final int SENTINEL = 118;
public static final Constant[] CONSTANTS = new Constant[]
@@ -136,23 +234,100 @@
new DoubleConstant(-1d),
+ new StringConstant(UTF8_EMPTY, null, null),
+
new FieldrefConstant(X, NAME_AND_TYPE_I, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_L, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_F, null, null),
new FieldrefConstant(X, NAME_AND_TYPE_D, null, null),
- new NameAndTypeConstant(Y, TYPE_I),
- new NameAndTypeConstant(Y, TYPE_L),
- new NameAndTypeConstant(Y, TYPE_F),
- new NameAndTypeConstant(Y, TYPE_D),
+ new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_EQUALS, null, null),
+ new MethodrefConstant(CLASS_STRING, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_INIT_STRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_Z_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_C_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_I_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_J_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_F_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_D_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_APPEND_STRING_STRINGBUFFER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUFFER, NAME_AND_TYPE_TOSTRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_INIT_STRING, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_Z_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_C_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_I_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_J_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_F_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_D_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_APPEND_STRING_STRINGBUILDER, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_LENGTH, null, null),
+ new MethodrefConstant(CLASS_STRINGBUILDER, NAME_AND_TYPE_TOSTRING, null, null),
+ new ClassConstant(UTF8_STRING, null),
+ new ClassConstant(UTF8_STRINGBUFFER, null),
+ new ClassConstant(UTF8_STRINGBUILDER, null),
+
+ new NameAndTypeConstant(Y, UTF8_I),
+ new NameAndTypeConstant(Y, UTF8_L),
+ new NameAndTypeConstant(Y, UTF8_F),
+ new NameAndTypeConstant(Y, UTF8_D),
+ new NameAndTypeConstant(UTF8_EQUALS, UTF8_OBJECT_Z),
+ new NameAndTypeConstant(UTF8_LENGTH, UTF8__I),
+ new NameAndTypeConstant(UTF8_INIT, UTF8__VOID),
+ new NameAndTypeConstant(UTF8_INIT, UTF8_STRING_VOID),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUFFER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_Z_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_C_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_I_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_J_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_F_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_D_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_APPEND, UTF8_STRING_STRINGBUILDER),
+ new NameAndTypeConstant(UTF8_TOSTRING, UTF8__STRING),
+
+ new Utf8Constant(""),
new Utf8Constant("I"),
new Utf8Constant("J"),
new Utf8Constant("F"),
new Utf8Constant("D"),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_EQUALS),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_EQUALS),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_LENGTH),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LENGTH),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_INIT),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INIT),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_VOID),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_TOSTRING),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_TOSTRING),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_NAME_APPEND),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUFFER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_BOOLEAN_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_CHAR_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_INT_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_LONG_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_FLOAT_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_DOUBLE_STRING_BUILDER),
+ new Utf8Constant(ClassConstants.INTERNAL_METHOD_TYPE_STRING_STRING_BUILDER),
};
-
public static final Instruction[][][] VARIABLE = new Instruction[][][]
{
{ // nop = nothing
@@ -237,7 +412,7 @@
{ // a = a = nothing
{
new VariableInstruction(InstructionConstants.OP_ALOAD, X),
- new SimpleInstruction(InstructionConstants.OP_POP),
+ new VariableInstruction(InstructionConstants.OP_ASTORE, X),
},{
// Nothing.
},
@@ -382,12 +557,12 @@
},
{ // c * i = i * c
{
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
new SimpleInstruction(InstructionConstants.OP_IMUL),
},{
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new SimpleInstruction(InstructionConstants.OP_IMUL),
},
},
@@ -548,7 +723,7 @@
{ // i = i + c = i += c
{
new VariableInstruction(InstructionConstants.OP_ILOAD, X),
- new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, A),
new SimpleInstruction(InstructionConstants.OP_IADD),
new VariableInstruction(InstructionConstants.OP_ISTORE, X),
},{
@@ -651,22 +826,23 @@
// Nothing.
},
},
- { // ... + 0f = ...
- {
- new SimpleInstruction(InstructionConstants.OP_FCONST_0),
- new SimpleInstruction(InstructionConstants.OP_FADD),
- },{
- // Nothing.
- },
- },
- { // ... + 0d = ...
- {
- new SimpleInstruction(InstructionConstants.OP_DCONST_0),
- new SimpleInstruction(InstructionConstants.OP_DADD),
- },{
- // Nothing.
- },
- },
+ // Not valid for -0.0.
+// { // ... + 0f = ...
+// {
+// new SimpleInstruction(InstructionConstants.OP_FCONST_0),
+// new SimpleInstruction(InstructionConstants.OP_FADD),
+// },{
+// // Nothing.
+// },
+// },
+// { // ... + 0d = ...
+// {
+// new SimpleInstruction(InstructionConstants.OP_DCONST_0),
+// new SimpleInstruction(InstructionConstants.OP_DADD),
+// },{
+// // Nothing.
+// },
+// },
{ // ... - 0 = ...
{
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
@@ -1072,7 +1248,8 @@
new SimpleInstruction(InstructionConstants.OP_FNEG),
},
},
-// { // ... * 0f = 0f (or NaN)
+ // Not valid for -0.0 and for NaN.
+// { // ... * 0f = 0f
// {
// new SimpleInstruction(InstructionConstants.OP_FCONST_0),
// new SimpleInstruction(InstructionConstants.OP_FMUL),
@@ -1097,7 +1274,8 @@
new SimpleInstruction(InstructionConstants.OP_DNEG),
},
},
-// { // ... * 0d = 0d (or NaN)
+ // Not valid for -0.0 and for NaN.
+// { // ... * 0d = 0d
// {
// new SimpleInstruction(InstructionConstants.OP_DCONST_0),
// new SimpleInstruction(InstructionConstants.OP_DMUL),
@@ -1504,6 +1682,7 @@
new SimpleInstruction(InstructionConstants.OP_ICONST_0),
},
},
+ // Not valid for negative values.
// { // ... % 2 = ... & 0x1
// {
// new SimpleInstruction(InstructionConstants.OP_ICONST_2),
@@ -3348,4 +3527,898 @@
// },
// }
};
-}
\ No newline at end of file
+
+ public static final Instruction[][][] STRING = new Instruction[][][]
+ {
+ { // "...".equals("...") = true
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_EQUALS),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_ICONST_1),
+ },
+ },
+ { // "...".length() = ...
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRING_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+
+ { // new StringBuffer("...").toString() = "..." (ignoring identity)
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_TOSTRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ },
+ },
+ { // new StringBuffer("...").length() = length
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUFFER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+ { // StringBuffer#append("") = nothing
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ // Nothing.
+ },
+ },
+ { // new StringBuffer().append(Z) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(C) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Cc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(I) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Ic) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(J) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Jc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(F) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Fc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(D) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append(Dc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer().append("...") = new StringBuffer("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Z) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(C) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Cc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(I) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Ic) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(J) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Jc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(F) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Fc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(D) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append(Dc) = new StringBuffer("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // new StringBuffer("...").append("...") = new StringBuffer("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUFFER_INIT_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Z) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(C) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Cc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(I) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Ic) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(J) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Jc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(F) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Fc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(D) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append(Dc) = StringBuffer#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+ { // StringBuffer#append("...").append("...") = StringBuffer#append("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUFFER_APPEND_STRING),
+ },
+ },
+
+ { // new StringBuilder("...").toString() = "..." (ignoring identity)
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_TOSTRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ },
+ },
+ { // new StringBuilder("...").length() = length
+ {
+ new ConstantInstruction(InstructionConstants.OP_NEW, CLASS_STRINGBUILDER),
+ new SimpleInstruction(InstructionConstants.OP_DUP),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_LENGTH),
+ },{
+ new SimpleInstruction(InstructionConstants.OP_SIPUSH, STRING_A_LENGTH),
+ },
+ },
+ { // StringBuilder#append("") = nothing
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_EMPTY),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ // Nothing.
+ },
+ },
+ { // new StringBuilder().append(Z) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, BOOLEAN_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(C) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Cc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, CHAR_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(I) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Ic) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, INT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(J) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Jc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, LONG_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(F) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Fc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, FLOAT_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(D) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append(Dc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, DOUBLE_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder().append("...") = new StringBuilder("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT),
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Z) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(C) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Cc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(I) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Ic) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(J) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Jc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(F) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Fc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(D) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append(Dc) = new StringBuilder("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // new StringBuilder("...").append("...") = new StringBuilder("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKESPECIAL, METHOD_STRINGBUILDER_INIT_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Z) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_BOOLEAN),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | BOOLEAN_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(C) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Cc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_CHAR),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | CHAR_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(I) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_ICONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Ic) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_INTEGER),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | INT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(J) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_LCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Jc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_LONG),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | LONG_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(F) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_FCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Fc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_FLOAT),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | FLOAT_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(D) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new SimpleInstruction(InstructionConstants.OP_DCONST_0, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append(Dc) = StringBuilder#append("....")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC2_W, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_DOUBLE),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | DOUBLE_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ { // StringBuilder#append("...").append("...") = StringBuilder#append("......")
+ {
+ new ConstantInstruction(InstructionConstants.OP_LDC, A),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ new ConstantInstruction(InstructionConstants.OP_LDC, B),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },{
+ new ConstantInstruction(InstructionConstants.OP_LDC, STRING_A_STRING | STRING_B_STRING),
+ new ConstantInstruction(InstructionConstants.OP_INVOKEVIRTUAL, METHOD_STRINGBUILDER_APPEND_STRING),
+ },
+ },
+ };
+
+ /*
+ static
+ {
+ ProgramClass clazz = new ProgramClass();
+ clazz.constantPool = CONSTANTS;
+
+ ClassPrinter printer = new ClassPrinter();
+
+ for (int index = 0; index < CONSTANTS.length; index++)
+ {
+ System.out.print("["+index+"] ");
+ try
+ {
+ CONSTANTS[index].accept(clazz, printer);
+ }
+ catch (Exception e)
+ {
+ System.out.println("("+e.getClass().getName()+")");
+ }
+ }
+
+ if (CONSTANTS.length != SENTINEL)
+ {
+ throw new IllegalStateException("Constants length ["+CONSTANTS.length+"] different from number of constant names ["+SENTINEL+"]");
+ }
+
+ Instruction[] instructions = STRING[2][0];
+
+ for (int index = 0; index < instructions.length; index++)
+ {
+ Instruction instruction = instructions[index];
+ try
+ {
+ instruction.accept(clazz, null, null, index, new ClassPrinter());
+ }
+ catch (Exception e)
+ {
+ //System.out.println(" "+instruction.toString(offset));
+ }
+ }
+ }
+ //*/
+}
diff --git a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java b/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
index bce06e2..be65b53 100644
--- a/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
+++ b/src/proguard/optimize/peephole/InstructionSequenceReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -22,9 +22,9 @@
import proguard.classfile.*;
import proguard.classfile.attribute.CodeAttribute;
-import proguard.classfile.constant.Constant;
+import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
-import proguard.classfile.editor.CodeAttributeEditor;
+import proguard.classfile.editor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
@@ -42,10 +42,48 @@
implements InstructionVisitor,
ConstantVisitor
{
+ /*
+ public static boolean DEBUG = true;
+ /*/
private static final boolean DEBUG = false;
+ //*/
+
+ public static final int X = InstructionSequenceMatcher.X;
+ public static final int Y = InstructionSequenceMatcher.Y;
+ public static final int Z = InstructionSequenceMatcher.Z;
+
+ public static final int A = InstructionSequenceMatcher.A;
+ public static final int B = InstructionSequenceMatcher.B;
+ public static final int C = InstructionSequenceMatcher.C;
+ public static final int D = InstructionSequenceMatcher.D;
+
+ private static final int BOOLEAN_STRING = 0x1;
+ private static final int CHAR_STRING = 0x2;
+ private static final int INT_STRING = 0x3;
+ private static final int LONG_STRING = 0x4;
+ private static final int FLOAT_STRING = 0x5;
+ private static final int DOUBLE_STRING = 0x6;
+ private static final int STRING_STRING = 0x7;
+
+ public static final int STRING_A_LENGTH = 0x20000000;
+ public static final int BOOLEAN_A_STRING = 0x20000001;
+ public static final int CHAR_A_STRING = 0x20000002;
+ public static final int INT_A_STRING = 0x20000003;
+ public static final int LONG_A_STRING = 0x20000004;
+ public static final int FLOAT_A_STRING = 0x20000005;
+ public static final int DOUBLE_A_STRING = 0x20000006;
+ public static final int STRING_A_STRING = 0x20000007;
+ public static final int BOOLEAN_B_STRING = 0x20000010;
+ public static final int CHAR_B_STRING = 0x20000020;
+ public static final int INT_B_STRING = 0x20000030;
+ public static final int LONG_B_STRING = 0x20000040;
+ public static final int FLOAT_B_STRING = 0x20000050;
+ public static final int DOUBLE_B_STRING = 0x20000060;
+ public static final int STRING_B_STRING = 0x20000070;
private final InstructionSequenceMatcher instructionSequenceMatcher;
+ private final Constant[] patternConstants;
private final Instruction[] replacementInstructions;
private final BranchTargetFinder branchTargetFinder;
private final CodeAttributeEditor codeAttributeEditor;
@@ -101,6 +139,7 @@
InstructionVisitor extraInstructionVisitor)
{
this.instructionSequenceMatcher = new InstructionSequenceMatcher(patternConstants, patternInstructions);
+ this.patternConstants = patternConstants;
this.replacementInstructions = replacementInstructions;
this.branchTargetFinder = branchTargetFinder;
this.codeAttributeEditor = codeAttributeEditor;
@@ -140,7 +179,7 @@
for (int index = 0; index < replacementInstructions.length; index++)
{
int matchedOffset = instructionSequenceMatcher.matchedInstructionOffset(index);
- System.out.println(" "+replacementInstructionFactory.create(index).shrink().toString(matchedOffset));
+ System.out.println(" "+replacementInstructionFactory.create(clazz, index).shrink().toString(matchedOffset));
}
}
@@ -148,7 +187,7 @@
for (int index = 0; index < replacementInstructions.length; index++)
{
codeAttributeEditor.replaceInstruction(instructionSequenceMatcher.matchedInstructionOffset(index),
- replacementInstructionFactory.create(index).shrink());
+ replacementInstructionFactory.create(clazz, index).shrink());
}
// Delete any remaining instructions in the from sequence.
@@ -204,10 +243,10 @@
* Creates the replacement instruction for the given index in the
* instruction sequence.
*/
- public Instruction create(int index)
+ public Instruction create(Clazz clazz, int index)
{
// Create the instruction.
- replacementInstructions[index].accept(null,
+ replacementInstructions[index].accept(clazz,
null,
null,
instructionSequenceMatcher.matchedInstructionOffset(index),
@@ -224,7 +263,7 @@
{
replacementInstruction =
new SimpleInstruction(simpleInstruction.opcode,
- instructionSequenceMatcher.matchedArgument(simpleInstruction.constant));
+ matchedArgument(clazz, simpleInstruction.constant));
}
@@ -241,7 +280,8 @@
{
replacementInstruction =
new ConstantInstruction(constantInstruction.opcode,
- instructionSequenceMatcher.matchedConstantIndex(constantInstruction.constantIndex),
+ matchedConstantIndex((ProgramClass)clazz,
+ constantInstruction.constantIndex),
instructionSequenceMatcher.matchedArgument(constantInstruction.constant));
}
@@ -250,7 +290,8 @@
{
replacementInstruction =
new BranchInstruction(branchInstruction.opcode,
- instructionSequenceMatcher.matchedBranchOffset(offset, branchInstruction.branchOffset));
+ instructionSequenceMatcher.matchedBranchOffset(offset,
+ branchInstruction.branchOffset));
}
@@ -261,7 +302,8 @@
instructionSequenceMatcher.matchedBranchOffset(offset, tableSwitchInstruction.defaultOffset),
instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.lowCase),
instructionSequenceMatcher.matchedArgument(tableSwitchInstruction.highCase),
- instructionSequenceMatcher.matchedJumpOffsets(offset, tableSwitchInstruction.jumpOffsets));
+ instructionSequenceMatcher.matchedJumpOffsets(offset,
+ tableSwitchInstruction.jumpOffsets));
}
@@ -274,5 +316,105 @@
instructionSequenceMatcher.matchedArguments(lookUpSwitchInstruction.cases),
instructionSequenceMatcher.matchedJumpOffsets(offset, lookUpSwitchInstruction.jumpOffsets));
}
+
+
+ /**
+ * Returns the matched argument for the given pattern argument.
+ */
+ private int matchedArgument(Clazz clazz, int argument)
+ {
+ // Special case: do we have to compute the string length?
+ if (argument == STRING_A_LENGTH)
+ {
+ // Return the string length.
+ return clazz.getStringString(instructionSequenceMatcher.matchedArgument(A)).length();
+ }
+
+ // Otherwise, just return the matched argument.
+ return instructionSequenceMatcher.matchedArgument(argument);
+ }
+
+
+ /**
+ * Returns the matched or newly created constant index for the given
+ * pattern constant index.
+ */
+ private int matchedConstantIndex(ProgramClass programClass, int constantIndex)
+ {
+ // Special case: do we have to create a concatenated string?
+ if (constantIndex >= BOOLEAN_A_STRING &&
+ constantIndex <= (STRING_A_STRING | STRING_B_STRING))
+ {
+ // Create a new string constant and return its index.
+ return new ConstantPoolEditor(programClass).addStringConstant(
+ argumentAsString(programClass, constantIndex & 0xf, A) +
+ argumentAsString(programClass, (constantIndex >>> 4) & 0xf, B),
+ null,
+ null);
+ }
+
+ int matchedConstantIndex =
+ instructionSequenceMatcher.matchedConstantIndex(constantIndex);
+
+ // Do we have a matched constant index?
+ if (matchedConstantIndex > 0)
+ {
+ // Return its index.
+ return matchedConstantIndex;
+ }
+
+ // Otherwise, we still have to create a new constant.
+ // This currently only works for constants without any wildcards.
+ ProgramClass dummyClass = new ProgramClass();
+ dummyClass.constantPool = patternConstants;
+
+ return new ConstantAdder(programClass).addConstant(dummyClass, constantIndex);
+ }
+
+
+ private String argumentAsString(ProgramClass programClass,
+ int valueType,
+ int argument)
+ {
+ switch (valueType)
+ {
+ case BOOLEAN_STRING:
+ return Boolean.toString((instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument)) != 0);
+
+ case CHAR_STRING:
+ return Character.toString((char)(instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument)));
+
+ case INT_STRING:
+ return Integer.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((IntegerConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case LONG_STRING:
+ return Long.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((LongConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case FLOAT_STRING:
+ return Float.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((FloatConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case DOUBLE_STRING:
+ return Double.toString(instructionSequenceMatcher.wasConstant(argument) ?
+ ((DoubleConstant)(programClass.getConstant(instructionSequenceMatcher.matchedConstantIndex(argument)))).getValue() :
+ instructionSequenceMatcher.matchedArgument(argument));
+
+ case STRING_STRING:
+ return
+ programClass.getStringString(instructionSequenceMatcher.matchedConstantIndex(argument));
+
+ default:
+ return "";
+ }
+ }
}
}
diff --git a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java b/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
index f12b51a..72fc334 100644
--- a/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
+++ b/src/proguard/optimize/peephole/InstructionSequencesReplacer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/MemberPrivatizer.java b/src/proguard/optimize/peephole/MemberPrivatizer.java
index 55b2f31..254e968 100644
--- a/src/proguard/optimize/peephole/MemberPrivatizer.java
+++ b/src/proguard/optimize/peephole/MemberPrivatizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/MethodFinalizer.java b/src/proguard/optimize/peephole/MethodFinalizer.java
index af1811b..140a114 100644
--- a/src/proguard/optimize/peephole/MethodFinalizer.java
+++ b/src/proguard/optimize/peephole/MethodFinalizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/MethodInliner.java b/src/proguard/optimize/peephole/MethodInliner.java
index 55f9ccb..8857202 100644
--- a/src/proguard/optimize/peephole/MethodInliner.java
+++ b/src/proguard/optimize/peephole/MethodInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -29,10 +29,10 @@
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.MemberVisitor;
+import proguard.classfile.visitor.*;
import proguard.optimize.info.*;
-import java.util.Stack;
+import java.util.*;
/**
* This AttributeVisitor inlines short methods or methods that are only invoked
@@ -48,7 +48,7 @@
MemberVisitor
{
private static final int MAXIMUM_INLINED_CODE_LENGTH = Integer.parseInt(System.getProperty("maximum.inlined.code.length", "8"));
- private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "8000"));
+ private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "7000"));
private static final int MAXIMUM_RESULTING_CODE_LENGTH_JME = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "2000"));
private static final int MAXIMUM_CODE_EXPANSION = 2;
private static final int MAXIMUM_EXTRA_CODE_LENGTH = 128;
@@ -138,6 +138,42 @@
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
+ // TODO: Remove this when the method inliner has stabilized.
+ // Catch any unexpected exceptions from the actual visiting method.
+ try
+ {
+ // Process the code.
+ visitCodeAttribute0(clazz, method, codeAttribute);
+ }
+ catch (RuntimeException ex)
+ {
+ System.err.println("Unexpected error while inlining method:");
+ System.err.println(" Target class = ["+targetClass.getName()+"]");
+ System.err.println(" Target method = ["+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]");
+ if (inlining)
+ {
+ System.err.println(" Inlined class = ["+clazz.getName()+"]");
+ System.err.println(" Inlined method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
+ }
+ System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
+ System.err.println("Not inlining this method");
+
+ if (DEBUG)
+ {
+ targetMethod.accept(targetClass, new ClassPrinter());
+ if (inlining)
+ {
+ method.accept(clazz, new ClassPrinter());
+ }
+
+ throw ex;
+ }
+ }
+ }
+
+
+ public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
if (!inlining)
{
// codeAttributeComposer.DEBUG = DEBUG =
@@ -305,12 +341,12 @@
// Copy the instructions.
codeAttribute.instructionsAccept(clazz, method, this);
- // Copy the exceptions.
- codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder);
-
// Append a label just after the code.
codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
+ // Copy the exceptions.
+ codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder);
+
codeAttributeComposer.endCodeFragment();
}
@@ -457,42 +493,42 @@
if (// Only inline the method if it is private, static, or final.
(accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC |
- ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
+ ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
// Only inline the method if it is not synchronized, etc.
(accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED |
ClassConstants.INTERNAL_ACC_NATIVE |
ClassConstants.INTERNAL_ACC_INTERFACE |
- ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
+ ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
// Don't inline an <init> method, except in an <init> method in the
// same class.
// (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ||
// (programClass.equals(targetClass) &&
// targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) &&
- !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
+ !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
// Don't inline a method into itself.
(!programMethod.equals(targetMethod) ||
- !programClass.equals(targetClass)) &&
+ !programClass.equals(targetClass)) &&
// Only inline the method if it isn't recursing.
- !inliningMethods.contains(programMethod) &&
+ !inliningMethods.contains(programMethod) &&
// Only inline the method if its target class has at least the
// same version number as the source class, in order to avoid
// introducing incompatible constructs.
- targetClass.u4version >= programClass.u4version &&
+ targetClass.u4version >= programClass.u4version &&
// Only inline the method if it doesn't invoke a super method, or if
// it is in the same class.
(!SuperInvocationMarker.invokesSuperMethods(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't branch backward while there
// are uninitialized objects.
(!BackwardBranchMarker.branchesBackward(programMethod) ||
- uninitializedObjectCount == 0) &&
+ uninitializedObjectCount == 0) &&
// Only inline if the code access of the inlined method allows it.
(allowAccessModification ||
@@ -501,47 +537,24 @@
(!AccessMethodMarker.accessesPackageCode(programMethod) ||
ClassUtil.internalPackageName(programClass.getName()).equals(
- ClassUtil.internalPackageName(targetClass.getName()))))) &&
+ ClassUtil.internalPackageName(targetClass.getName()))))) &&
// (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
// targetClass.extends_(programClass) ||
// targetClass.implements_(programClass)) ||
(!AccessMethodMarker.accessesProtectedCode(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't catch exceptions, or if it
// is invoked with an empty stack.
(!CatchExceptionMarker.catchesExceptions(programMethod) ||
- emptyInvokingStack) &&
+ emptyInvokingStack) &&
- // Only inline the method if it comes from the same class or from
- // a class with a static initializer.
+ // Only inline the method if it comes from the a class with at most
+ // a subset of the initialized superclasses.
(programClass.equals(targetClass) ||
- programClass.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
- ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) == null))
- {
-// System.out.print("MethodInliner: inlining ");
-// programMethod.accept(programClass, new SimpleClassPrinter(true));
-// System.out.print(" in ");
-// targetMethod.accept(targetClass, new SimpleClassPrinter(true));
-//
-// System.out.println(" Private: "+
-// (!AccessMethodMarker.accessesPrivateCode(programMethod) ||
-// programClass.equals(targetClass)));
-//
-// System.out.println(" Package: "+
-// (!AccessMethodMarker.accessesPackageCode(programMethod) ||
-// ClassUtil.internalPackageName(programClass.getName()).equals(
-// ClassUtil.internalPackageName(targetClass.getName()))));
-//
-// System.out.println(" Protected: "+
-// ((!AccessMethodMarker.accessesProtectedCode(programMethod) ||
-// targetClass.extends_(programClass) ||
-// targetClass.implements_(programClass)) ||
-// ClassUtil.internalPackageName(programClass.getName()).equals(
-// ClassUtil.internalPackageName(targetClass.getName()))));
-
- boolean oldInlining = inlining;
+ initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass))))
+ { boolean oldInlining = inlining;
inlining = true;
inliningMethods.push(programMethod);
@@ -564,4 +577,21 @@
uninitializedObjectCount--;
}
}
+
+
+ /**
+ * Returns the set of superclasses and interfaces that are initialized.
+ */
+ private Set initializedSuperClasses(Clazz clazz)
+ {
+ Set set = new HashSet();
+
+ // Visit all superclasses and interfaces, collecting the ones that have
+ // static initializers.
+ clazz.hierarchyAccept(true, true, true, false,
+ new StaticInitializerContainingClassFilter(
+ new ClassCollector(set)));
+
+ return set;
+ }
}
diff --git a/src/proguard/optimize/peephole/NopRemover.java b/src/proguard/optimize/peephole/NopRemover.java
index 69adb30..4c99f3a 100644
--- a/src/proguard/optimize/peephole/NopRemover.java
+++ b/src/proguard/optimize/peephole/NopRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/PeepholeOptimizer.java b/src/proguard/optimize/peephole/PeepholeOptimizer.java
index 98f8e8d..d865638 100644
--- a/src/proguard/optimize/peephole/PeepholeOptimizer.java
+++ b/src/proguard/optimize/peephole/PeepholeOptimizer.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/ReachableCodeMarker.java b/src/proguard/optimize/peephole/ReachableCodeMarker.java
index d9dbf2d..cac1965 100644
--- a/src/proguard/optimize/peephole/ReachableCodeMarker.java
+++ b/src/proguard/optimize/peephole/ReachableCodeMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -27,6 +27,8 @@
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
+import java.util.Arrays;
+
/**
* This AttributeVisitor finds all instruction offsets, branch targets, and
* exception targets in the CodeAttribute objects that it visits.
@@ -91,10 +93,7 @@
else
{
// Reset the array.
- for (int index = 0; index < codeLength; index++)
- {
- isReachable[index] = false;
- }
+ Arrays.fill(isReachable, 0, codeLength, false);
}
// Mark the code, starting at the entry point.
diff --git a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
index 6707a12..254f748 100644
--- a/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
+++ b/src/proguard/optimize/peephole/RetargetedInnerClassAttributeRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -28,6 +28,8 @@
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.ClassVisitor;
+import java.util.Arrays;
+
/**
* This ClassVisitor removes InnerClasses and EnclosingMethod attributes in
* classes that are retargeted or that refer to classes that are retargeted.
@@ -70,10 +72,7 @@
}
// Clean up any remaining array elements.
- for (int index = newAtributesCount; index < attributesCount; index++)
- {
- attributes[index] = null;
- }
+ Arrays.fill(attributes, newAtributesCount, attributesCount, null);
// Update the number of attribuets.
programClass.u2attributesCount = newAtributesCount;
@@ -90,8 +89,39 @@
// Check whether the class itself is retargeted.
checkTarget(clazz);
- // Check whether the referenced classes are retargeted.
- innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ if (!retargeted)
+ {
+ // Check whether the referenced classes are retargeted.
+ innerClassesAttribute.innerClassEntriesAccept(clazz, this);
+ int classesCount = innerClassesAttribute.u2classesCount;
+ InnerClassesInfo[] classes = innerClassesAttribute.classes;
+
+ int newClassesCount = 0;
+
+ // Copy over all non-retargeted attributes.
+ for (int index = 0; index < classesCount; index++)
+ {
+ InnerClassesInfo classInfo = classes[index];
+
+ // Check if the outer class or inner class is a retargeted class.
+ retargeted = false;
+ classInfo.outerClassConstantAccept(clazz, this);
+ classInfo.innerClassConstantAccept(clazz, this);
+ if (!retargeted)
+ {
+ classes[newClassesCount++] = classInfo;
+ }
+ }
+
+ // Clean up any remaining array elements.
+ Arrays.fill(classes, newClassesCount, classesCount, null);
+
+ // Update the number of classes.
+ innerClassesAttribute.u2classesCount = newClassesCount;
+
+ // Remove the attribute altogether if it's empty.
+ retargeted = newClassesCount == 0;
+ }
}
diff --git a/src/proguard/optimize/peephole/TargetClassChanger.java b/src/proguard/optimize/peephole/TargetClassChanger.java
index 22fd83d..5fa4fac 100644
--- a/src/proguard/optimize/peephole/TargetClassChanger.java
+++ b/src/proguard/optimize/peephole/TargetClassChanger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -51,13 +51,13 @@
AnnotationVisitor,
ElementValueVisitor
{
+ private static final boolean DEBUG = false;
+
+
// Implementations for ClassVisitor.
public void visitProgramClass(ProgramClass programClass)
{
- Clazz superClass = null;
- Clazz[] interfaceClasses = null;
-
// Change the references of the constant pool.
programClass.constantPoolEntriesAccept(this);
@@ -80,34 +80,39 @@
programClass.getName(),
programClass);
+ // This class will loose all its interfaces.
+ programClass.u2interfacesCount = 0;
+
// This class will loose all its subclasses.
programClass.subClasses = null;
}
-
- // Remove interface classes that are pointing to this class.
- int newInterfacesCount = 0;
- for (int index = 0; index < programClass.u2interfacesCount; index++)
+ else
{
- Clazz interfaceClass = programClass.getInterface(index);
- if (!programClass.equals(interfaceClass))
+ // Remove interface classes that are pointing to this class.
+ int newInterfacesCount = 0;
+ for (int index = 0; index < programClass.u2interfacesCount; index++)
{
- programClass.u2interfaces[newInterfacesCount++] =
- programClass.u2interfaces[index];
+ Clazz interfaceClass = programClass.getInterface(index);
+ if (!programClass.equals(interfaceClass))
+ {
+ programClass.u2interfaces[newInterfacesCount++] =
+ programClass.u2interfaces[index];
+ }
}
+ programClass.u2interfacesCount = newInterfacesCount;
+
+ // Update the subclasses of the superclass and interfaces of the
+ // target class.
+ ConstantVisitor subclassAdder =
+ new ReferencedClassVisitor(
+ new SubclassFilter(programClass,
+ new SubclassAdder(programClass)));
+
+ programClass.superClassConstantAccept(subclassAdder);
+ programClass.interfaceConstantsAccept(subclassAdder);
+
+ // TODO: Maybe restore private method references.
}
- programClass.u2interfacesCount = newInterfacesCount;
-
- // Update the subclasses of the superclass and interfaces of the
- // target class.
- ConstantVisitor subclassAdder =
- new ReferencedClassVisitor(
- new SubclassFilter(programClass,
- new SubclassAdder(programClass)));
-
- programClass.superClassConstantAccept(subclassAdder);
- programClass.interfaceConstantsAccept(subclassAdder);
-
- // TODO: Maybe restore private method references.
}
@@ -188,6 +193,12 @@
Clazz newReferencedClass = updateReferencedClass(referencedClass);
if (referencedClass != newReferencedClass)
{
+ if (DEBUG)
+ {
+ System.out.println("TargetClassChanger:");
+ System.out.println(" ["+clazz.getName()+"] changing reference from ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
+ }
+
// Change the referenced class.
refConstant.referencedClass = newReferencedClass;
@@ -197,6 +208,11 @@
refConstant.getName(clazz),
refConstant.getType(clazz),
newReferencedClass);
+
+ if (DEBUG)
+ {
+ System.out.println(" ["+clazz.getName()+"] to ["+refConstant.referencedClass+"."+refConstant.referencedMember.getName(refConstant.referencedClass)+refConstant.referencedMember.getDescriptor(refConstant.referencedClass)+"]");
+ }
}
}
diff --git a/src/proguard/optimize/peephole/UnreachableCodeRemover.java b/src/proguard/optimize/peephole/UnreachableCodeRemover.java
index e8a99ab..fcb8914 100644
--- a/src/proguard/optimize/peephole/UnreachableCodeRemover.java
+++ b/src/proguard/optimize/peephole/UnreachableCodeRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java b/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
index 048f5e3..f3ecf0b 100644
--- a/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
+++ b/src/proguard/optimize/peephole/UnreachableExceptionRemover.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/VariableShrinker.java b/src/proguard/optimize/peephole/VariableShrinker.java
index 45b694f..55f42ca 100644
--- a/src/proguard/optimize/peephole/VariableShrinker.java
+++ b/src/proguard/optimize/peephole/VariableShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/optimize/peephole/VerticalClassMerger.java b/src/proguard/optimize/peephole/VerticalClassMerger.java
index 29ed6ff..721f2a5 100644
--- a/src/proguard/optimize/peephole/VerticalClassMerger.java
+++ b/src/proguard/optimize/peephole/VerticalClassMerger.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/preverify/CodePreverifier.java b/src/proguard/preverify/CodePreverifier.java
index fa60b9a..670f26e 100644
--- a/src/proguard/preverify/CodePreverifier.java
+++ b/src/proguard/preverify/CodePreverifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/preverify/CodeSubroutineInliner.java b/src/proguard/preverify/CodeSubroutineInliner.java
index 603eb75..9012b05 100644
--- a/src/proguard/preverify/CodeSubroutineInliner.java
+++ b/src/proguard/preverify/CodeSubroutineInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -67,6 +67,7 @@
// DEBUG =
// clazz.getName().equals("abc/Def") &&
// method.getName(clazz).equals("abc");
+// CodeAttributeComposer.DEBUG = DEBUG;
// TODO: Remove this when the subroutine inliner has stabilized.
// Catch any unexpected exceptions from the actual visiting method.
diff --git a/src/proguard/preverify/Preverifier.java b/src/proguard/preverify/Preverifier.java
index e071c5c..3cbd930 100644
--- a/src/proguard/preverify/Preverifier.java
+++ b/src/proguard/preverify/Preverifier.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -59,13 +59,12 @@
new AllAttributeVisitor(
new CodePreverifier(configuration.microEdition)));
- // In Java Standard Edition, only class files from Java 6 or higher
- // should be preverified.
+ // Classes from Java 6 may optionally be preverified.
+ // Classes from Java 7 or higher must be preverified.
if (!configuration.microEdition)
{
preverifier =
new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_6,
- Integer.MAX_VALUE,
preverifier);
}
diff --git a/src/proguard/preverify/SubroutineInliner.java b/src/proguard/preverify/SubroutineInliner.java
index e28512f..38a824e 100644
--- a/src/proguard/preverify/SubroutineInliner.java
+++ b/src/proguard/preverify/SubroutineInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -65,7 +65,6 @@
{
inliner =
new ClassVersionFilter(ClassConstants.INTERNAL_CLASS_VERSION_1_6,
- Integer.MAX_VALUE,
inliner);
}
diff --git a/src/proguard/retrace/ReTrace.java b/src/proguard/retrace/ReTrace.java
index 97ab27b..183d9a0 100644
--- a/src/proguard/retrace/ReTrace.java
+++ b/src/proguard/retrace/ReTrace.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -47,7 +47,7 @@
private static final String REGEX_CLASS_SLASH = "\\b(?:[A-Za-z0-9_$]+/)*[A-Za-z0-9_$]+\\b";
private static final String REGEX_LINE_NUMBER = "\\b[0-9]+\\b";
private static final String REGEX_TYPE = REGEX_CLASS + "(?:\\[\\])*";
- private static final String REGEX_MEMBER = "\\b[A-Za-z0-9_$]+\\b";
+ private static final String REGEX_MEMBER = "<?\\b[A-Za-z0-9_$]+\\b>?";
private static final String REGEX_ARGUMENTS = "(?:" + REGEX_TYPE + "(?:\\s*,\\s*" + REGEX_TYPE + ")*)?";
// The class settings.
diff --git a/src/proguard/shrink/AnnotationUsageMarker.java b/src/proguard/shrink/AnnotationUsageMarker.java
index 9aaae34..0b2fd91 100644
--- a/src/proguard/shrink/AnnotationUsageMarker.java
+++ b/src/proguard/shrink/AnnotationUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -52,7 +52,6 @@
// Fields acting as a return parameters for several methods.
private boolean attributeUsed;
private boolean annotationUsed;
- private boolean elementValueUsed;
private boolean classUsed;
private boolean methodUsed;
@@ -151,9 +150,6 @@
markConstant(clazz, constantElementValue.u2elementNameIndex);
markConstant(clazz, constantElementValue.u2constantValueIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
@@ -164,7 +160,7 @@
{
// Check the referenced classes.
classUsed = true;
- enumConstantElementValue.referencedClassesAccept(usageMarker);
+ enumConstantElementValue.referencedClassesAccept(this);
if (classUsed)
{
@@ -174,9 +170,6 @@
markConstant(clazz, enumConstantElementValue.u2elementNameIndex);
markConstant(clazz, enumConstantElementValue.u2typeNameIndex);
markConstant(clazz, enumConstantElementValue.u2constantNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
}
@@ -188,7 +181,7 @@
{
// Check the referenced classes.
classUsed = true;
- classElementValue.referencedClassesAccept(usageMarker);
+ classElementValue.referencedClassesAccept(this);
if (classUsed)
{
@@ -197,9 +190,6 @@
markConstant(clazz, classElementValue.u2elementNameIndex);
markConstant(clazz, classElementValue.u2classInfoIndex);
-
- // The return value.
- elementValueUsed = true;
}
}
}
@@ -221,9 +211,6 @@
usageMarker.markAsUsed(annotationElementValue);
markConstant(clazz, annotationElementValue.u2elementNameIndex);
-
- // The return value.
- elementValueUsed = true;
}
annotationUsed = oldAnnotationUsed;
@@ -235,26 +222,13 @@
{
if (isReferencedMethodUsed(arrayElementValue))
{
- boolean oldelementValueUsed = elementValueUsed;
-
// Check and mark the contained element values.
- elementValueUsed = false;
arrayElementValue.elementValuesAccept(clazz, annotation, this);
- if (elementValueUsed)
- {
- // Mark the element value as being used.
- usageMarker.markAsUsed(arrayElementValue);
+ // Mark the element value as being used.
+ usageMarker.markAsUsed(arrayElementValue);
- markConstant(clazz, arrayElementValue.u2elementNameIndex);
-
- // The return value.
- //elementValueUsed = true;
- }
- else
- {
- elementValueUsed = oldelementValueUsed;
- }
+ markConstant(clazz, arrayElementValue.u2elementNameIndex);
}
}
diff --git a/src/proguard/shrink/ClassShrinker.java b/src/proguard/shrink/ClassShrinker.java
index 0b5c5b7..f40e3ce 100644
--- a/src/proguard/shrink/ClassShrinker.java
+++ b/src/proguard/shrink/ClassShrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -24,15 +24,17 @@
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
-import proguard.classfile.attribute.visitor.AttributeVisitor;
+import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.editor.*;
import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
+import java.util.Arrays;
+
/**
- * This ClassVisitor removes constant pool entries and class members that
- * are not marked as being used.
+ * This ClassVisitor removes constant pool entries, class members, and other
+ * class elements that are not marked as being used.
*
* @see UsageMarker
*
@@ -48,8 +50,7 @@
{
private final UsageMarker usageMarker;
- private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
-
+ private int[] constantIndexMap = new int[ClassConstants.TYPICAL_CONSTANT_POOL_SIZE];
private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
@@ -76,7 +77,7 @@
programClass.u2interfacesCount);
// Shrinking the constant pool also sets up an index map.
- programClass.u2constantPoolCount =
+ int newConstantPoolCount =
shrinkConstantPool(programClass.constantPool,
programClass.u2constantPoolCount);
@@ -98,9 +99,15 @@
programClass.methodsAccept(this);
programClass.attributesAccept(this);
- // Remap all constant pool references.
- constantPoolRemapper.setConstantIndexMap(constantIndexMap);
- constantPoolRemapper.visitProgramClass(programClass);
+ // Remap the references to the constant pool if it has shrunk.
+ if (newConstantPoolCount < programClass.u2constantPoolCount)
+ {
+ programClass.u2constantPoolCount = newConstantPoolCount;
+
+ // Remap all constant pool references.
+ constantPoolRemapper.setConstantIndexMap(constantIndexMap);
+ constantPoolRemapper.visitProgramClass(programClass);
+ }
// Remove the unused interfaces from the class signature.
programClass.attributesAccept(new SignatureShrinker());
@@ -140,6 +147,15 @@
public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Shrink the array of BootstrapMethodInfo objects.
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount =
+ shrinkArray(bootstrapMethodsAttribute.bootstrapMethods,
+ bootstrapMethodsAttribute.u2bootstrapMethodsCount);
+ }
+
+
public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
{
// Shrink the array of InnerClassesInfo objects.
@@ -349,10 +365,7 @@
}
// Clear the remaining constant pool elements.
- for (int index = counter; index < length; index++)
- {
- constantPool[index] = null;
- }
+ Arrays.fill(constantPool, counter, length, null);
return counter;
}
@@ -377,10 +390,7 @@
}
// Clear the remaining array elements.
- for (int index = counter; index < length; index++)
- {
- array[index] = 0;
- }
+ Arrays.fill(array, counter, length, 0);
return counter;
}
@@ -437,10 +447,10 @@
}
}
- // Clear the remaining array elements.
- for (int index = counter; index < length; index++)
+ // Clear any remaining array elements.
+ if (counter < length)
{
- array[index] = null;
+ Arrays.fill(array, counter, length, null);
}
return counter;
diff --git a/src/proguard/shrink/InnerUsageMarker.java b/src/proguard/shrink/InnerUsageMarker.java
index b8ca801..c95bc64 100644
--- a/src/proguard/shrink/InnerUsageMarker.java
+++ b/src/proguard/shrink/InnerUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/InterfaceUsageMarker.java b/src/proguard/shrink/InterfaceUsageMarker.java
index 7599898..065745d 100644
--- a/src/proguard/shrink/InterfaceUsageMarker.java
+++ b/src/proguard/shrink/InterfaceUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/ShortestUsageMark.java b/src/proguard/shrink/ShortestUsageMark.java
index 757c713..a2ff762 100644
--- a/src/proguard/shrink/ShortestUsageMark.java
+++ b/src/proguard/shrink/ShortestUsageMark.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/ShortestUsageMarker.java b/src/proguard/shrink/ShortestUsageMarker.java
index da8fad3..3f2cf94 100644
--- a/src/proguard/shrink/ShortestUsageMarker.java
+++ b/src/proguard/shrink/ShortestUsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/ShortestUsagePrinter.java b/src/proguard/shrink/ShortestUsagePrinter.java
index db42fe1..4f12e87 100644
--- a/src/proguard/shrink/ShortestUsagePrinter.java
+++ b/src/proguard/shrink/ShortestUsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/Shrinker.java b/src/proguard/shrink/Shrinker.java
index edbc27f..66ca161 100644
--- a/src/proguard/shrink/Shrinker.java
+++ b/src/proguard/shrink/Shrinker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -21,7 +21,7 @@
package proguard.shrink;
import proguard.*;
-import proguard.classfile.ClassPool;
+import proguard.classfile.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.visitor.*;
@@ -67,9 +67,20 @@
new UsageMarker() :
new ShortestUsageMarker();
+ // Automatically mark the parameterless constructors of seed classes,
+ // mainly for convenience and for backward compatibility.
+ ClassVisitor classUsageMarker =
+ new MultiClassVisitor(new ClassVisitor[]
+ {
+ usageMarker,
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ usageMarker)
+ });
+
ClassPoolVisitor classPoolvisitor =
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep,
- usageMarker,
+ classUsageMarker,
usageMarker,
true,
false,
diff --git a/src/proguard/shrink/UsageMarker.java b/src/proguard/shrink/UsageMarker.java
index e913046..a1b2f53 100644
--- a/src/proguard/shrink/UsageMarker.java
+++ b/src/proguard/shrink/UsageMarker.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -27,10 +27,10 @@
import proguard.classfile.attribute.preverification.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
+import proguard.classfile.constant.visitor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
+import proguard.classfile.util.*;
import proguard.classfile.visitor.*;
@@ -65,18 +65,15 @@
private static final Object USED = new Object();
- private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
- private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
-// private ClassVisitor dynamicClassMarker =
-// new MultiClassVisitor(
-// new ClassVisitor[]
-// {
-// this,
-// new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
-// ClassConstants.INTERNAL_METHOD_TYPE_INIT,
-// this)
-// });
-
+ private final MyInterfaceUsageMarker interfaceUsageMarker = new MyInterfaceUsageMarker();
+ private final MyPossiblyUsedMemberUsageMarker possiblyUsedMemberUsageMarker = new MyPossiblyUsedMemberUsageMarker();
+ private final MemberVisitor nonEmptyMethodUsageMarker = new AllAttributeVisitor(
+ new MyNonEmptyMethodUsageMarker());
+ private final ConstantVisitor parameterlessConstructorMarker = new ConstantTagFilter(new int[] { ClassConstants.CONSTANT_String, ClassConstants.CONSTANT_Class },
+ new ReferencedClassVisitor(
+ new NamedMethodVisitor(ClassConstants.INTERNAL_METHOD_NAME_INIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_INIT,
+ this)));
// Implementations for ClassVisitor.
@@ -107,15 +104,10 @@
programClass.hierarchyAccept(false, false, true, false,
interfaceUsageMarker);
- // Explicitly mark the <clinit> method.
+ // Explicitly mark the <clinit> method, if it's not empty.
programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
ClassConstants.INTERNAL_METHOD_TYPE_CLINIT,
- this);
-
- // Explicitly mark the parameterless <init> method.
- programClass.methodAccept(ClassConstants.INTERNAL_METHOD_NAME_INIT,
- ClassConstants.INTERNAL_METHOD_TYPE_INIT,
- this);
+ nonEmptyMethodUsageMarker);
// Process all class members that have already been marked as possibly used.
programClass.fieldsAccept(possiblyUsedMemberUsageMarker);
@@ -187,6 +179,10 @@
}
+ /**
+ * This MemberVisitor marks ProgramField and ProgramMethod objects that
+ * have already been marked as possibly used.
+ */
private class MyPossiblyUsedMemberUsageMarker
extends SimplifiedVisitor
implements MemberVisitor
@@ -230,6 +226,28 @@
}
+ /**
+ * This AttributeVisitor marks ProgramMethod objects of non-empty methods.
+ */
+ private class MyNonEmptyMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor
+ {
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
+ {
+ if (codeAttribute.u4codeLength > 1)
+ {
+ method.accept(clazz, UsageMarker.this);
+ }
+ }
+ }
+
+
// Implementations for MemberVisitor.
public void visitProgramField(ProgramClass programClass, ProgramField programField)
@@ -337,7 +355,8 @@
{
if ((method.getAccessFlags() &
(ClassConstants.INTERNAL_ACC_PRIVATE |
- ClassConstants.INTERNAL_ACC_STATIC)) == 0)
+ ClassConstants.INTERNAL_ACC_STATIC)) == 0 &&
+ !ClassUtil.isInitializer(method.getName(clazz)))
{
clazz.accept(new ConcreteClassDownTraveler(
new ClassHierarchyTraveler(true, true, false, true,
@@ -395,11 +414,7 @@
markConstant(clazz, stringConstant.u2stringIndex);
- // Mark the referenced class and its parameterless constructor,
- // if the string is being used in a Class.forName construct.
- //stringConstant.referencedClassAccept(dynamicClassMarker);
-
- // Mark the referenced class or class member, if any.
+ // Mark the referenced class and class member, if any.
stringConstant.referencedClassAccept(this);
stringConstant.referencedMemberAccept(this);
}
@@ -415,6 +430,31 @@
}
+ public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
+ {
+ if (shouldBeMarkedAsUsed(invokeDynamicConstant))
+ {
+ markAsUsed(invokeDynamicConstant);
+
+ markConstant(clazz, invokeDynamicConstant.u2nameAndTypeIndex);
+
+ // Mark the bootstrap methods attribute.
+ clazz.attributesAccept(new MyBootStrapMethodUsageMarker(invokeDynamicConstant.u2bootstrapMethodAttributeIndex));
+ }
+ }
+
+
+ public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodHandleConstant))
+ {
+ markAsUsed(methodHandleConstant);
+
+ markConstant(clazz, methodHandleConstant.u2referenceIndex);
+ }
+ }
+
+
public void visitAnyRefConstant(Clazz clazz, RefConstant refConstant)
{
if (shouldBeMarkedAsUsed(refConstant))
@@ -450,6 +490,17 @@
}
+ public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
+ {
+ if (shouldBeMarkedAsUsed(methodTypeConstant))
+ {
+ markAsUsed(methodTypeConstant);
+
+ markConstant(clazz, methodTypeConstant.u2descriptorIndex);
+ }
+ }
+
+
public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
{
if (shouldBeMarkedAsUsed(nameAndTypeConstant))
@@ -462,6 +513,58 @@
}
+ /**
+ * This AttributeVisitor marks the bootstrap methods attributes, their
+ * method entries, their method handles, and their arguments.
+ */
+ private class MyBootStrapMethodUsageMarker
+ extends SimplifiedVisitor
+ implements AttributeVisitor,
+ BootstrapMethodInfoVisitor
+ {
+ private int bootstrapMethodIndex;
+
+
+ private MyBootStrapMethodUsageMarker(int bootstrapMethodIndex)
+ {
+ this.bootstrapMethodIndex = bootstrapMethodIndex;
+ }
+
+
+ // Implementations for AttributeVisitor.
+
+ public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
+
+
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ if (shouldBeMarkedAsUsed(bootstrapMethodsAttribute))
+ {
+ markAsUsed(bootstrapMethodsAttribute);
+
+ markConstant(clazz, bootstrapMethodsAttribute.u2attributeNameIndex);
+
+ bootstrapMethodsAttribute.bootstrapMethodEntryAccept(clazz,
+ bootstrapMethodIndex,
+ this);
+ }
+ }
+
+
+ // Implementations for BootstrapMethodInfoVisitor.
+
+ public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
+ {
+ markAsUsed(bootstrapMethodInfo);
+
+ markConstant(clazz, bootstrapMethodInfo.u2methodHandleIndex);
+
+ // Mark the constant pool entries referenced by the arguments.
+ bootstrapMethodInfo.methodArgumentsAccept(clazz, UsageMarker.this);
+ }
+ }
+
+
// Implementations for AttributeVisitor.
// Note that attributes are typically only referenced once, so we don't
// test if they have been marked already.
@@ -475,6 +578,13 @@
}
+ public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
+ {
+ // Don't mark the attribute and its name here. We may mark it in
+ // MyBootStrapMethodsAttributeUsageMarker.
+ }
+
+
public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
{
markAsUsed(sourceFileAttribute);
@@ -837,6 +947,12 @@
public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
{
markConstant(clazz, constantInstruction.constantIndex);
+
+ // Also mark the parameterless constructor of the class, in case the
+ // string constant or class constant is being used in a Class.forName
+ // or a .class construct.
+ clazz.constantPoolEntryAccept(constantInstruction.constantIndex,
+ parameterlessConstructorMarker);
}
@@ -915,6 +1031,6 @@
*/
private void markConstant(Clazz clazz, int index)
{
- clazz.constantPoolEntryAccept(index, this);
+ clazz.constantPoolEntryAccept(index, this);
}
}
diff --git a/src/proguard/shrink/UsagePrinter.java b/src/proguard/shrink/UsagePrinter.java
index 294b9e1..53f7bc2 100644
--- a/src/proguard/shrink/UsagePrinter.java
+++ b/src/proguard/shrink/UsagePrinter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/UsedClassFilter.java b/src/proguard/shrink/UsedClassFilter.java
index ec180bd..b5a77fb 100644
--- a/src/proguard/shrink/UsedClassFilter.java
+++ b/src/proguard/shrink/UsedClassFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/shrink/UsedMemberFilter.java b/src/proguard/shrink/UsedMemberFilter.java
index 755cfd1..0034ce7 100644
--- a/src/proguard/shrink/UsedMemberFilter.java
+++ b/src/proguard/shrink/UsedMemberFilter.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -39,7 +39,7 @@
/**
- * Creates a new UsedClassFilter.
+ * Creates a new UsedMemberFilter.
* @param usageMarker the usage marker that is used to mark the classes
* and class members.
* @param memberVisitor the member visitor to which the visiting will be
diff --git a/src/proguard/util/AndMatcher.java b/src/proguard/util/AndMatcher.java
index 94a37e5..ae70e5d 100644
--- a/src/proguard/util/AndMatcher.java
+++ b/src/proguard/util/AndMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ClassNameParser.java b/src/proguard/util/ClassNameParser.java
index ee972f0..fd12475 100644
--- a/src/proguard/util/ClassNameParser.java
+++ b/src/proguard/util/ClassNameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ConstantMatcher.java b/src/proguard/util/ConstantMatcher.java
index 1764caa..90e5a0c 100644
--- a/src/proguard/util/ConstantMatcher.java
+++ b/src/proguard/util/ConstantMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/EmptyStringMatcher.java b/src/proguard/util/EmptyStringMatcher.java
index 543f446..5e56147 100644
--- a/src/proguard/util/EmptyStringMatcher.java
+++ b/src/proguard/util/EmptyStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ExtensionMatcher.java b/src/proguard/util/ExtensionMatcher.java
index 5a9f658..9e3fd65 100644
--- a/src/proguard/util/ExtensionMatcher.java
+++ b/src/proguard/util/ExtensionMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/FileNameParser.java b/src/proguard/util/FileNameParser.java
index 913f22d..d5cbdf3 100644
--- a/src/proguard/util/FileNameParser.java
+++ b/src/proguard/util/FileNameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/FixedStringMatcher.java b/src/proguard/util/FixedStringMatcher.java
index c1eb3f4..570b70e 100644
--- a/src/proguard/util/FixedStringMatcher.java
+++ b/src/proguard/util/FixedStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ListMatcher.java b/src/proguard/util/ListMatcher.java
index b2559c8..30f1a9b 100644
--- a/src/proguard/util/ListMatcher.java
+++ b/src/proguard/util/ListMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ListParser.java b/src/proguard/util/ListParser.java
index cec803b..b8f075d 100644
--- a/src/proguard/util/ListParser.java
+++ b/src/proguard/util/ListParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/ListUtil.java b/src/proguard/util/ListUtil.java
index 570dbe8..71556f3 100644
--- a/src/proguard/util/ListUtil.java
+++ b/src/proguard/util/ListUtil.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
@@ -34,7 +34,7 @@
/**
* Creates a comma-separated String from the given List of String objects.
*/
- public static String commaSeparatedString(List list)
+ public static String commaSeparatedString(List list, boolean quoteStrings)
{
if (list == null)
{
@@ -50,7 +50,14 @@
buffer.append(',');
}
- buffer.append(quotedString((String)list.get(index)));
+ String string = (String)list.get(index);
+
+ if (quoteStrings)
+ {
+ string = quotedString(string);
+ }
+
+ buffer.append(string);
}
return buffer.toString();
@@ -165,7 +172,7 @@
System.out.println("["+list.get(index)+"]");
}
- String string = commaSeparatedString(list);
+ String string = commaSeparatedString(list, true);
System.out.println("Resulting string: ["+string+"]");
}
diff --git a/src/proguard/util/NameParser.java b/src/proguard/util/NameParser.java
index e311fbf..6bbf4f6 100644
--- a/src/proguard/util/NameParser.java
+++ b/src/proguard/util/NameParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/NotMatcher.java b/src/proguard/util/NotMatcher.java
index f2a9a51..53b87ae 100644
--- a/src/proguard/util/NotMatcher.java
+++ b/src/proguard/util/NotMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/OrMatcher.java b/src/proguard/util/OrMatcher.java
index 097c6c6..70b849b 100644
--- a/src/proguard/util/OrMatcher.java
+++ b/src/proguard/util/OrMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/SettableMatcher.java b/src/proguard/util/SettableMatcher.java
index 9557f62..48f01e1 100644
--- a/src/proguard/util/SettableMatcher.java
+++ b/src/proguard/util/SettableMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/StringMatcher.java b/src/proguard/util/StringMatcher.java
index bd66dcc..571ee7f 100644
--- a/src/proguard/util/StringMatcher.java
+++ b/src/proguard/util/StringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/StringParser.java b/src/proguard/util/StringParser.java
index 29f4f16..541d30c 100644
--- a/src/proguard/util/StringParser.java
+++ b/src/proguard/util/StringParser.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/util/VariableStringMatcher.java b/src/proguard/util/VariableStringMatcher.java
index 1e41323..9b296d4 100644
--- a/src/proguard/util/VariableStringMatcher.java
+++ b/src/proguard/util/VariableStringMatcher.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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
diff --git a/src/proguard/wtk/ProGuardObfuscator.java b/src/proguard/wtk/ProGuardObfuscator.java
index 4618437..da957ed 100644
--- a/src/proguard/wtk/ProGuardObfuscator.java
+++ b/src/proguard/wtk/ProGuardObfuscator.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2011 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