Compare commits

...

No commits in common. 'master' and 'generics' have entirely different histories.

  1. 14
      CVSROOT/checkoutlist
  2. 15
      CVSROOT/commitinfo
  3. 11
      CVSROOT/config
  4. 1
      CVSROOT/cvsignore
  5. 24
      CVSROOT/cvswrappers
  6. 21
      CVSROOT/editinfo
  7. 27
      CVSROOT/loginfo
  8. 1
      CVSROOT/modules
  9. 12
      CVSROOT/notify
  10. 13
      CVSROOT/rcsinfo
  11. 206
      CVSROOT/syncmail
  12. 20
      CVSROOT/taginfo
  13. 21
      CVSROOT/verifymsg
  14. 7
      jode/.classpath
  15. 2
      jode/.project
  16. 353
      jode/.settings/org.eclipse.jdt.core.prefs
  17. 4
      jode/.settings/org.eclipse.jdt.ui.prefs
  18. 3
      jode/.settings/org.eclipse.ltk.core.refactoring.prefs
  19. 4
      jode/build.xml
  20. 25
      jode/doc/download.htp
  21. BIN
      jode/doc/jode-2.png
  22. BIN
      jode/doc/jode-logo.png
  23. BIN
      jode/doc/w3c_ab.png
  24. 17
      jode/src/net/sf/jode/bytecode/BasicBlockReader.java
  25. 4
      jode/src/net/sf/jode/bytecode/BasicBlockWriter.java
  26. 1
      jode/src/net/sf/jode/bytecode/BasicBlocks.java
  27. 1
      jode/src/net/sf/jode/bytecode/Block.java
  28. 20
      jode/src/net/sf/jode/bytecode/ClassInfo.java
  29. 11
      jode/src/net/sf/jode/bytecode/FieldInfo.java
  30. 9
      jode/src/net/sf/jode/bytecode/GrowableConstantPool.java
  31. 11
      jode/src/net/sf/jode/bytecode/MethodInfo.java
  32. 450
      jode/src/net/sf/jode/bytecode/TypeSignature.java
  33. 3
      jode/src/net/sf/jode/decompiler/Applet.java
  34. 108
      jode/src/net/sf/jode/decompiler/ClassAnalyzer.java
  35. 16
      jode/src/net/sf/jode/decompiler/ClassDeclarer.java
  36. 11
      jode/src/net/sf/jode/decompiler/FieldAnalyzer.java
  37. 5
      jode/src/net/sf/jode/decompiler/ImportHandler.java
  38. 43
      jode/src/net/sf/jode/decompiler/Main.java
  39. 127
      jode/src/net/sf/jode/decompiler/MethodAnalyzer.java
  40. 14
      jode/src/net/sf/jode/decompiler/Opcodes.java
  41. 2
      jode/src/net/sf/jode/decompiler/Options.java
  42. 8
      jode/src/net/sf/jode/decompiler/OuterValues.java
  43. 175
      jode/src/net/sf/jode/decompiler/TabbedPrintWriter.java
  44. 5
      jode/src/net/sf/jode/decompiler/Window.java
  45. 2
      jode/src/net/sf/jode/expr/ArrayStoreOperator.java
  46. 5
      jode/src/net/sf/jode/expr/ClassFieldOperator.java
  47. 10
      jode/src/net/sf/jode/expr/ConstOperator.java
  48. 13
      jode/src/net/sf/jode/expr/Expression.java
  49. 144
      jode/src/net/sf/jode/expr/FieldOperator.java
  50. 1
      jode/src/net/sf/jode/expr/IIncOperator.java
  51. 8
      jode/src/net/sf/jode/expr/IfThenElseOperator.java
  52. 2
      jode/src/net/sf/jode/expr/InstanceOfOperator.java
  53. 61
      jode/src/net/sf/jode/expr/InvokeOperator.java
  54. 3
      jode/src/net/sf/jode/expr/LValueExpression.java
  55. 3
      jode/src/net/sf/jode/expr/LocalLoadOperator.java
  56. 2
      jode/src/net/sf/jode/expr/LocalStoreOperator.java
  57. 1
      jode/src/net/sf/jode/expr/NoArgOperator.java
  58. 4
      jode/src/net/sf/jode/expr/Operator.java
  59. 3
      jode/src/net/sf/jode/expr/OuterLocalOperator.java
  60. 1
      jode/src/net/sf/jode/expr/PrePostFixOperator.java
  61. 1
      jode/src/net/sf/jode/expr/PutFieldOperator.java
  62. 4
      jode/src/net/sf/jode/expr/StoreInstruction.java
  63. 7
      jode/src/net/sf/jode/expr/StringAddOperator.java
  64. 25
      jode/src/net/sf/jode/expr/ThisOperator.java
  65. 1
      jode/src/net/sf/jode/flow/BreakableBlock.java
  66. 4
      jode/src/net/sf/jode/flow/CatchBlock.java
  67. 1
      jode/src/net/sf/jode/flow/CombineIfGotoExpressions.java
  68. 5
      jode/src/net/sf/jode/flow/ConditionalBlock.java
  69. 6
      jode/src/net/sf/jode/flow/CreateAssignExpression.java
  70. 6
      jode/src/net/sf/jode/flow/CreateClassField.java
  71. 1
      jode/src/net/sf/jode/flow/CreateConstantArray.java
  72. 11
      jode/src/net/sf/jode/flow/CreateIfThenElseOperator.java
  73. 8
      jode/src/net/sf/jode/flow/CreatePrePostIncExpression.java
  74. 157
      jode/src/net/sf/jode/flow/FlowBlock.java
  75. 11
      jode/src/net/sf/jode/flow/IfThenElseBlock.java
  76. 9
      jode/src/net/sf/jode/flow/InstructionBlock.java
  77. 2
      jode/src/net/sf/jode/flow/InstructionContainer.java
  78. 2
      jode/src/net/sf/jode/flow/Jump.java
  79. 161
      jode/src/net/sf/jode/flow/LabelledBlock.java
  80. 15
      jode/src/net/sf/jode/flow/LoopBlock.java
  81. 4
      jode/src/net/sf/jode/flow/ReturnBlock.java
  82. 1
      jode/src/net/sf/jode/flow/SequentialBlock.java
  83. 3
      jode/src/net/sf/jode/flow/SlotSet.java
  84. 7
      jode/src/net/sf/jode/flow/StructuredBlock.java
  85. 2
      jode/src/net/sf/jode/flow/SynchronizedBlock.java
  86. 2
      jode/src/net/sf/jode/flow/ThrowBlock.java
  87. 9
      jode/src/net/sf/jode/flow/TransformConstructors.java
  88. 10
      jode/src/net/sf/jode/flow/TransformExceptionHandlers.java
  89. 3
      jode/src/net/sf/jode/flow/VariableSet.java
  90. 7
      jode/src/net/sf/jode/flow/VariableStack.java
  91. 6
      jode/src/net/sf/jode/jvm/CodeVerifier.java
  92. 1
      jode/src/net/sf/jode/jvm/Interpreter.java
  93. 16
      jode/src/net/sf/jode/jvm/SyntheticAnalyzer.java
  94. 1
      jode/src/net/sf/jode/jvm/Value.java
  95. 1
      jode/src/net/sf/jode/jvm/VerifyException.java
  96. 5
      jode/src/net/sf/jode/obfuscator/ClassBundle.java
  97. 4
      jode/src/net/sf/jode/obfuscator/ClassIdentifier.java
  98. 2
      jode/src/net/sf/jode/obfuscator/FieldIdentifier.java
  99. 1
      jode/src/net/sf/jode/obfuscator/Identifier.java
  100. 1
      jode/src/net/sf/jode/obfuscator/Main.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,14 +0,0 @@
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'
syncmail

@ -1,15 +0,0 @@
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,11 +0,0 @@
# Set this to "no" if pserver shouldn't check system users/passwords
#SystemAuth=no
# Set `PreservePermissions' to `yes' to save file status information
# in the repository.
#PreservePermissions=no
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no

@ -1,24 +0,0 @@
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
*.gif -k 'b'
*.xcf -k 'b'

@ -1,21 +0,0 @@
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

@ -1,27 +0,0 @@
# The "loginfo" file controls where "cvs commit" log information
# is sent. The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT. If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter. The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators. The format
# characters are:
#
# s = file name
# V = old version number (pre-checkin)
# v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
DEFAULT $CVSROOT/CVSROOT/syncmail %{sVv} jode-commit@lists.sourceforge.net

@ -1 +0,0 @@
jode jode

@ -1,12 +0,0 @@
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"

@ -1,13 +0,0 @@
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,206 +0,0 @@
#! /usr/bin/python
# -*- Python -*-
"""Complicated notification for CVS checkins.
This script is used to provide email notifications of changes to the CVS
repository. These email changes will include context diffs of the changes.
Really big diffs will be trimmed.
This script is run from a CVS loginfo file (see $CVSROOT/CVSROOT/loginfo). To
set this up, create a loginfo entry that looks something like this:
mymodule /path/to/this/script %%s some-email-addr@your.domain
In this example, whenever a checkin that matches `mymodule' is made, this
script is invoked, which will generate the diff containing email, and send it
to some-email-addr@your.domain.
Note: This module used to also do repository synchronizations via
rsync-over-ssh, but since the repository has been moved to SourceForge,
this is no longer necessary. The syncing functionality has been ripped
out in the 3.0, which simplifies it considerably. Access the 2.x versions
to refer to this functionality. Because of this, the script is misnamed.
It no longer makes sense to run this script from the command line. Doing so
will only print out this usage information.
Usage:
%(PROGRAM)s [options] <%%S> email-addr [email-addr ...]
Where options is:
--cvsroot=<path>
Use <path> as the environment variable CVSROOT. Otherwise this
variable must exist in the environment.
--help
-h
Print this text.
<%%S>
CVS %%s loginfo expansion. When invoked by CVS, this will be a single
string containing the directory the checkin is being made in, relative
to $CVSROOT, followed by the list of files that are changing. If the
%%s in the loginfo file is %%{sVv}, context diffs for each of the
modified files are included in any email messages that are generated.
email-addrs
At least one email address.
"""
import os
import sys
import string
import time
import getopt
# Notification command
MAILCMD = '/bin/mail -s "%(SUBJECT)s" %(PEOPLE)s 2>&1 > /dev/null'
# Diff trimming stuff
DIFF_HEAD_LINES = 20
DIFF_TAIL_LINES = 20
DIFF_TRUNCATE_IF_LARGER = 1000
PROGRAM = sys.argv[0]
def usage(code, msg=''):
print __doc__ % globals()
if msg:
print msg
sys.exit(code)
def calculate_diff(filespec):
try:
file, oldrev, newrev = string.split(filespec, ',')
except ValueError:
# No diff to report
return '***** Bogus filespec: %s' % filespec
if oldrev == 'NONE':
try:
if os.path.exists(file):
fp = open(file)
else:
update_cmd = 'cvs -fn update -r %s -p %s' % (newrev, file)
fp = os.popen(update_cmd)
lines = fp.readlines()
fp.close()
lines.insert(0, '--- NEW FILE ---\n')
except IOError, e:
lines = ['***** Error reading new file: ',
str(e), '\n***** file: ', file, ' cwd: ', os.getcwd()]
elif newrev == 'NONE':
lines = ['--- %s DELETED ---\n' % file]
else:
# This /has/ to happen in the background, otherwise we'll run into CVS
# lock contention. What a crock.
diffcmd = '/usr/bin/cvs -f diff -kk -C 2 -r %s -r %s %s' % (
oldrev, newrev, file)
fp = os.popen(diffcmd)
lines = fp.readlines()
sts = fp.close()
# ignore the error code, it always seems to be 1 :(
## if sts:
## return 'Error code %d occurred during diff\n' % (sts >> 8)
if len(lines) > DIFF_TRUNCATE_IF_LARGER:
removedlines = len(lines) - DIFF_HEAD_LINES - DIFF_TAIL_LINES
del lines[DIFF_HEAD_LINES:-DIFF_TAIL_LINES]
lines.insert(DIFF_HEAD_LINES,
'[...%d lines suppressed...]\n' % removedlines)
return string.join(lines, '')
def calculate_url(dir, filespec):
try:
file, oldrev, newrev = string.split(filespec, ',')
except ValueError:
# No diff to report
return '***** Bogus filespec: %s' % filespec
if oldrev == 'NONE':
lines = [ 'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jode/%s/%s?rev=%s' % (dir, file, newrev) ]
elif newrev == 'NONE':
lines = [ 'DELETED: http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jode/%s/%s?rev=%s' % (dir, file, oldrev) ]
else:
lines = [ 'http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jode/%s/%s.diff?r1=%s&r2=%s&diff_format=u' % (dir, file, oldrev, newrev) ]
return string.join(lines, '')
def blast_mail(mailcmd, dir, filestodiff):
## cannot wait for child process or that will cause parent to retain cvs
## lock for too long. Urg!
#if not os.fork():
# in the child
# give up the lock you cvs thang!
time.sleep(2)
fp = os.popen(mailcmd, 'w')
fp.write(sys.stdin.read())
fp.write('\n')
# append the cvsweb urls if available
fp.write('CVSWeb URLs:\n');
for file in filestodiff:
# fp.write(calculate_diff(file))
fp.write(calculate_url(dir, file))
fp.write('\n')
fp.close()
## doesn't matter what code we return, it isn't waited on
# os._exit(0)
# scan args for options
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 'h', ['cvsroot=', 'help'])
except getopt.error, msg:
usage(1, msg)
# parse the options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt == '--cvsroot':
os.environ['CVSROOT'] = arg
# What follows is the specification containing the files that were
# modified. The argument actually must be split, with the first component
# containing the directory the checkin is being made in, relative to
# $CVSROOT, followed by the list of files that are changing.
if not args:
usage(1, 'No CVS module specified')
specs = string.split(args[0])
changedfiles = [ specs[0] ];
for filespec in specs[1:]:
try:
file, oldrev, newrev = string.split(filespec, ',')
changedfiles.append(file)
except ValueError:
changedfiles.append(filespec)
SUBJECT = string.join(changedfiles, ' ')
del args[0]
# The remaining args should be the email addresses
if not args:
usage(1, 'No recipients specified')
# Now do the mail command
PEOPLE = string.join(args)
mailcmd = MAILCMD % vars()
if specs == ['-', 'Imported', 'sources']:
return
if specs[-3:] == ['-', 'New', 'directory']:
del specs[-3:]
blast_mail(mailcmd, specs[0], specs[1:])
if __name__ == '__main__':
main()
sys.exit(0)

@ -1,20 +0,0 @@
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

@ -1,21 +0,0 @@
# The "verifymsg" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

@ -1,7 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="net/sf/jode/obfuscator/modules/LocalOptimizer.java|net/sf/jode/obfuscator/modules/LocalizeFieldTransformer.java|net/sf/jode/obfuscator/modules/RemovePopAnalyzer.java" kind="src" output="build" path="src"/>
<classpathentry excluding="net/sf/jode/obfuscator/modules/LocalOptimizer.java|net/sf/jode/obfuscator/modules/RemovePopAnalyzer.java" kind="src" path="src"/>
<classpathentry excluding="src/|innerclasses/" kind="src" path="test"/>
<classpathentry kind="src" path="test/innerclasses"/>
<classpathentry kind="src" path="test/src"/>
<classpathentry kind="lib" path="lib/java-getopt-1.0.8.jar"/>
<classpathentry kind="src" path="props"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3.8.1"/>
<classpathentry kind="output" path="build"/>
</classpath>

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>jode</name>
<name>Jode</name>
<comment></comment>
<projects>
</projects>

@ -1,353 +0,0 @@
#Thu Mar 01 23:39:18 CET 2012
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.4
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
org.eclipse.jdt.core.compiler.problem.deadCode=warning
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nullReference=warning
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.3
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=mixed
org.eclipse.jdt.core.formatter.tabulation.size=8
org.eclipse.jdt.core.formatter.use_on_off_tags=false
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true

@ -1,4 +0,0 @@
#Thu Mar 01 22:21:28 CET 2012
eclipse.preferences.version=1
formatter_profile=org.eclipse.jdt.ui.default.sun_profile
formatter_settings_version=12

@ -1,3 +0,0 @@
#Thu Mar 01 22:15:48 CET 2012
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false

@ -302,7 +302,7 @@
<target name="test" depends="build-test">
<mkdir dir="${test.log}"/>
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement path="${test.build}"/>
<pathelement path="${build}"/>
@ -319,7 +319,7 @@
<target name="test-cvs" depends="build-test">
<mkdir dir="${test.log}"/>
<junit printsummary="yes" fork="yes" haltonfailure="yes">
<junit printsummary="yes" haltonfailure="yes">
<classpath>
<pathelement path="${test.build}"/>
<pathelement path="${build}"/>

@ -18,22 +18,21 @@ packages are already included in the archive. </li>
without any other package.</li> </ul>
</section>
<section title="Subversion Repository">
<p>You can get the latest sources from the <a
href="http://sourceforge.net/svn/?group_id=3790">SVN repository</a>.
Follow the instruction on that page; use
<code>/svnroot/jode/trunk/jode</code> as last part of the URL. If you
want to checkout a specific version you can checkout the URL
<code>.../svnroot/jode/tags/xxx/jode</code>:</p>
<section title="CVS Repository">
<p>You can get the latest sources from the <sflink href="cvs/"> CVS
repository</a>. Follow the instruction on that page; use
<code>jode</code> as <i>modulename</i>. If you want to checkout a
specific version you can use the <code>-r</code> option:</p>
<ul>
<li><code>../jode/tags/jode_1_0_93/jode</code>: checks out the version 1.0.93</li>
<li><code>../jode/branches/branch_1_1/jode</code>: checks out the latest version in the
<li><code>-r jode_1_0_93</code>: checks out the version 1.0.93</li>
<li><code>-r branch_1_1</code>: checks out the latest version in the
1.1 series.</li> </ul>
<p>To build the sources from latest SVN change to the main directory and invoke ant.</p>
<p>To build the 1.1 versions of jode change to the main directory and run
<p>To build the sources from CVS change to the main directory where
the <code>configure.in</code> file resides and run
<pre>aclocal && automake -a && autoconf</pre>
<p>Afterwards follow the instruction in the INSTALL file. </p>
</section>
</section>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -63,11 +63,6 @@ class BasicBlockReader implements Opcodes {
String name, type;
}
private class LNTEntry {
int lineNr;
int start;
}
InstrInfo[] infos;
HandlerEntry[] handlers;
BasicBlocks bb;
@ -543,8 +538,10 @@ class BasicBlockReader implements Opcodes {
case opc_ldc: {
int index = input.readUnsignedByte();
int tag = cp.getTag(index);
if (tag != ConstantPool.STRING && tag != ConstantPool.CLASS
&& tag != ConstantPool.INTEGER && tag != ConstantPool.FLOAT)
if (tag != ConstantPool.STRING
&& tag != ConstantPool.CLASS
&& tag != ConstantPool.INTEGER
&& tag != ConstantPool.FLOAT)
throw new ClassFormatException
("wrong constant tag: "+tag);
instr = new ConstantInstruction
@ -555,8 +552,10 @@ class BasicBlockReader implements Opcodes {
case opc_ldc_w: {
int index = input.readUnsignedShort();
int tag = cp.getTag(index);
if (tag != ConstantPool.STRING && tag != ConstantPool.CLASS
&& tag != ConstantPool.INTEGER && tag != ConstantPool.FLOAT)
if (tag != ConstantPool.STRING
&& tag != ConstantPool.CLASS
&& tag != ConstantPool.INTEGER
&& tag != ConstantPool.FLOAT)
throw new ClassFormatException
("wrong constant tag: "+tag);
instr = new ConstantInstruction

@ -35,6 +35,7 @@ class BasicBlockWriter implements Opcodes {
private class LVTEntry {
int startAddr, endAddr;
Instruction start, end;
LocalVariableInfo lvi;
}
@ -389,7 +390,8 @@ class BasicBlockWriter implements Opcodes {
length = 3;
break;
case opc_invokeinterface:
gcp.putRef(ConstantPool.INTERFACEMETHODREF, instr.getReference());
gcp.putRef(ConstantPool.INTERFACEMETHODREF,
instr.getReference());
length = 5;
break;
case opc_new:

@ -183,7 +183,6 @@ public class BasicBlocks extends BinaryInfo implements Opcodes {
BitSet visited = new BitSet();
Stack todo = new Stack();
startBlock.stackHeight = 0;
todo.push(startBlock);
while (!todo.isEmpty()) {

@ -280,6 +280,7 @@ public final class Block {
if (succs[succs.length-1] == null)
output.println("\treturn");
else
output.println("\tgoto "+succs[succs.length-1]);
}
}

@ -867,6 +867,10 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
}
if (deprecatedFlag)
gcp.putUTF8("Deprecated");
if (signature != null) {
gcp.putUTF8("Signature");
gcp.putUTF8(signature);
}
prepareAttributes(gcp);
}
@ -934,6 +938,11 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
output.writeShort(gcp.putUTF8("Deprecated"));
output.writeInt(0);
}
if (signature != null) {
output.writeShort(gcp.putUTF8("Signature"));
output.writeInt(2);
output.writeShort(gcp.putUTF8(signature));
}
}
@ -1193,14 +1202,20 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
/**
* Gets the type signature including template information of the class.
* <b>WARNING:</b> This field may disappear and merged into getType later.
* @return the type signature.
* The type signature of a class consists of the signature for the
* superclass followed by the signatures of the interfaces.
* @return the type signature, empty string for java.lang.Object.
* @see TypeSignature
*/
public String getSignature() {
if (status < HIERARCHY)
throw new IllegalStateException("status is "+status);
if (signature != null)
if (signature != null) {
System.err.println("Sig(attrib) of "+this+": "+signature);/*XXX REMOVE*/
return signature;
}
if (superclass == null)
return "";
StringBuffer sb = new StringBuffer();
sb.append('L').append(superclass.getName().replace('.','/'))
.append(";");
@ -1208,6 +1223,7 @@ public final class ClassInfo extends BinaryInfo implements Comparable {
sb.append('L').append(interfaces[i].getName().replace('.','/'))
.append(";");
}
System.err.println("Sig of "+this+": "+sb.toString());/*XXX REMOVE*/
return sb.toString();
}

@ -146,6 +146,10 @@ public final class FieldInfo extends BinaryInfo implements Comparable {
gcp.putUTF8("Synthetic");
if (deprecatedFlag)
gcp.putUTF8("Deprecated");
if (signature != null) {
gcp.putUTF8("Signature");
gcp.putUTF8(signature);
}
prepareAttributes(gcp);
}
@ -183,6 +187,11 @@ public final class FieldInfo extends BinaryInfo implements Comparable {
output.writeShort(gcp.putUTF8("Deprecated"));
output.writeInt(0);
}
if (signature != null) {
output.writeShort(gcp.putUTF8("Signature"));
output.writeInt(2);
output.writeShort(gcp.putUTF8(signature));
}
}
void write(GrowableConstantPool constantPool,
@ -325,7 +334,7 @@ public final class FieldInfo extends BinaryInfo implements Comparable {
public String toString() {
return "Field "+Modifier.toString(modifier)+" "+
typeSig+" "+name;
getSignature()+" "+name;
}
}

@ -234,6 +234,8 @@ public class GrowableConstantPool extends ConstantPool {
public int putConstant(Object c) {
if (c instanceof String) {
return putIndexed(STRING, c, putUTF8((String) c), 0);
} else if (c instanceof Reference) {
return putClassType(((Reference) c).getClazz());
} else {
int tag;
if (c instanceof Integer)
@ -279,6 +281,13 @@ public class GrowableConstantPool extends ConstantPool {
public int reserveConstant(Object c) {
if (c instanceof String) {
return putIndexed(STRING, c, -1, 0);
} else if (c instanceof Reference) {
String name = ((Reference) c).getClazz();
if (name.charAt(0) == 'L')
name = name.substring(1, name.length()-1);
else if (name.charAt(0) != '[')
throw new IllegalArgumentException("wrong class type: "+name);
return putIndexed(CLASS, name, -1, 0);
} else {
return putConstant(c);
}

@ -147,6 +147,10 @@ public final class MethodInfo extends BinaryInfo implements Comparable {
gcp.putUTF8("Synthetic");
if (deprecatedFlag)
gcp.putUTF8("Deprecated");
if (signature != null) {
gcp.putUTF8("Signature");
gcp.putUTF8(signature);
}
prepareAttributes(gcp);
}
@ -187,6 +191,11 @@ public final class MethodInfo extends BinaryInfo implements Comparable {
output.writeShort(gcp.putUTF8("Deprecated"));
output.writeInt(0);
}
if (signature != null) {
output.writeShort(gcp.putUTF8("Signature"));
output.writeInt(2);
output.writeShort(gcp.putUTF8(signature));
}
}
void write(GrowableConstantPool constantPool,
@ -325,6 +334,6 @@ public final class MethodInfo extends BinaryInfo implements Comparable {
* @return a string representation of this method.
*/
public String toString() {
return "MethodInfo[name="+name+",type="+typeSig+"]";
return "MethodInfo[name="+name+",sig="+getSignature()+"]";
}
}

@ -18,6 +18,10 @@
*/
package net.sf.jode.bytecode;
///#def COLLECTIONS java.util
import java.util.ArrayList;
import java.util.Map;
///#enddef
/**
* This class contains some static methods to handle type signatures. <br>
@ -212,12 +216,21 @@ public class TypeSignature {
* @param position the index to the last entry.
* @return the index to the next entry.
*/
static int skipType(String methodTypeSig, int position) {
public static int skipType(String methodTypeSig, int position) {
char c = methodTypeSig.charAt(position++);
while (c == '[')
c = methodTypeSig.charAt(position++);
if (c == 'L')
return methodTypeSig.indexOf(';', position) + 1;
if (c == 'L' || c == 'T') {
int angledepth = 0;
c = methodTypeSig.charAt(position++);
while (c != ';' || angledepth > 0) {
if (c == '<')
angledepth++;
else if (c == '>')
angledepth--;
c = methodTypeSig.charAt(position++);
}
}
return position;
}
@ -262,12 +275,50 @@ public class TypeSignature {
return 1;
}
/**
* Gets the argument type signatures of the given template signature.
* @param templateTypeSig the template type signature.
* @return an array containing all parameter types in correct order.
*/
public static String[] getArgumentTypes(String templateTypeSig) {
System.err.println(templateTypeSig);
int pos = 1;
int count = 0;
char c;
while ((c = templateTypeSig.charAt(pos)) != '>') {
if (c == '*') {
pos++;
} else {
if (c == '+' || c == '-')
pos++;
pos = skipType(templateTypeSig, pos);
}
count++;
}
String[] params = new String[count];
pos = 1;
for (int i = 0; i < count; i++) {
int start = pos;
c = templateTypeSig.charAt(pos);
if (c == '*') {
pos++;
} else {
if (c == '+' || c == '-')
pos++;
pos = skipType(templateTypeSig, pos);
}
params[i] = templateTypeSig.substring(start, pos);
}
return params;
}
/**
* Gets the parameter type signatures of the given method signature.
* @param methodTypeSig the method type signature.
* @return an array containing all parameter types in correct order.
*/
public static String[] getParameterTypes(String methodTypeSig) {
System.err.println(methodTypeSig);
int pos = 1;
int count = 0;
while (methodTypeSig.charAt(pos) != ')') {
@ -293,6 +344,230 @@ public class TypeSignature {
return methodTypeSig.substring(methodTypeSig.lastIndexOf(')')+1);
}
/**
* Gets the names and types of the generic parameters of the given type signature.
* @param typeSig the type signature.
* @return an array containing all generic parameters together with their
* type in correct order, or null if there aren't any generic parameters.
*/
public static String[] getGenericSignatures(String typeSig) {
System.err.println(typeSig);
if (typeSig.charAt(0) != '<')
return null;
int pos = 1;
int count = 0;
while (typeSig.charAt(pos) != '>') {
while (typeSig.charAt(pos) != ':')
pos++;
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
count++;
}
String[] params = new String[count];
pos = 1;
count = 0;
while (typeSig.charAt(pos) != '>') {
int spos = pos;
while (typeSig.charAt(pos) != ':')
pos++;
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
params[count++] = typeSig.substring(spos, pos);
}
return params;
}
/**
* Gets the names of the generic parameters of the given type signature.
* @param typeSig the type signature.
* @return an array containing all generic parameter types
* in correct order, or null if there aren't any generic parameters.
*/
public static String[] getGenericNames(String typeSig) {
System.err.println(typeSig);
if (typeSig.charAt(0) != '<')
return null;
int pos = 1;
int count = 0;
while (typeSig.charAt(pos) != '>') {
while (typeSig.charAt(pos) != ':')
pos++;
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
count++;
}
String[] params = new String[count];
pos = 1;
count = 0;
while (typeSig.charAt(pos) != '>') {
int spos = pos;
while (typeSig.charAt(pos) != ':')
pos++;
params[count++] = typeSig.substring(spos, pos);
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
}
return params;
}
/**
* Gets the signature of the super class from a class signature.
* @param typeSig the class's signature.
* @return the signature of the super class.
*/
public static String getSuperSignature(String typeSig) {
int pos = 0;
if (typeSig.charAt(0) == '<') {
/* Skip generic info */
pos++;
while (typeSig.charAt(pos) != '>') {
while (typeSig.charAt(pos) != ':')
pos++;
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
}
pos++;
}
return typeSig.substring(pos, skipType(typeSig, pos));
}
/**
* Gets the signatures of the super interfaces from a class signature.
* @param typeSig the class's signature.
* @return an array containing the signatures of the interfaces.
*/
public static String[] getIfaceSignatures(String typeSig) {
int pos = 0;
if (typeSig.charAt(0) == '<') {
/* Skip generic info */
pos++;
while (typeSig.charAt(pos) != '>') {
while (typeSig.charAt(pos) != ':')
pos++;
/* check for empty entry */
if (typeSig.charAt(pos+1) == ':')
pos++;
while (typeSig.charAt(pos) == ':') {
/* skip colon and type */
pos = skipType(typeSig, pos + 1);
}
}
pos++;
}
pos = skipType(typeSig, pos);
ArrayList list = new ArrayList();
while (pos < typeSig.length()) {
int epos = skipType(typeSig, pos);
list.add(typeSig.substring(pos, epos));
pos = epos;
}
return (String[]) list.toArray(new String[list.size()]);
}
private static int mapGenericsInType(String typeSig, Map generics,
StringBuffer mapped, int spos) {
int pos = spos;
char c = typeSig.charAt(pos++);
while (c == '[')
c = typeSig.charAt(pos++);
if (c == 'T') {
int epos = typeSig.indexOf(';', pos);
String key = typeSig.substring(pos, epos);
String mapval = (String) generics.get(key);
if (mapval != null) {
mapped.append(typeSig.substring(spos, pos - 1))
.append(key);
spos = epos + 1;
}
pos = epos + 1;
} else if (c == 'L') {
c = typeSig.charAt(pos++);
while (c != ';' && c != '<')
c = typeSig.charAt(pos++);
if (c == '<') {
mapped.append(typeSig.substring(spos, pos));
while (typeSig.charAt(pos) != '>') {
pos = mapGenericsInType(typeSig, generics, mapped, pos);
}
spos = pos;
pos += 2;
}
}
mapped.append(typeSig.substring(spos, pos));
return pos;
}
/**
* Map the names of the generic parameters in the given type signature
* and return the type signature with the generic parameters mapped to
* (more or less) real types.
* @param typeSig the type signature.
* @param generics A map from generic names to type signatures.
* @return the mapped generic type signature.
*/
public static String mapGenerics(String typeSig, Map generics) {
StringBuffer mapped = new StringBuffer();
int pos = 0;
int spos = 0;
if (typeSig.length() == 0)
return "";
char c = typeSig.charAt(pos++);
if (c == '<') {
c = typeSig.charAt(pos++);
while (c != '>') {
while (c != ':') {
c = typeSig.charAt(pos++);
}
if (typeSig.charAt(pos) == ':')
pos++;
while (c == ':') {
mapped.append(typeSig.substring(spos, pos));
pos = mapGenericsInType(typeSig, generics, mapped, pos);
spos = pos;
c = typeSig.charAt(pos);
}
}
}
if (c == '(') {
while (typeSig.charAt(pos) != ')') {
mapped.append(typeSig.substring(spos, pos));
pos = mapGenericsInType(typeSig, generics, mapped, pos);
spos = pos;
}
pos++;
}
mapped.append(typeSig.substring(spos, pos));
while (pos < typeSig.length()) {
pos = mapGenericsInType(typeSig, generics, mapped, pos);
}
return mapped.toString();
}
/**
* Gets the default value an object of the given type has. It is
* null for objects and arrays, Integer(0) for boolean and short
@ -328,19 +603,61 @@ public class TypeSignature {
/**
* Checks if there is a valid class name starting at index
* in string typesig and ending with a semicolon.
* in string typeSig and ending with a semicolon.
* @return the index at which the class name ends.
* @exception IllegalArgumentException if there was an illegal character.
* @exception StringIndexOutOfBoundsException if the typesig ended early.
* @exception StringIndexOutOfBoundsException if the typeSig ended early.
*/
private static int checkClassName(String clName, int i)
throws IllegalArgumentException, StringIndexOutOfBoundsException
{
char c = clName.charAt(i++);
while (c != ';' && c != '.' && c != '<') {
if (c != '/' && !Character.isJavaIdentifierPart(c))
throw new IllegalArgumentException("Illegal java class name: "
+ clName);
c = clName.charAt(i++);
}
if (c == '<') {
c = clName.charAt(i++);
do {
if (c == '*')
i++;
else {
if (c == '+' || c == '-')
c = clName.charAt(i++);
if (c != 'L' && c != 'T' && c != '[')
throw new IllegalArgumentException
("Wrong class instantiation: "+clName);
i = checkTypeSig(clName, i - 1);
}
c = clName.charAt(i++);
} while (c != '>');
c = clName.charAt(i++);
}
if (c == '.')
return checkClassName(clName, i);
if (c != ';')
throw new IllegalArgumentException
("no ; after > in "+clName);
return i;
}
/**
* Checks if there is a valid class name starting at index
* in string typeSig and ending with a semicolon.
* @return the index at which the class name ends.
* @exception IllegalArgumentException if there was an illegal character.
* @exception StringIndexOutOfBoundsException if the typeSig ended early.
*/
private static int checkTemplateName(String clName, int i)
throws IllegalArgumentException, StringIndexOutOfBoundsException
{
while (true) {
char c = clName.charAt(i++);
if (c == ';')
return i;
if (c != '/' && !Character.isJavaIdentifierPart(c))
if (!Character.isJavaIdentifierPart(c))
throw new IllegalArgumentException("Illegal java class name: "
+ clName);
}
@ -348,76 +665,149 @@ public class TypeSignature {
/**
* Checks if there is a valid simple type signature starting at index
* in string typesig.
* in string typeSig.
* @return the index at which the type signature ends.
* @exception IllegalArgumentException if there was an illegal character.
* @exception StringIndexOutOfBoundsException if the typesig ended early.
* @exception StringIndexOutOfBoundsException if the typeSig ended early.
*/
private static int checkTypeSig(String typesig, int index) {
char c = typesig.charAt(index++);
private static int checkTypeSig(String typeSig, int index) {
char c = typeSig.charAt(index++);
while (c == '[')
c = typesig.charAt(index++);
c = typeSig.charAt(index++);
if (c == 'L') {
index = checkClassName(typesig, index);
index = checkClassName(typeSig, index);
} else if (c == 'T') {
index = checkTemplateName(typeSig, index);
} else {
if ("ZBSCIJFD".indexOf(c) == -1)
throw new IllegalArgumentException("Type sig error: "+typesig);
throw new IllegalArgumentException("Type sig error: "+typeSig);
}
return index;
}
/**
* Checks whether a given type signature starts with valid generic
* part and returns the index where generics end.
* @param typeSig the type signature.
* @param i the start index.
* @exception NullPointerException if typeSig is null.
* @exception IllegalArgumentException if typeSig is not a valid
* type signature.
* @return 0 if no generics at beginning, otherwise the
* index after the &gt; sign.
*/
private static int checkGenerics(String typeSig, int i) {
if (typeSig.charAt(i) == '<') {
i++;
char c = typeSig.charAt(i++);
if (c == '>')
throw new IllegalArgumentException("Empty Generics: "+typeSig);
while (c != '>') {
if (c == ':')
throw new IllegalArgumentException("Empty type name: "+typeSig);
while (c != ':') {
if (!Character.isJavaIdentifierPart(c))
throw new IllegalArgumentException
("Illegal generic name: "+ typeSig);
c = typeSig.charAt(i++);
}
c = typeSig.charAt(i++);
if (c != 'L' && c != 'T' && c != ':')
throw new IllegalArgumentException
("Wrong generic extends: "+typeSig);
if (c != ':')
i = checkTypeSig(typeSig, i - 1);
c = typeSig.charAt(i++);
while(c == ':') {
i = checkTypeSig(typeSig, i);
c = typeSig.charAt(i++);
}
}
}
return i;
}
/**
* Checks whether a given type signature is a valid (not method)
* type signature. Throws an exception otherwise.
* @param typesig the type signature.
* @param typeSig the type signature.
* @exception NullPointerException if typeSig is null.
* @exception IllegalArgumentException if typeSig is not a valid
* type signature or if it's a method type signature.
*/
public static void checkTypeSig(String typesig)
public static void checkTypeSig(String typeSig)
throws IllegalArgumentException
{
try {
if (checkTypeSig(typesig, 0) != typesig.length())
int i = checkGenerics(typeSig, 0);
if (checkTypeSig(typeSig, i) != typeSig.length())
throw new IllegalArgumentException
("Type sig too long: "+typesig);
("Type sig too long: "+typeSig);
} catch (StringIndexOutOfBoundsException ex) {
throw new IllegalArgumentException
("Incomplete type sig: "+typeSig);
}
}
/**
* Checks whether a given type signature is a valid class
* type signature. Throws an exception otherwise.
* A class type signature starts optionally with generics,
* followed by type signature of super class, followed by
* type signature of super interfaces.
* @param typeSig the type signature.
* @exception NullPointerException if typeSig is null.
* @exception IllegalArgumentException if typeSig is not a valid
* type signature or if it's a method type signature.
*/
public static void checkClassTypeSig(String typeSig)
throws IllegalArgumentException
{
try {
int i = checkGenerics(typeSig, 0);
i = checkTypeSig(typeSig, i);
while (i != typeSig.length()) {
i = checkTypeSig(typeSig, i);
}
} catch (StringIndexOutOfBoundsException ex) {
throw new IllegalArgumentException
("Incomplete type sig: "+typesig);
("Incomplete type sig: "+typeSig);
}
}
/**
* Checks whether a given type signature is a valid method
* type signature. Throws an exception otherwise.
* @param typesig the type signature.
* @param typeSig the type signature.
* @exception NullPointerException if typeSig is null.
* @exception IllegalArgumentException if typeSig is not a valid
* method type signature.
*/
public static void checkMethodTypeSig(String typesig)
public static void checkMethodTypeSig(String typeSig)
throws IllegalArgumentException
{
try {
if (typesig.charAt(0) != '(')
int i = checkGenerics(typeSig, 0);
if (typeSig.charAt(i) != '(')
throw new IllegalArgumentException
("No method signature: "+typesig);
int i = 1;
while (typesig.charAt(i) != ')')
i = checkTypeSig(typesig, i);
("No method signature: "+typeSig);
i++;
while (typeSig.charAt(i) != ')')
i = checkTypeSig(typeSig, i);
// skip closing parenthesis.
i++;
if (typesig.charAt(i) == 'V')
if (typeSig.charAt(i) == 'V')
// accept void return type.
i++;
else
i = checkTypeSig(typesig, i);
if (i != typesig.length())
i = checkTypeSig(typeSig, i);
if (i != typeSig.length())
throw new IllegalArgumentException
("Type sig too long: "+typesig);
("Type sig too long: "+typeSig);
} catch (StringIndexOutOfBoundsException ex) {
throw new IllegalArgumentException
("Incomplete type sig: "+typesig);
("Incomplete type sig: "+typeSig);
}
}
}

@ -24,7 +24,8 @@ import java.awt.Graphics;
import java.awt.Insets;
public class Applet extends java.applet.Applet {
private final int BORDER = 10;
private static final long serialVersionUID = -132941289170424862L;
private final int BORDER = 10;
private final int BEVEL = 2;
private Window jodeWin = new Window(this);
private Insets myInsets;

@ -21,11 +21,14 @@ package net.sf.jode.decompiler;
import net.sf.jode.GlobalOptions;
import net.sf.jode.type.MethodType;
import net.sf.jode.type.Type;
import net.sf.jode.type.GenericParameterType;
import net.sf.jode.type.ClassType;
import net.sf.jode.bytecode.ClassFormatException;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.bytecode.FieldInfo;
import net.sf.jode.bytecode.MethodInfo;
import net.sf.jode.bytecode.TypeSignature;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.ThisOperator;
import net.sf.jode.flow.TransformConstructors;
@ -33,7 +36,11 @@ import net.sf.jode.flow.StructuredBlock;
import net.sf.jode.util.SimpleSet;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.Enumeration;
import java.io.IOException;
///#def COLLECTIONS java.util
@ -46,8 +53,11 @@ public class ClassAnalyzer
{
ImportHandler imports;
ClassInfo clazz;
ClassType myType;
ClassDeclarer parent;
ProgressListener progressListener;
String[] generics;
GenericParameterType[] genericTypes;
/**
* The complexity for initi#alizing a class.
@ -92,9 +102,49 @@ public class ClassAnalyzer
throws ClassFormatException, IOException
{
clazz.load(ClassInfo.ALL);
String signature = clazz.getSignature();
if (signature.charAt(0) == '<') {
String[] genericSignatures = TypeSignature.getGenericSignatures(signature);
generics = new String[genericSignatures.length];
genericTypes = new GenericParameterType[genericSignatures.length];
for (int i = 0; i < generics.length; i++) {
int colon = genericSignatures[i].indexOf(':');
String genName;
if (colon == -1) {
generics[i] = genericSignatures[i];
genericTypes[i] =
new GenericParameterType(genericSignatures[i],
Type.tObject,
new ClassType[0]);
} else {
generics[i] = genericSignatures[i].substring(0, colon);
String remainder = genericSignatures[i].substring(colon+1);
int nextIndex = TypeSignature.skipType(remainder, 0);
List superClazzes = new ArrayList();
for (;;) {
String clazzSig = remainder.substring(0, nextIndex);
superClazzes.add(Type.tType(clazz.getClassPath(),
clazzSig));
if (nextIndex >= remainder.length())
break;
remainder = remainder.substring(nextIndex+1);
}
ClassType genSupClass = (ClassType) superClazzes.get(0);
if (!genSupClass.isInterface())
superClazzes.remove(0);
else
genSupClass = Type.tObject;
ClassType[] genSupIfaces = (ClassType[])
superClazzes.toArray(new ClassType[0]);
genericTypes[i] = new GenericParameterType(generics[i],
genSupClass,
genSupIfaces);
}
}
}
ClassInfo superClass = clazz.getSuperclass();
String myPackage = clazz.getName().substring
(clazz.getName().lastIndexOf('.') + 1);
(clazz.getName().lastIndexOf('.') + 1);
while (superClass != null) {
int howMuch = (superClass.getName().startsWith(myPackage)
&& (superClass.getName().lastIndexOf('.')
@ -117,6 +167,7 @@ public class ClassAnalyzer
this.parent = parent;
this.clazz = clazz;
this.myType = Type.tClass(clazz, genericTypes);
this.imports = imports;
modifiers = clazz.getModifiers();
@ -127,7 +178,7 @@ public class ClassAnalyzer
*/
if ((Options.options & Options.OPTION_INNER) != 0
&& parent instanceof ClassAnalyzer && !isStatic())
outerInstance = new ThisOperator(((ClassAnalyzer) parent).clazz);
outerInstance = new ThisOperator((ClassAnalyzer) parent);
if (outerValues != null)
this.outerValues = new OuterValues(this, outerValues);
}
@ -195,6 +246,10 @@ public class ClassAnalyzer
return clazz;
}
public ClassType getType() {
return myType;
}
public String getName() {
return name;
@ -456,6 +511,9 @@ public class ClassAnalyzer
{
dumpDeclaration(writer, null, 0.0, 0.0);
}
public void dumpGenericDeclaration(GenericParameterType gen) {
}
public void dumpDeclaration(TabbedPrintWriter writer,
ProgressListener pl, double done, double scale)
@ -468,7 +526,7 @@ public class ClassAnalyzer
return;
}
writer.startOp(TabbedPrintWriter.NO_PAREN, 0);
writer.startOp(writer.NO_PAREN, 0);
/* Clear the SUPER bit, which is also used as SYNCHRONIZED bit. */
int modifiedModifiers = modifiers & ~(Modifier.SYNCHRONIZED
| STRICTFP);
@ -495,28 +553,23 @@ public class ClassAnalyzer
if (!clazz.isInterface())
writer.print("class ");
writer.print(name);
ClassInfo superClazz = clazz.getSuperclass();
if (superClazz != null &&
superClazz.getName() != "java.lang.Object") {
writer.breakOp();
writer.print(" extends " + (writer.getClassString
(superClazz, Scope.CLASSNAME)));
}
ClassInfo[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
writer.breakOp();
writer.print(clazz.isInterface() ? " extends " : " implements ");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 1);
for (int i=0; i < interfaces.length; i++) {
if (genericTypes != null) {
writer.print("<");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
for (int i=0; i< genericTypes.length; i++) {
if (i > 0) {
writer.print(", ");
writer.breakOp();
}
writer.print(writer.getClassString
(interfaces[i], Scope.CLASSNAME));
writer.print(genericTypes[i].getClassName());
writer.printExtendsImplements(genericTypes[i]);
}
writer.endOp();
writer.print(">");
}
String signature = clazz.getSignature();
System.err.println("Class Signature: "+signature+ " (class "+name+")");
writer.printExtendsImplements(myType);
writer.println();
writer.openBraceClass();
@ -630,7 +683,7 @@ public class ClassAnalyzer
needNewLine = true;
}
writer.popScope();
clazz.drop(ClassInfo.DECLARATIONS);
clazz.drop(clazz.DECLARATIONS);
}
public void dumpSource(TabbedPrintWriter writer)
@ -668,7 +721,6 @@ public class ClassAnalyzer
dumpSource(writer, pl, 0.8, 0.2);
if (pl != null)
pl.updateProgress(1.0, name);
writer.flush();
}
public boolean isScopeOf(Object obj, int scopeType) {
@ -705,9 +757,9 @@ public class ClassAnalyzer
}
if (usageType == CLASSNAME || usageType == AMBIGUOUSNAME) {
try {
info.load(ClassInfo.DECLARATIONS);
info.load(info.DECLARATIONS);
} catch (IOException ex) {
info.guess(ClassInfo.DECLARATIONS);
info.guess(info.DECLARATIONS);
}
ClassInfo[] iinfos = info.getClasses();
if (iinfos != null) {
@ -747,6 +799,18 @@ public class ClassAnalyzer
return getParent().getClassAnalyzer(cinfo);
}
public GenericParameterType getGenericType(String name) {
if (genericTypes != null) {
for (int i = 0; i < genericTypes.length; i++) {
if (genericTypes[i].getClassName().equals(name))
return genericTypes[i];
}
}
if (parent != null)
return parent.getGenericType(name);
return null;
}
/**
* Get the class analyzer for the given inner class.
* @param name the short name of the inner class

@ -19,6 +19,8 @@
package net.sf.jode.decompiler;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.type.GenericParameterType;
/**
* This is the interface for objects, that a method can declare
@ -29,6 +31,12 @@ public interface ClassDeclarer {
* @return null if this is the outermost instance.
*/
public ClassDeclarer getParent();
/**
* Get the current class path.
* @return the current class path.
*/
public ClassPath getClassPath();
/**
* Get the class analyzer for the given anonymous class info. It
@ -38,5 +46,13 @@ public interface ClassDeclarer {
*/
public ClassAnalyzer getClassAnalyzer(ClassInfo ci);
/**
* Gets the generic type for the given named generic.
* @param name the name of the generic, e.g. K.
* @return the generic type for the named generic.
*/
public GenericParameterType getGenericType(String name);
public void addClassAnalyzer(ClassAnalyzer classAna);
}

@ -21,6 +21,8 @@ package net.sf.jode.decompiler;
import net.sf.jode.type.Type;
import net.sf.jode.bytecode.FieldInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.ThisOperator;
import net.sf.jode.expr.LocalLoadOperator;
import net.sf.jode.expr.ConstOperator;
import net.sf.jode.expr.OuterLocalOperator;
@ -49,13 +51,18 @@ public class FieldAnalyzer implements Analyzer {
imports = i;
modifiers = fd.getModifiers();
type = Type.tType(cla.getClassPath(), fd.getType());
type = Type.tType(cla.getClassPath(), cla.getType(), fd.getSignature());
fieldName = fd.getName();
constant = null;
this.isSynthetic = fd.isSynthetic();
this.isDeprecated = fd.isDeprecated();
if (fd.getConstant() != null) {
constant = new ConstOperator(fd.getConstant());
if (fd.getConstant() instanceof String) {
constant = new ConstOperator(cla.getClassPath(),
(String) fd.getConstant());
} else {
constant = new ConstOperator(fd.getConstant());
}
constant.setType(type);
constant.makeInitializer(type);
}

@ -21,6 +21,7 @@ package net.sf.jode.decompiler;
import net.sf.jode.GlobalOptions;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.type.SystemClassType;
import net.sf.jode.type.Type;
import net.sf.jode.type.ArrayType;
import net.sf.jode.type.ClassInfoType;
@ -208,6 +209,7 @@ public class ImportHandler {
}
public void dumpHeader(TabbedPrintWriter writer)
throws java.io.IOException
{
writer.println("/* "+ className
+ " - Decompiled by JODE");
@ -320,7 +322,7 @@ public class ImportHandler {
useType(((ArrayType) type).getElementType());
else if (type instanceof ClassInfoType)
useClass(((ClassInfoType) type).getClassInfo());
else if (type instanceof ClassType)
else if (type instanceof SystemClassType)
useClass(((ClassType) type).getClassName());
}
@ -371,6 +373,7 @@ public class ImportHandler {
String pkgName = name.substring(0, pkgdelim);
Integer i;
if (pkgName.equals(pkg)
|| (imports.get(pkgName+".*") != null
&& !conflictsImport(name))) {

@ -53,7 +53,6 @@ public class Main extends Options {
new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'D'),
new LongOpt("import", LongOpt.REQUIRED_ARGUMENT, null, 'i'),
new LongOpt("style", LongOpt.REQUIRED_ARGUMENT, null, 's'),
new LongOpt("chars-per-line", LongOpt.REQUIRED_ARGUMENT, null, 'l'),
new LongOpt("lvt", LongOpt.OPTIONAL_ARGUMENT, null,
OPTION_START+0),
new LongOpt("inner", LongOpt.OPTIONAL_ARGUMENT, null,
@ -95,10 +94,8 @@ public class Main extends Options {
"The directories should be separated by ','.");
err.println(" -d, --dest <dir> "+
"write decompiled files to disk into directory destdir.");
err.println(" -s, --style {sun|gnu|pascal|python} "+
err.println(" -s, --style {sun|gnu} "+
"specify indentation style");
err.println(" -l, --chars-per-line <number> "+
"specify line length");
err.println(" -i, --import <pkglimit>,<clslimit>");
err.println(" "+
"import classes used more than clslimit times");
@ -215,8 +212,14 @@ public class Main extends Options {
}
}
public static void main(String[] params) throws Throwable{
decompile(params);
public static void main(String[] params) {
try {
decompile(params);
} catch (ExceptionInInitializerError ex) {
ex.getException().printStackTrace();
} catch (Throwable ex) {
ex.printStackTrace();
}
/* When AWT applications are compiled with insufficient
* classpath the type guessing by reflection code can
* generate an awt thread that will prevent normal
@ -247,13 +250,12 @@ public class Main extends Options {
int importClassLimit = ImportHandler.DEFAULT_CLASS_LIMIT;;
int outputStyle = TabbedPrintWriter.BRACE_AT_EOL;
int indentSize = 4;
int outputLineLength = 79;
boolean keepGoing = false;
GlobalOptions.err.println(GlobalOptions.copyright);
boolean errorInParams = false;
Getopt g = new Getopt("net.sf.jode.decompiler.Main", params, "hVvkc:d:D:i:s:l:",
Getopt g = new Getopt("net.sf.jode.decompiler.Main", params, "hVvkc:d:D:i:s:",
longOptions, true);
for (int opt = g.getopt(); opt != -1; opt = g.getopt()) {
switch(opt) {
@ -307,12 +309,9 @@ public class Main extends Options {
} else if (arg.equals("sun")) {
outputStyle = TabbedPrintWriter.BRACE_AT_EOL;
indentSize = 4;
} else if (arg.equals("pascal")) {
outputStyle = 0;
indentSize = 4;
} else if (arg.equals("python") || arg.equals("codd")) {
outputStyle = TabbedPrintWriter.BRACE_AT_EOL|TabbedPrintWriter.CODD_FORMATTING;
indentSize = 4;
} else if (arg.equals("pascal")) {
outputStyle = 0;
indentSize = 4;
} else {
GlobalOptions.err.println
("net.sf.jode.decompiler.Main: Unknown style `"+arg+"'.");
@ -320,18 +319,6 @@ public class Main extends Options {
}
break;
}
case 'l': {
String arg = g.getOptarg();
try {
outputLineLength = Integer.parseInt(arg.trim());
}
catch (RuntimeException rte) {
GlobalOptions.err.println(
"net.sf.jode.decompiler.Main: Invalid Linelength " + arg);
errorInParams = true;
}
break;
}
case 'i': {
String arg = g.getOptarg();
int comma = arg.indexOf(',');
@ -378,7 +365,7 @@ public class Main extends Options {
TabbedPrintWriter writer = null;
if (destDir == null)
writer = new TabbedPrintWriter(System.out, imports, true,
outputStyle, indentSize, 0, outputLineLength);
outputStyle, indentSize, 0, 79);
else if (destDir.toLowerCase().endsWith(".zip")
|| destDir.toLowerCase().endsWith(".jar")) {
try {
@ -390,7 +377,7 @@ public class Main extends Options {
}
writer = new TabbedPrintWriter(new BufferedOutputStream(destZip),
imports, false,
outputStyle, indentSize, 0, outputLineLength);
outputStyle, indentSize, 0, 79);
}
for (int i= g.getOptind(); i< params.length; i++) {
try {

@ -22,13 +22,16 @@ import net.sf.jode.GlobalOptions;
import net.sf.jode.bytecode.BasicBlocks;
import net.sf.jode.bytecode.Block;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.bytecode.Handler;
import net.sf.jode.bytecode.Instruction;
import net.sf.jode.bytecode.LocalVariableInfo;
import net.sf.jode.bytecode.MethodInfo;
import net.sf.jode.bytecode.TypeSignature;
import net.sf.jode.jvm.SyntheticAnalyzer;
import net.sf.jode.type.*;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.ConstOperator;
import net.sf.jode.expr.CheckNullOperator;
import net.sf.jode.expr.ThisOperator;
import net.sf.jode.expr.LocalLoadOperator;
@ -37,15 +40,23 @@ import net.sf.jode.expr.InvokeOperator;
import net.sf.jode.flow.StructuredBlock;
import net.sf.jode.flow.FlowBlock;
import net.sf.jode.flow.TransformExceptionHandlers;
import net.sf.jode.flow.Jump;
import net.sf.jode.jvm.CodeVerifier;
import net.sf.jode.jvm.VerifyException;
import net.sf.jode.util.SimpleMap;
import java.lang.reflect.Modifier;
import java.util.BitSet;
import java.util.Stack;
import java.util.Vector;
import java.util.Enumeration;
import java.io.DataInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
///#def COLLECTIONS java.util
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;
@ -178,6 +189,11 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
* classes that are used in this method.
*/
Collection usedAnalyzers;
/**
* This array contains the generic types this method declares if
* it is generic.
*/
GenericParameterType[] genericTypes;
/**
* This is the default constructor.
@ -191,7 +207,47 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
this.imports = imports;
this.minfo = minfo;
this.methodName = minfo.getName();
this.methodType = Type.tMethod(cla.getClassPath(), minfo.getType());
String signature = minfo.getSignature();
if (signature.charAt(0) == '<') {
String[] genericSignatures =
TypeSignature.getGenericSignatures(signature);
genericTypes = new GenericParameterType[genericSignatures.length];
for (int i = 0; i < genericTypes.length; i++) {
int colon = genericSignatures[i].indexOf(':');
String genName;
if (colon == -1) {
genericTypes[i] =
new GenericParameterType(genericSignatures[i],
Type.tObject,
new ClassType[0]);
} else {
String genname = genericSignatures[i].substring(0, colon);
String remainder = genericSignatures[i].substring(colon+1);
int nextIndex = TypeSignature.skipType(remainder, 0);
List superClazzes = new ArrayList();
for (;;) {
String clazzSig = remainder.substring(0, nextIndex);
superClazzes.add(Type.tType(classAnalyzer.getClassPath(),
classAnalyzer.getType(), clazzSig));
if (nextIndex >= remainder.length())
break;
remainder = remainder.substring(nextIndex+1);
}
ClassType genSupClass = (ClassType) superClazzes.get(0);
if (!genSupClass.isInterface())
superClazzes.remove(0);
else
genSupClass = Type.tObject;
ClassType[] genSupIfaces = (ClassType[])
superClazzes.toArray(new ClassType[0]);
genericTypes[i] = new GenericParameterType(genname,
genSupClass,
genSupIfaces);
}
}
}
this.methodType = Type.tMethod(cla.getClassPath(), cla.getType(), signature, genericTypes);
this.isConstructor =
methodName.equals("<init>") || methodName.equals("<clinit>");
@ -415,8 +471,10 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
LocalInfo li = new LocalInfo(this, lvi.getSlot());
if ((Options.options & Options.OPTION_LVT) != 0
&& lvi.getName() != null)
li.addHint(lvi.getName(), Type.tType(classAnalyzer.getClassPath(),
lvi.getType()));
li.addHint(lvi.getName(),
Type.tType(classAnalyzer.getClassPath(),
classAnalyzer.getType(),
lvi.getType()));
allLocals.addElement(li);
return li;
}
@ -433,7 +491,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
Block[] blocks = bb.getBlocks();
for (int i=0; i < blocks.length; i++)
count += blocks[i].getInstructions().length;
return count;
return (double) count;
}
}
@ -453,12 +511,15 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
Block[] blocks = bb.getBlocks();
FlowBlock[] flows = new FlowBlock[blocks.length];
TransformExceptionHandlers excHandlers;
TransformExceptionHandlers excHandlers;
{
for (int i=0; i < blocks.length; i++)
flows[i] = new FlowBlock(this, i, i > 0 ? flows[i-1]: null);
/* We transform every basic block into a FlowBlock
/* While we read the opcodes into FlowBlocks
* we try to combine sequential blocks, as soon as we
* find two sequential instructions in a row, where the
* second has no predecessors.
*/
int count = 0;
for (int i=0; i < blocks.length; i++) {
@ -507,23 +568,22 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
excHandlers = new TransformExceptionHandlers(flows);
for (int i=0; i<handlers.length; i++) {
Type type = null;
int start = handlers[i].getStart().getBlockNr();
int end = handlers[i].getEnd().getBlockNr();
FlowBlock handler = flows[handlers[i].getCatcher().getBlockNr()];
FlowBlock start = flows[handlers[i].getStart().getBlockNr()];
FlowBlock end = flows[handlers[i].getEnd().getBlockNr()];
FlowBlock handler
= flows[handlers[i].getCatcher().getBlockNr()];
if (handlers[i].getType() != null)
type = Type.tClass(classAnalyzer.getClassPath(),
handlers[i].getType());
for (int j = start; j <= end; j++) {
if (flows[j] != handler)
flows[j].addExceptionHandler(type, handler);
}
excHandlers.addHandler(start, end, handler, type);
}
}
if (GlobalOptions.verboseLevel > 0)
GlobalOptions.err.print('-');
//excHandlers.analyze();
excHandlers.analyze();
methodHeader.analyze();
methodHeader.removeStartPred();
@ -572,11 +632,10 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
int offset = 0;
int slot = 0;
if (!isStatic()) {
ClassInfo classInfo = classAnalyzer.getClazz();
param[offset] = getLocalInfo(bb != null
? bb.getParamInfo(slot)
: LocalVariableInfo.getInfo(slot));
param[offset].setExpression(new ThisOperator(classInfo, true));
param[offset].setExpression(new ThisOperator(classAnalyzer, true));
slot++;
offset++;
}
@ -607,6 +666,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
public void analyzeInnerClasses()
throws ClassFormatError
{
int serialnr = 0;
Enumeration elts = anonConstructors.elements();
while (elts.hasMoreElements()) {
InvokeOperator cop = (InvokeOperator) elts.nextElement();
@ -682,10 +742,10 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (synth != null) {
// We don't need this class anymore (hopefully?)
if (synth.getKind() == SyntheticAnalyzer.GETCLASS)
if (synth.getKind() == synth.GETCLASS)
return true;
if (synth.getKind() >= SyntheticAnalyzer.ACCESSGETFIELD
&& synth.getKind() <= SyntheticAnalyzer.ACCESSDUPPUTSTATIC
if (synth.getKind() >= synth.ACCESSGETFIELD
&& synth.getKind() <= synth.ACCESSDUPPUTSTATIC
&& (Options.options & Options.OPTION_INNER) != 0
&& (Options.options & Options.OPTION_ANON) != 0)
return true;
@ -814,8 +874,8 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
| Modifier.PROTECTED | Modifier.PRIVATE);
modifiedModifiers &= ~STRICTFP;
writer.startOp(TabbedPrintWriter.NO_PAREN, 0);
writer.startOp(TabbedPrintWriter.NO_PAREN, 5);
writer.startOp(writer.NO_PAREN, 0);
writer.startOp(writer.NO_PAREN, 5);
String delim ="";
if (minfo.isSynthetic()) {
@ -859,7 +919,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
writer.breakOp();
writer.printOptionalSpace();
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
int offset = skipParams + (isStatic() ? 0 : 1);
for (int i = offset; i < param.length; i++) {
if (i > offset) {
@ -875,7 +935,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
if (exceptions.length > 0) {
writer.breakOp();
writer.print(" throws ");
writer.startOp(TabbedPrintWriter.NO_PAREN, 0);
writer.startOp(writer.NO_PAREN, 0);
for (int i= 0; i< exceptions.length; i++) {
if (i > 0) {
writer.print(", ");
@ -982,7 +1042,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
}
public void analyzeInvokeOperator(InvokeOperator cop) {
ClassInfo clazz = cop.getClassInfo();
ClassInfo clazz = (ClassInfo) cop.getClassInfo();
ClassAnalyzer anonAnalyzer = getParent().getClassAnalyzer(clazz);
if (anonAnalyzer == null) {
@ -1000,7 +1060,7 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
expr).getSubExpressions()[0];
if (expr instanceof ThisOperator) {
outerValueArray[j] =
new ThisOperator(((ThisOperator) expr).getClassInfo());
new ThisOperator(((ThisOperator) expr).getClassAnalyzer());
continue;
}
LocalInfo li = null;
@ -1098,6 +1158,23 @@ public class MethodAnalyzer implements Scope, ClassDeclarer {
return getParent().getClassAnalyzer(cinfo);
}
public GenericParameterType getGenericType(String name) {
if (genericTypes != null) {
for (int i = 0; i < genericTypes.length; i++) {
if (genericTypes[i].getClassName().equals(name))
return genericTypes[i];
}
}
return getParent().getGenericType(name);
}
/**
* Gets the current class path.
*/
public ClassPath getClassPath() {
return classAnalyzer.getClassPath();
}
public void addClassAnalyzer(ClassAnalyzer clazzAna) {
if (innerAnalyzers == null)
innerAnalyzers = new Vector();

@ -20,9 +20,12 @@
package net.sf.jode.decompiler;
import net.sf.jode.type.Type;
import net.sf.jode.type.IntegerType;
import net.sf.jode.type.MethodType;
import net.sf.jode.expr.*;
import net.sf.jode.flow.*;
import net.sf.jode.bytecode.*;
import java.io.*;
import java.util.Vector;
/**
* This is an abstract class which creates flow blocks for the
@ -84,6 +87,12 @@ public abstract class Opcodes implements net.sf.jode.bytecode.Opcodes {
return new SpecialBlock(type, stackcount, param);
}
private static StructuredBlock createGoto(MethodAnalyzer ma,
Instruction instr)
{
return new EmptyBlock();
}
private static StructuredBlock createJsr(MethodAnalyzer ma,
Instruction instr)
{
@ -143,7 +152,10 @@ public abstract class Opcodes implements net.sf.jode.bytecode.Opcodes {
if (instr.getConstant() instanceof Reference) {
Reference ref = (Reference) instr.getConstant();
expr = new ClassFieldOperator
(Type.tType(cp, ref.getClazz()));
(Type.tType(ma.getClassPath(), null, ref.getType()),
Type.tType(ma.getClassPath(), null, ref.getClazz()));
} else if (instr.getConstant() instanceof String) {
expr = new ConstOperator(cp, (String) instr.getConstant());
} else {
expr = new ConstOperator(instr.getConstant());
}

@ -35,7 +35,7 @@ public class Options {
public static int options =
OPTION_LVT | OPTION_INNER | OPTION_ANON | OPTION_PRETTY |
OPTION_DECRYPT | OPTION_VERIFY | OPTION_CONTRAFO | OPTION_PUSH;
OPTION_DECRYPT | OPTION_VERIFY | OPTION_CONTRAFO;
public final static boolean doAnonymous() {
return (options & OPTION_ANON) != 0;

@ -23,6 +23,7 @@ import net.sf.jode.expr.Expression;
import net.sf.jode.expr.ThisOperator;
import net.sf.jode.expr.LocalLoadOperator;
import net.sf.jode.expr.OuterLocalOperator;
import net.sf.jode.util.SimpleMap;
import net.sf.jode.type.Type;
import java.util.Vector;
@ -323,6 +324,13 @@ public class OuterValues
implicitOuterClass = value;
}
private static int countSlots(Expression[] exprs, int length) {
int slots = 0;
for (int i=0; i < length; i++)
slots += exprs[i].getType().stackSize();
return slots;
}
public void setMinCount(int newMin) {
if (headCount < newMin) {
GlobalOptions.err.println

@ -22,6 +22,7 @@ import java.io.*;
import java.util.Stack;
import java.util.Vector;
import java.util.Enumeration;
import net.sf.jode.GlobalOptions;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.type.*;
@ -41,7 +42,6 @@ public class TabbedPrintWriter {
public static final int BRACE_AT_EOL = 0x10;
public static final int INDENT_BRACES = 0x20;
public static final int GNU_SPACING = 0x40;
public static final int CODD_FORMATTING = 0x80; // allow trailing CLOSING braces as well
/**
* This string contains a few tab characters followed by tabWidth - 1
@ -72,18 +72,19 @@ public class TabbedPrintWriter {
indent -= tabs * tabWidth;
if (tabs <= FASTINDENT) {
/* The fast way. */
return tabSpaceString.substring(FASTINDENT - tabs,
return tabSpaceString.substring(FASTINDENT - tabs,
FASTINDENT + indent);
}
/* the not so fast way */
StringBuffer sb = new StringBuffer(tabs + indent);
while (tabs > FASTINDENT) {
sb.append(tabSpaceString.substring(0, FASTINDENT));
tabs -= 20;
}
sb.append(tabSpaceString.substring(FASTINDENT - tabs,
FASTINDENT + indent));
return sb.toString();
} else {
/* the not so fast way */
StringBuffer sb = new StringBuffer(tabs + indent);
while (tabs > FASTINDENT) {
sb.append(tabSpaceString.substring(0, FASTINDENT));
tabs -= 20;
}
sb.append(tabSpaceString.substring(FASTINDENT - tabs,
FASTINDENT + indent));
return sb.toString();
}
}
class BreakPoint {
@ -459,10 +460,7 @@ public class TabbedPrintWriter {
public TabbedPrintWriter (OutputStream os, ImportHandler imports,
boolean autoFlush, int style,
int indentSize, int tabWidth, int lineWidth) {
if ((style & CODD_FORMATTING) != 0)
pw = new PrintWriter(new NlRemover(new OutputStreamWriter(os), tabWidth), autoFlush);
else
pw = new PrintWriter(os, autoFlush);
pw = new PrintWriter(os, autoFlush);
this.imports = imports;
this.style = style;
this.indentsize = indentSize;
@ -471,11 +469,10 @@ public class TabbedPrintWriter {
init();
}
public TabbedPrintWriter (Writer os, ImportHandler imports, boolean autoFlush, int style, int indentSize, int tabWidth, int lineWidth) {
if ((style & CODD_FORMATTING) != 0)
pw = new PrintWriter(new NlRemover(os, tabWidth), autoFlush);
else {
pw = new PrintWriter(os, autoFlush); }
public TabbedPrintWriter (Writer os, ImportHandler imports,
boolean autoFlush, int style,
int indentSize, int tabWidth, int lineWidth) {
pw = new PrintWriter(os, autoFlush);
this.imports = imports;
this.style = style;
this.indentsize = indentSize;
@ -495,19 +492,19 @@ public class TabbedPrintWriter {
}
public TabbedPrintWriter (OutputStream os, ImportHandler imports) {
this(os, imports, true);
this(os, imports, true, BRACE_AT_EOL, 4, 8, 79);
}
public TabbedPrintWriter (Writer os, ImportHandler imports) {
this(os, imports, true);
this(os, imports, true, BRACE_AT_EOL, 4, 8, 79);
}
public TabbedPrintWriter (OutputStream os) {
this(os, null);
this(os, null, true, BRACE_AT_EOL, 4, 8, 79);
}
public TabbedPrintWriter (Writer os) {
this(os, null);
this(os, null, true, BRACE_AT_EOL, 4, 8, 79);
}
private void init() {
@ -519,7 +516,7 @@ public class TabbedPrintWriter {
private void initTabString() {
char tabChar = '\t';
if (tabWidth <= 1) {
if (tabWidth == 0) {
/* If tabWidth is 0 use spaces instead of tabs. */
tabWidth = 1;
tabChar = ' ';
@ -622,6 +619,29 @@ public class TabbedPrintWriter {
print(getTypeString(type));
}
public void printExtendsImplements(ClassType clazz) {
ClassType superClazz = clazz.getSuperClass();
if (superClazz != null &&
superClazz.getClassName() != "java.lang.Object") {
breakOp();
print(" extends " + getTypeString(superClazz));
}
ClassType[] interfaces = clazz.getInterfaces();
if (interfaces.length > 0) {
breakOp();
print(clazz.isInterface() ? " extends " : " implements ");
startOp(EXPL_PAREN, 1);
for (int i=0; i < interfaces.length; i++) {
if (i > 0) {
print(", ");
breakOp();
}
print(getTypeString(interfaces[i]));
}
endOp();
}
}
public void pushScope(Scope scope) {
scopes.push(scope);
}
@ -693,7 +713,8 @@ public class TabbedPrintWriter {
if (scope != null)
return "NAME CONFLICT " + className;
return "UNREACHABLE " + className;
else
return "UNREACHABLE " + className;
}
if (imports != null) {
String importedName = imports.getClassString(clazz);
@ -710,8 +731,21 @@ public class TabbedPrintWriter {
if (type instanceof ArrayType)
return getTypeString(((ArrayType) type).getElementType()) + "[]";
else if (type instanceof ClassInfoType) {
ClassInfo clazz = ((ClassInfoType) type).getClassInfo();
return getClassString(clazz, Scope.CLASSNAME);
ClassInfoType classInfoType = (ClassInfoType) type;
ClassInfo clazz = classInfoType.getClassInfo();
String clazzName = getClassString(clazz, Scope.CLASSNAME);
Type[] genInstances = classInfoType.getGenericInstances();
if (genInstances == null)
return clazzName;
StringBuffer sb = new StringBuffer(clazzName);
sb.append("<");
for (int i = 0; i < genInstances.length; i++) {
if (i > 0)
sb.append(",");
sb.append(getTypeString(genInstances[i]));
}
sb.append(">");
return sb.toString();
} else if (type instanceof ClassType) {
String name = ((ClassType) type).getClassName();
if (imports != null) {
@ -793,7 +827,7 @@ public class TabbedPrintWriter {
}
public void closeBraceContinue() {
if ((style & (BRACE_AT_EOL|CODD_FORMATTING)) == BRACE_AT_EOL)
if ((style & BRACE_AT_EOL) != 0)
print("} ");
else
println("}");
@ -825,84 +859,3 @@ public class TabbedPrintWriter {
pw.close();
}
}
class NlRemover extends Writer {
private int tabWidth;
private Writer out;
private int pendingNL;
private boolean lastWasClBr;
private int pendingSpace;
public NlRemover(Writer to, int tabWidth) {
this.out = to;
this.tabWidth = tabWidth; }
public void close() throws IOException {
if (out != null) {
while (pendingNL > 0) {
out.write('\n');
pendingNL--;
}
out.close();
out = null;
}
}
public void flush() throws IOException {
if (out != null) {
while (pendingNL > 0) {
out.write('\n');
pendingNL--;
}
out.flush();
}
}
public void write(int x) throws IOException {
switch ((char)x) {
case '}':
if (! lastWasClBr && pendingSpace > 0)
out.write(' ');
out.write('}');
pendingSpace = 0;
pendingNL = 0;
lastWasClBr = true;
return;
case '\r':
pendingSpace = 0;
return;
case '\n':
if (pendingNL > 0) {
out.write('\n'); }
else
pendingNL++;
pendingSpace = 0;
return;
case '\t':
pendingSpace = (pendingSpace + tabWidth) / tabWidth * tabWidth;
return;
case ' ':
pendingSpace += 1;
return;
default:
while (pendingNL > 0) {
out.write('\n');
pendingNL--;
}
while (pendingSpace > 0) {
out.write(' ');
pendingSpace--;
}
out.write(x);
lastWasClBr = false;
}
}
public void write(char[] cbuf, int off, int len) throws IOException {
len+=off;
while (off < len)
write(cbuf[off++]);
}
}

@ -18,6 +18,7 @@
*/
package net.sf.jode.decompiler;
import java.applet.*;
import java.awt.*;
///#ifndef AWT10
import java.awt.event.*;
@ -181,7 +182,7 @@ public class Window
FileDialog.SAVE);
fd.setFile(lastClassName.substring
(lastClassName.lastIndexOf('.')+1).concat(".java"));
fd.setVisible(true);
fd.show();
String fileName = fd.getFile();
if (fileName == null)
return;
@ -301,6 +302,6 @@ public class Window
});
///#endif
frame.pack();
frame.setVisible(true);
frame.show();
}
}

@ -41,7 +41,7 @@ public class ArrayStoreOperator extends ArrayLoadOperator
if (!elemType.isOfType(getType())) {
/* We need an explicit widening cast */
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 1);
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(Type.tArray(getType().getHint()));
writer.print(") ");

@ -19,13 +19,14 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class ClassFieldOperator extends NoArgOperator {
Type classType;
public ClassFieldOperator(Type classType) {
super(Type.tJavaLangClass);
public ClassFieldOperator(Type javaLangClass, Type classType) {
super(javaLangClass);
this.classType = classType;
}

@ -18,6 +18,7 @@
*/
package net.sf.jode.expr;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.type.Type;
import net.sf.jode.type.IntegerType;
import net.sf.jode.util.StringQuoter;
@ -32,6 +33,11 @@ public class ConstOperator extends NoArgOperator {
| IntegerType.IT_Z
| IntegerType.IT_S | IntegerType.IT_B);
public ConstOperator(ClassPath cp, String constant) {
super(Type.tClass(cp, "java.lang.String"));
value = constant;
}
public ConstOperator(Object constant) {
super(Type.tUnknown);
if (constant instanceof Boolean) {
@ -60,8 +66,6 @@ public class ConstOperator extends NoArgOperator {
updateParentType(Type.tFloat);
else if (constant instanceof Double)
updateParentType(Type.tDouble);
else if (constant instanceof String)
updateParentType(Type.tString);
else if (constant == null)
updateParentType(Type.tUObject);
else
@ -129,7 +133,7 @@ public class ConstOperator extends NoArgOperator {
if (type.getHint().equals(Type.tChar)) {
char c = (char) ((Integer) value).intValue();
return StringQuoter.quote(c);
} else if (type.equals(Type.tString)) {
} else if (value instanceof String) {
return StringQuoter.quote(strVal);
} else if (parent != null) {
int opindex = parent.getOperatorIndex();

@ -204,8 +204,6 @@ public abstract class Expression {
return this;
}
public static Expression EMPTYSTRING = new ConstOperator("");
public Expression simplifyStringBuffer() {
return null;
}
@ -239,6 +237,7 @@ public abstract class Expression {
public void dumpExpression(TabbedPrintWriter writer, int minPriority)
throws java.io.IOException {
int options;
boolean needParen1 = false, needParen2 = false;
boolean needEndOp1 = false, needEndOp2 = false;
@ -255,10 +254,10 @@ public abstract class Expression {
needParen1 = true;
needEndOp1 = true;
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
} else if (minPriority < 700) {
needEndOp1 = true;
writer.startOp(TabbedPrintWriter.IMPL_PAREN, 1);
writer.startOp(writer.IMPL_PAREN, 1);
}
writer.print(typecast);
writer.breakOp();
@ -271,13 +270,13 @@ public abstract class Expression {
needParen2 = true;
needEndOp2 = true;
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, getBreakPenalty());
writer.startOp(writer.EXPL_PAREN, getBreakPenalty());
} else if (priority != minPriority) {
needEndOp2 = true;
if (getType() == Type.tVoid)
writer.startOp(TabbedPrintWriter.NO_PAREN, getBreakPenalty());
writer.startOp(writer.NO_PAREN, getBreakPenalty());
else
writer.startOp(TabbedPrintWriter.IMPL_PAREN, 1 + getBreakPenalty());
writer.startOp(writer.IMPL_PAREN, 1 + getBreakPenalty());
}
try {

@ -18,6 +18,7 @@
*/
package net.sf.jode.expr;
import net.sf.jode.GlobalOptions;
import net.sf.jode.type.Type;
import net.sf.jode.type.NullType;
import net.sf.jode.type.ClassInfoType;
@ -28,6 +29,7 @@ import net.sf.jode.bytecode.Reference;
import net.sf.jode.bytecode.TypeSignature;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.FieldAnalyzer;
import net.sf.jode.decompiler.Options;
import net.sf.jode.decompiler.TabbedPrintWriter;
@ -60,8 +62,8 @@ public abstract class FieldOperator extends Operator {
this.methodAnalyzer = methodAnalyzer;
this.staticFlag = staticFlag;
this.type = Type.tType(classPath, ref.getType());
this.classType = Type.tType(classPath, ref.getClazz());
this.type = Type.tType(methodAnalyzer, ref.getType());
this.classType = Type.tType(methodAnalyzer, ref.getClazz());
this.ref = ref;
if (staticFlag)
methodAnalyzer.useType(classType);
@ -117,7 +119,7 @@ public abstract class FieldOperator extends Operator {
while (true) {
if (clazz == ana.getClazz()) {
int field = ana.getFieldIndex
(ref.getName(), Type.tType(classPath, ref.getType()));
(ref.getName(), Type.tType(methodAnalyzer, ref.getType()));
if (field >= 0)
return ana.getField(field);
return null;
@ -141,12 +143,27 @@ public abstract class FieldOperator extends Operator {
}
public Type getFieldType() {
return Type.tType(classPath, ref.getType());
return Type.tType(methodAnalyzer, ref.getType());
}
private void loadFields(ClassInfo clazz) {
int howMuch = (clazz.getName().startsWith(callerPackage)
&& (clazz.getName().lastIndexOf('.')
< callerPackage.length()))
? ClassInfo.DECLARATIONS : ClassInfo.PUBLICDECLARATIONS;
try {
clazz.load(howMuch);
} catch (IOException ex) {
GlobalOptions.err.println("Warning: Can't find fields of "
+clazz+" to detect hiding conflicts");
clazz.guess(howMuch);
}
}
private static FieldInfo getFieldInfo(ClassInfo clazz,
String name, String type) {
private FieldInfo getFieldInfo(ClassInfo clazz,
String name, String type) {
while (clazz != null) {
loadFields(clazz);
FieldInfo field = clazz.findField(name, type);
if (field != null)
return field;
@ -164,14 +181,14 @@ public abstract class FieldOperator extends Operator {
}
public FieldInfo getFieldInfo() {
ClassInfo clazz;
if (ref.getClazz().charAt(0) == '[')
clazz = classPath.getClassInfo("java.lang.Object");
else
clazz = TypeSignature.getClassInfo(classPath, ref.getClazz());
return getFieldInfo(clazz, ref.getName(), ref.getType());
return getFieldInfo(classInfo, ref.getName(), ref.getType());
}
/**
* Checks if we need a cast to the super class, to which the field
* belongs.
* @param type the canonic type of the zeroth subexpression.
*/
public boolean needsCast(Type type) {
if (type instanceof NullType)
return true;
@ -179,46 +196,43 @@ public abstract class FieldOperator extends Operator {
&& classType instanceof ClassInfoType))
return false;
ClassInfo clazz = ((ClassInfoType) classType).getClassInfo();
ClassInfo parClazz = ((ClassInfoType) type).getClassInfo();
FieldInfo field = clazz.findField(ref.getName(), ref.getType());
find_field:
while (field == null) {
ClassInfo ifaces[] = clazz.getInterfaces();
for (int i = 0; i < ifaces.length; i++) {
field = ifaces[i].findField(ref.getName(), ref.getType());
if (field != null)
break find_field;
}
clazz = clazz.getSuperclass();
if (clazz == null)
/* Weird, field not existing? */
return false;
field = clazz.findField(ref.getName(), ref.getType());
ClassInfo subexprClass = ((ClassInfoType) type).getClassInfo();
FieldInfo field = getFieldInfo();
if (field == null) {
/* Weird, field not existing? */
return false;
}
/**
* We need an explicit cast if we access a private field
* of a parent class (which is only possible if the parent
* class is an outer class of the current class).
*/
if (Modifier.isPrivate(field.getModifiers()))
return parClazz != clazz;
return subexprClass != classInfo;
else if ((field.getModifiers()
& (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
/* Field is protected. We need a cast if parClazz is in
* other package than clazz.
/* Field is protected. We need a cast if subexprClass is in
* other package than classInfo.
*/
int lastDot = clazz.getName().lastIndexOf('.');
int lastDot = classInfo.getName().lastIndexOf('.');
if (lastDot == -1
|| lastDot != parClazz.getName().lastIndexOf('.')
|| !(parClazz.getName()
.startsWith(clazz.getName().substring(0,lastDot))))
|| lastDot != subexprClass.getName().lastIndexOf('.')
|| !(subexprClass.getName()
.startsWith(classInfo.getName().substring(0,lastDot))))
return true;
}
while (clazz != parClazz && clazz != null) {
FieldInfo[] fields = parClazz.getFields();
/* We also need an explicit cast if the field is hidden by a
* declaration in param class.
*/
while (classInfo != subexprClass && classInfo != null) {
FieldInfo[] fields = subexprClass.getFields();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName().equals(ref.getName()))
return true;
}
parClazz = parClazz.getSuperclass();
subexprClass = subexprClass.getSuperclass();
}
return false;
}
@ -258,10 +272,9 @@ public abstract class FieldOperator extends Operator {
writer.breakOp();
writer.print(".");
}
writer.print(fieldName);
} else if (needsCast(subExpressions[0].getType().getCanonic())) {
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 1);
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(classType);
writer.print(") ");
@ -271,36 +284,33 @@ public abstract class FieldOperator extends Operator {
writer.print(")");
writer.breakOp();
writer.print(".");
writer.print(fieldName);
} else {
if (opIsThis) {
ThisOperator thisOp = (ThisOperator) subExpressions[0];
Scope scope = writer.getScope(thisOp.getClassInfo(),
Scope.CLASSSCOPE);
if (scope == null || writer.conflicts(fieldName, scope,
Scope.FIELDNAME)) {
thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print(".");
} else if (writer.conflicts(fieldName, scope,
} else if (opIsThis) {
ThisOperator thisOp = (ThisOperator) subExpressions[0];
Scope scope = writer.getScope(thisOp.getClassInfo(),
Scope.CLASSSCOPE);
if (scope == null || writer.conflicts(fieldName, scope,
Scope.FIELDNAME)) {
thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print(".");
} else if (writer.conflicts(fieldName, scope,
Scope.AMBIGUOUSNAME)
|| (/* This is a inherited field conflicting
* with a field name in some outer class.
*/
getField() == null
&& writer.conflicts(fieldName, null,
Scope.NOSUPERFIELDNAME))) {
thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print(".");
}
} else {
subExpressions[0].dumpExpression(writer, 950);
|| (/* This is a inherited field conflicting
* with a field name in some outer class.
*/
getField() == null
&& writer.conflicts(fieldName, null,
Scope.NOSUPERFIELDNAME))) {
thisOp.dumpExpression(writer, 950);
writer.breakOp();
writer.print(".");
}
writer.print(fieldName);
} else {
subExpressions[0].dumpExpression(writer, 950);
writer.breakOp();
writer.print(".");
}
writer.print(fieldName);
}
}

@ -19,6 +19,7 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class IIncOperator extends Operator

@ -76,6 +76,7 @@ public class IfThenElseOperator extends Operator {
= (GetFieldOperator) subExpressions[2 - cmpType];
StoreInstruction put
= (StoreInstruction) subExpressions[1 + cmpType];
int opIndex = cmp.getOperatorIndex();
FieldAnalyzer field;
if (put.getLValue() instanceof PutFieldOperator
&& ((field = ((PutFieldOperator)put.getLValue())
@ -97,8 +98,9 @@ public class IfThenElseOperator extends Operator {
ClassPath cp = field.getClassAnalyzer().getClassPath();
if (field.setClassConstant(clazz))
return new ClassFieldOperator
(clazz.charAt(0) == '['
? Type.tType(cp, clazz)
(invoke.getType(),
clazz.charAt(0) == '['
? Type.tType(field.getClassAnalyzer(), clazz)
: Type.tClass(cp, clazz));
}
}
@ -119,7 +121,7 @@ public class IfThenElseOperator extends Operator {
int subPriority = 0;
if (!subExpressions[1].getType().getHint().isOfType
(subExpressions[2].getType())) {
writer.startOp(TabbedPrintWriter.IMPL_PAREN, 2);
writer.startOp(writer.IMPL_PAREN, 2);
/* We need a cast here */
writer.print("(");
writer.printType(getType().getHint());

@ -51,7 +51,7 @@ public class InstanceOfOperator extends Operator {
Type superType
= instanceType.getCastHelper(subExpressions[0].getType());
if (superType != null) {
writer.startOp(TabbedPrintWriter.IMPL_PAREN, 2);
writer.startOp(writer.IMPL_PAREN, 2);
writer.print("(");
writer.printType(superType);
writer.print(") ");

@ -20,6 +20,7 @@
package net.sf.jode.expr;
import java.lang.reflect.Modifier;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.TabbedPrintWriter;
@ -39,6 +40,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
///#enddef
@ -153,10 +155,12 @@ public final class InvokeOperator extends Operator
super(Type.tUnknown, 0);
this.classPath = methodAnalyzer.getClassAnalyzer().getClassPath();
this.ref = reference;
this.methodType = Type.tMethod(classPath, reference.getType());
//TODO: generics
this.methodType = Type.tMethod(methodAnalyzer.getClassPath(),
null, reference.getType(), null);
this.methodName = reference.getName();
this.classType = (ClassType)
Type.tType(classPath, reference.getClazz());
Type.tType(methodAnalyzer.getClassPath(), null, reference.getClazz());
this.hints = null;
Map allHints = (Map) hintTypes.get(methodName+"."+methodType);
if (allHints != null) {
@ -216,9 +220,9 @@ public final class InvokeOperator extends Operator
String name, String type) {
while (clazz != null) {
try {
clazz.load(ClassInfo.DECLARATIONS);
clazz.load(clazz.DECLARATIONS);
} catch (IOException ex) {
clazz.guess(ClassInfo.DECLARATIONS);
clazz.guess(clazz.DECLARATIONS);
}
MethodInfo method = clazz.findMethod(name, type);
if (method != null)
@ -413,7 +417,7 @@ public final class InvokeOperator extends Operator
* Checks, whether this is a call of a method from the super class.
*/
public boolean isSuperOrThis() {
return classType.maybeSubTypeOf
return classType.maybeSuperTypeOf
(Type.tClass(methodAnalyzer.getClazz()));
}
@ -513,7 +517,7 @@ public final class InvokeOperator extends Operator
}
return null;
}
return new ConstOperator(result);
return new ConstOperator(classPath, result);
}
public Expression simplifyStringBuffer() {
@ -522,7 +526,7 @@ public final class InvokeOperator extends Operator
if (isConstructor()
&& subExpressions[0] instanceof NewOperator) {
if (methodType.getParameterTypes().length == 0)
return EMPTYSTRING;
return emptyString();
if (methodType.getParameterTypes().length == 1
&& methodType.getParameterTypes()[0].equals(Type.tString))
return subExpressions[1].simplifyString();
@ -538,14 +542,14 @@ public final class InvokeOperator extends Operator
subExpressions[1] = subExpressions[1].simplifyString();
if (firstOp == EMPTYSTRING
if (isEmptyString(firstOp)
&& subExpressions[1].getType().isOfType(Type.tString))
return subExpressions[1];
if (firstOp instanceof StringAddOperator
&& (((Operator)firstOp).getSubExpressions()[0]
== EMPTYSTRING))
firstOp = ((Operator)firstOp).getSubExpressions()[1];
&& isEmptyString(((Operator) firstOp)
.getSubExpressions()[0]))
firstOp = ((Operator) firstOp).getSubExpressions()[1];
Expression secondOp = subExpressions[1];
Type[] paramTypes = new Type[] {
@ -566,6 +570,15 @@ public final class InvokeOperator extends Operator
return null;
}
public boolean isEmptyString(Expression expr) {
return (expr instanceof ConstOperator
&& ((ConstOperator) expr).getValue() == "");
}
public ConstOperator emptyString() {
return new ConstOperator(classPath, "");
}
public Expression simplifyString() {
if (getMethodName().equals("toString")
&& !isStatic()
@ -586,7 +599,7 @@ public final class InvokeOperator extends Operator
Operator op = new StringAddOperator();
op.addOperand(subExpressions[0]);
op.addOperand(EMPTYSTRING);
op.addOperand(emptyString());
}
/* The pizza way (pizza is the compiler of kaffe) */
else if (getMethodName().equals("concat")
@ -598,7 +611,7 @@ public final class InvokeOperator extends Operator
if (right instanceof StringAddOperator) {
Operator op = (Operator) right;
if (op.subExpressions != null
&& op.subExpressions[0] == EMPTYSTRING)
&& isEmptyString(op.subExpressions[0]))
right = op.subExpressions[1];
}
result.addOperand(right);
@ -640,7 +653,7 @@ public final class InvokeOperator extends Operator
op = new StoreInstruction
(new PutFieldOperator(methodAnalyzer, false,
synth.getReference()));
if (synth.getKind() == SyntheticAnalyzer.ACCESSDUPPUTFIELD)
if (synth.getKind() == synth.ACCESSDUPPUTFIELD)
((StoreInstruction) op).makeNonVoid();
break;
case SyntheticAnalyzer.ACCESSPUTSTATIC:
@ -648,7 +661,7 @@ public final class InvokeOperator extends Operator
op = new StoreInstruction
(new PutFieldOperator(methodAnalyzer, true,
synth.getReference()));
if (synth.getKind() == SyntheticAnalyzer.ACCESSDUPPUTSTATIC)
if (synth.getKind() == synth.ACCESSDUPPUTSTATIC)
((StoreInstruction) op).makeNonVoid();
break;
case SyntheticAnalyzer.ACCESSMETHOD:
@ -762,8 +775,10 @@ public final class InvokeOperator extends Operator
/* method name doesn't match*/
continue next_method;
// TODO Generics
Type[] otherParamTypes
= Type.tMethod(classPath, methods[i].getType())
= Type.tMethod(methodAnalyzer.getClassPath(), null,
methods[i].getSignature(), null)
.getParameterTypes();
if (otherParamTypes.length != myParamTypes.length) {
/* parameter count doesn't match*/
@ -946,7 +961,7 @@ public final class InvokeOperator extends Operator
* we have to differentiate all kinds of method calls: static,
* virtual, constructor, anonymous constructors, super calls etc.
*/
writer.startOp(TabbedPrintWriter.NO_PAREN, 0);
writer.startOp(writer.NO_PAREN, 0);
switch (methodFlag) {
case CONSTRUCTOR: {
@ -1038,7 +1053,7 @@ public final class InvokeOperator extends Operator
if (outerExpr.getType().getCanonic()
instanceof NullType) {
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 1);
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(Type.tClass(clazz));
writer.print(") ");
@ -1076,7 +1091,7 @@ public final class InvokeOperator extends Operator
}
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
writer.print("(UNCONSTRUCTED)");
writer.breakOp();
subExpressions[0].dumpExpression(writer, 700);
@ -1146,7 +1161,7 @@ public final class InvokeOperator extends Operator
subExpressions[0].dumpExpression(writer, 950);
else {
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
writer.print("(");
writer.printType(classType);
writer.print(") ");
@ -1197,7 +1212,7 @@ public final class InvokeOperator extends Operator
} else {
if (needsCast(0, paramTypes)){
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 1);
writer.startOp(writer.EXPL_PAREN, 1);
writer.print("(");
writer.printType(classType);
writer.print(") ");
@ -1221,7 +1236,7 @@ public final class InvokeOperator extends Operator
writer.breakOp();
writer.printOptionalSpace();
writer.print("(");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
boolean first = true;
int offset = skippedArgs;
while (arg < length) {
@ -1233,7 +1248,7 @@ public final class InvokeOperator extends Operator
int priority = 0;
if (needsCast(arg, paramTypes)) {
Type castType = methodType.getParameterTypes()[arg-offset];
writer.startOp(TabbedPrintWriter.IMPL_PAREN, 1);
writer.startOp(writer.IMPL_PAREN, 1);
writer.print("(");
writer.printType(castType);
writer.print(") ");

@ -18,6 +18,9 @@
*/
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.GlobalOptions;
import net.sf.jode.decompiler.TabbedPrintWriter;
public interface LValueExpression extends MatchableOperator {
}

@ -18,9 +18,12 @@
*/
package net.sf.jode.expr;
import net.sf.jode.GlobalOptions;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class LocalLoadOperator extends LocalVarOperator {

@ -18,8 +18,10 @@
*/
package net.sf.jode.expr;
import net.sf.jode.GlobalOptions;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class LocalStoreOperator extends LocalVarOperator
implements LValueExpression {

@ -19,6 +19,7 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.TabbedPrintWriter;
public abstract class NoArgOperator extends Operator {

@ -19,6 +19,7 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.GlobalOptions;
import net.sf.jode.decompiler.TabbedPrintWriter;
///#def COLLECTIONS java.util
@ -133,7 +134,7 @@ public abstract class Operator extends Expression {
- subExpressions[i].getFreeOperandCount();
subExpressions[i] = expr;
expr.parent = this;
for (Operator ce = this; ce != null; ce = ce.parent)
for (Operator ce = this; ce != null; ce = (Operator) ce.parent)
ce.operandcount += diff;
updateType();
}
@ -220,6 +221,7 @@ public abstract class Operator extends Expression {
* is not a CombineableOperator.
*/
public boolean containsMatchingLoad(CombineableOperator comb) {
Operator combOp = (Operator) comb;
if (comb.getLValue().matches(this)) {
if (subsEquals((Operator) comb.getLValue()))
return true;

@ -19,6 +19,9 @@
package net.sf.jode.expr;
import net.sf.jode.GlobalOptions;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.decompiler.TabbedPrintWriter;

@ -52,6 +52,7 @@ public class PrePostFixOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
boolean needBrace = false;
int priority = 700;
if (!postfix) {
writer.print(getOperatorString());

@ -20,6 +20,7 @@
package net.sf.jode.expr;
import net.sf.jode.bytecode.Reference;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.FieldAnalyzer;
public class PutFieldOperator extends FieldOperator
implements LValueExpression {

@ -19,6 +19,7 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.GlobalOptions;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class StoreInstruction extends Operator
@ -72,6 +73,9 @@ public class StoreInstruction extends Operator
}
public void updateType() {
Type newType;
if (!opAssign) {
/* An opassign (+=, -=, etc.) doesn't merge rvalue type. */
Type lvalueType = subExpressions[0].getType();

@ -48,13 +48,6 @@ public class StringAddOperator extends Operator {
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
if (!subExpressions[0].getType().isOfType(Type.tString)
&& !subExpressions[1].getType().isOfType(Type.tString)) {
writer.print("\"\"");
writer.breakOp();
writer.print(getOperatorString());
}
subExpressions[0].dumpExpression(writer, 610);
writer.breakOp();
writer.print(getOperatorString());

@ -20,25 +20,30 @@
package net.sf.jode.expr;
import net.sf.jode.type.Type;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.Scope;
import net.sf.jode.decompiler.TabbedPrintWriter;
public class ThisOperator extends NoArgOperator {
boolean isInnerMost;
ClassInfo classInfo;
ClassAnalyzer classAna;
public ThisOperator(ClassInfo classInfo, boolean isInnerMost) {
super(Type.tClass(classInfo));
this.classInfo = classInfo;
public ThisOperator(ClassAnalyzer classAna, boolean isInnerMost) {
super(classAna.getType());
this.classAna = classAna;
this.isInnerMost = isInnerMost;
}
public ThisOperator(ClassInfo classInfo) {
this(classInfo, false);
public ThisOperator(ClassAnalyzer classAna) {
this(classAna, false);
}
public ClassInfo getClassInfo() {
return classInfo;
return classAna.getClazz();
}
public ClassAnalyzer getClassAnalyzer() {
return classAna;
}
public int getPriority() {
@ -46,18 +51,18 @@ public class ThisOperator extends NoArgOperator {
}
public String toString() {
return classInfo+".this";
return classAna+".this";
}
public boolean opEquals(Operator o) {
return (o instanceof ThisOperator &&
((ThisOperator) o).classInfo.equals(classInfo));
((ThisOperator) o).classAna == classAna);
}
public void dumpExpression(TabbedPrintWriter writer)
throws java.io.IOException {
if (!isInnerMost) {
writer.print(writer.getClassString(classInfo,
writer.print(writer.getClassString(getClassInfo(),
Scope.AMBIGUOUSNAME));
writer.print(".");
}

@ -18,6 +18,7 @@
*/
package net.sf.jode.flow;
import net.sf.jode.decompiler.TabbedPrintWriter;
/**
* This is a structured block, that supports break.

@ -25,8 +25,8 @@ import net.sf.jode.expr.Expression;
import net.sf.jode.expr.LocalLoadOperator;
import net.sf.jode.expr.LocalStoreOperator;
import net.sf.jode.expr.NopOperator;
import net.sf.jode.expr.Operator;
import net.sf.jode.expr.StoreInstruction;
import net.sf.jode.util.SimpleSet;
///#def COLLECTIONS java.util
import java.util.Collections;
@ -223,7 +223,7 @@ public class CatchBlock extends StructuredBlock {
((InstructionBlock) firstInstr).getInstruction();
if (instr instanceof StoreInstruction) {
StoreInstruction store = (StoreInstruction) instr;
if (store.getOperatorIndex() == Operator.OPASSIGN_OP
if (store.getOperatorIndex() == store.OPASSIGN_OP
&& store.getSubExpressions()[1] instanceof NopOperator
&& store.getLValue() instanceof LocalStoreOperator) {
/* The exception is stored in a local variable */

@ -18,6 +18,7 @@
*/
package net.sf.jode.flow;
import java.util.Vector;
import net.sf.jode.expr.*;
import net.sf.jode.type.Type;

@ -20,6 +20,7 @@
package net.sf.jode.flow;
import net.sf.jode.decompiler.TabbedPrintWriter;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.LocalVarOperator;
/**
* An ConditionalBlock is the structured block representing an if
@ -35,6 +36,8 @@ public class ConditionalBlock extends InstructionContainer {
public void checkConsistent() {
super.checkConsistent();
if (!(trueBlock instanceof EmptyBlock))
throw new InternalError("Inconsistency");
}
/**
@ -120,7 +123,7 @@ public class ConditionalBlock extends InstructionContainer {
throws java.io.IOException
{
writer.print("IF (");
instr.dumpExpression(TabbedPrintWriter.EXPL_PAREN, writer);
instr.dumpExpression(writer.EXPL_PAREN, writer);
writer.println(")");
writer.tab();
trueBlock.dumpSource(writer);

@ -115,7 +115,7 @@ public class CreateAssignExpression {
}
if (expr instanceof BinaryOperator) {
opIndex = expr.getOperatorIndex();
if (opIndex < Operator.ADD_OP || opIndex >= Operator.ASSIGN_OP)
if (opIndex < expr.ADD_OP || opIndex >= expr.ASSIGN_OP)
return false;
if (!(expr.getSubExpressions()[0] instanceof Operator))
@ -126,7 +126,7 @@ public class CreateAssignExpression {
&& loadExpr.getSubExpressions()[0] instanceof Operator)
loadExpr = (Operator) loadExpr.getSubExpressions()[0];
if (!store.lvalueMatches(loadExpr)
if (!store.lvalueMatches((Operator) loadExpr)
|| !(loadExpr.isFreeOperator(lvalueCount)))
return false;
@ -179,7 +179,7 @@ public class CreateAssignExpression {
ib.setInstruction(rightHandSide);
lvalue.setType(rvalueType);
store.makeOpAssign(Operator.OPASSIGN_OP + opIndex);
store.makeOpAssign(store.OPASSIGN_OP + opIndex);
if (isAssignOp)
store.makeNonVoid();

@ -21,6 +21,7 @@ package net.sf.jode.flow;
import net.sf.jode.expr.*;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.LocalInfo;
public class CreateClassField {
@ -73,8 +74,9 @@ public class CreateClassField {
if (put.getField().setClassConstant(clazz)) {
ClassPath cp = invoke.getClassPath();
cmp.setSubExpressions
(0, new ClassFieldOperator(clazz.charAt(0) == '['
? Type.tType(cp, clazz)
(0, new ClassFieldOperator(put.getType(),
clazz.charAt(0) == '['
? Type.tType(invoke.getClassAnalyzer(), clazz)
: Type.tClass(cp, clazz)));
EmptyBlock empty = new EmptyBlock();
empty.moveJump(ifBlock.thenBlock.jump);

@ -20,6 +20,7 @@
package net.sf.jode.flow;
import net.sf.jode.GlobalOptions;
import net.sf.jode.expr.*;
import net.sf.jode.type.Type;
public class CreateConstantArray {

@ -22,6 +22,9 @@ import net.sf.jode.GlobalOptions;
import net.sf.jode.type.Type;
import net.sf.jode.expr.*;
import java.util.Enumeration;
import java.util.Vector;
public class CreateIfThenElseOperator {
/**
@ -52,6 +55,7 @@ public class CreateIfThenElseOperator {
if (block instanceof IfThenElseBlock) {
IfThenElseBlock ifBlock = (IfThenElseBlock) block;
Expression expr1, expr2;
if (ifBlock.elseBlock == null)
return false;
@ -152,15 +156,18 @@ public class CreateIfThenElseOperator {
FlowBlock trueDestination;
FlowBlock falseDestination;
if (compare.getOperatorIndex() == Operator.EQUALS_OP) {
if (compare.getOperatorIndex() == compare.EQUALS_OP) {
trueDestination = cb.jump.destination;
falseDestination = cb.trueBlock.jump.destination;
} else if (compare.getOperatorIndex() == Operator.NOTEQUALS_OP) {
} else if (compare.getOperatorIndex() == compare.NOTEQUALS_OP) {
falseDestination = cb.jump.destination;
trueDestination = cb.trueBlock.jump.destination;
} else
return false;
Expression[] e = new Expression[3];
IfThenElseBlock ifBlock;
SequentialBlock sequBlock = (SequentialBlock) last.outer;
return createFunnyHelper(trueDestination, falseDestination,
sequBlock.subBlocks[0]);

@ -65,9 +65,9 @@ public class CreatePrePostIncExpression {
return false;
int op;
if (iinc.getOperatorIndex() == Operator.ADD_OP + Operator.OPASSIGN_OP)
if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP)
op = Operator.INC_OP;
else if (iinc.getOperatorIndex() == Operator.SUB_OP + Operator.OPASSIGN_OP)
else if (iinc.getOperatorIndex() == iinc.SUB_OP + iinc.OPASSIGN_OP)
op = Operator.DEC_OP;
else
return false;
@ -128,9 +128,9 @@ public class CreatePrePostIncExpression {
ConstOperator constOp = (ConstOperator) binOp.getSubExpressions()[1];
int op;
if (binOp.getOperatorIndex() == Operator.ADD_OP)
if (binOp.getOperatorIndex() == store.ADD_OP)
op = Operator.INC_OP;
else if (binOp.getOperatorIndex() == Operator.SUB_OP)
else if (binOp.getOperatorIndex() == store.SUB_OP)
op = Operator.DEC_OP;
else
return false;

@ -24,8 +24,8 @@ import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.CombineableOperator;
import net.sf.jode.type.Type;
import net.sf.jode.util.SimpleMap;
import net.sf.jode.util.SimpleSet;
///#def COLLECTIONS java.util
import java.util.Map;
@ -168,18 +168,12 @@ public class FlowBlock {
* The gen locals. This are the locals, which can be
* overwritten in this block on a path to the successor. That
* means, that there exists a path form the start of the
* current flow block to the successor that contains an
* current flow block to the successor that contains a
* assignments to this local, and that is not overwritten
* afterwards.
*/
VariableSet gen;
/**
* If this is non-null it contains an array list of all exception types
* for which the successor is the catch block.
*/
ArrayList catched;
/**
* The linked list of jumps.
*/
@ -223,24 +217,7 @@ public class FlowBlock {
/* We will put all jumps that we can not resolve into this
* linked list.
*/
if (jumps == null)
return null;
Jump remainingJumps = null;
/* find the smallest block containing all jumps */
lastModified = jumps.prev;
for (Jump jump = jumps.next; jump != null; jump = jump.next) {
while (!lastModified.contains(jump.prev))
lastModified = lastModified.outer;
}
StructuredBlock b = lastModified.outer;
while (b != null) {
if (b.outer instanceof TryBlock
&& ((TryBlock)b.outer).getSubBlocks()[0] == b) {
lastModified = b.outer;
}
b = b.outer;
}
if (lastModified.jump == null) {
/* This can happen if lastModified is a breakable block, and
@ -265,11 +242,9 @@ public class FlowBlock {
cb.setInstruction(instr.negate());
cb.swapJump(prev);
/* Update lastModified if it happened to be the conditional jump */
if (lastModified == prev)
lastModified = jump.prev;
}
}
next_jump:
while (jumps != null) {
Jump jump = jumps;
jumps = jumps.next;
@ -291,7 +266,7 @@ public class FlowBlock {
ConditionalBlock cb = (ConditionalBlock) prev.outer;
Expression instr = cb.getInstruction();
/* This is a jump inside a ConditionalBlock.
/* This is a jump inside an ConditionalBlock.
*
* cb is the conditional block,
* prev the empty block containing the jump
@ -299,7 +274,7 @@ public class FlowBlock {
if (cb.jump != null) {
/* This can only happen if cb also jumps to succ.
* This is a weird "if (cond) empty"-block. We
* This is a weired "if (cond) empty"-block. We
* transform it by hand.
*/
prev.removeJump();
@ -344,8 +319,6 @@ public class FlowBlock {
loopBlock.setCondition(instr.negate());
loopBlock.moveDefinitions(cb, null);
if (loopBlock.contains(lastModified))
lastModified = loopBlock;
cb.removeBlock();
continue;
}
@ -382,8 +355,6 @@ public class FlowBlock {
loopBlock.setType(LoopBlock.DOWHILE);
loopBlock.setCondition(instr.negate());
loopBlock.moveDefinitions(cb, null);
if (loopBlock.contains(lastModified))
lastModified = loopBlock;
cb.removeBlock();
continue;
}
@ -451,8 +422,8 @@ public class FlowBlock {
/* remove this jump if it jumps to the
* getNextFlowBlock(). */
if (jump.prev.outer != null &&
jump.destination == jump.prev.outer.getNextFlowBlock(jump.prev)) {
if (jump.destination
== jump.prev.outer.getNextFlowBlock(jump.prev)) {
jump.prev.removeJump();
continue;
}
@ -603,13 +574,14 @@ public class FlowBlock {
/**
* Resolve remaining jumps to the successor by generating break
* instructions. As last resort generate a labelled block.
* instructions. As last resort generate a do while(false) block.
* @param jumps The jump list that need to be resolved.
*/
void resolveRemaining(Jump jumps) {
LabelledBlock labelledBlock = null;
LoopBlock doWhileFalse = null;
StructuredBlock outerMost = lastModified;
boolean removeLast = false;
next_jump:
for (; jumps != null; jumps = jumps.next) {
StructuredBlock prevBlock = jumps.prev;
@ -635,18 +607,19 @@ public class FlowBlock {
prevBlock.removeJump();
if (breakToBlock == null) {
/* Nothing else helped, so put a labelled
/* Nothing else helped, so put a do/while(0)
* block around outerMost and break to that
* block.
*/
if (labelledBlock == null) {
labelledBlock = new LabelledBlock();
if (doWhileFalse == null) {
doWhileFalse = new LoopBlock(LoopBlock.DOWHILE,
LoopBlock.FALSE);
}
/* Adapt outermost, so that it contains the break. */
while (!outerMost.contains(prevBlock))
outerMost = outerMost.outer;
prevBlock.appendBlock
(new BreakBlock(labelledBlock, true));
(new BreakBlock(doWhileFalse, breaklevel > 0));
} else
prevBlock.appendBlock
(new BreakBlock(breakToBlock, breaklevel > 1));
@ -655,10 +628,10 @@ public class FlowBlock {
if (removeLast)
lastModified.removeJump();
if (labelledBlock != null) {
labelledBlock.replace(outerMost);
labelledBlock.setBody(outerMost);
lastModified = labelledBlock;
if (doWhileFalse != null) {
doWhileFalse.replace(outerMost);
doWhileFalse.setBody(outerMost);
lastModified = doWhileFalse;
}
}
@ -685,14 +658,10 @@ public class FlowBlock {
} else {
myInfo.gen.addAll(hisInfo.gen);
myInfo.kill.retainAll(hisInfo.kill);
if (myInfo.jumps == null)
myInfo.jumps = hisInfo.jumps;
else {
Jump myJumps = myInfo.jumps;
while (myJumps.next != null)
myJumps = myJumps.next;
myJumps.next = hisInfo.jumps;
}
Jump myJumps = myInfo.jumps;
while (myJumps.next != null)
myJumps = myJumps.next;
myJumps.next = hisInfo.jumps;
}
}
}
@ -993,6 +962,10 @@ public class FlowBlock {
}
public void setSuccessors(FlowBlock[] succs) {
SlotSet blockIn = new SlotSet();
SlotSet blockKill = new SlotSet();
VariableSet blockGen = new VariableSet();
Jump[] jumps = new Jump[succs.length];
for (int i=0; i< succs.length; i++) {
Jump jump = new Jump(succs[i]);
@ -1013,6 +986,7 @@ public class FlowBlock {
}
if (jumps.length > 0)
lastModified.setSuccessors(jumps);
gen = null;
kill = null;
checkConsistent();
}
@ -1033,10 +1007,6 @@ public class FlowBlock {
checkConsistent();
succ.checkConsistent();
/* Merge catching successors */
unifyCatchSuccessors(succ);
succ.unifyCatchSuccessors(this);
if ((GlobalOptions.debuggingFlags
& GlobalOptions.DEBUG_ANALYZE) != 0)
GlobalOptions.err.println
@ -1047,7 +1017,7 @@ public class FlowBlock {
/* Update the in/out-Vectors now */
updateInOut(succ, succInfo.gen, succInfo.kill);
/* Try to eliminate as many jumps as possible.
*/
Jump jumps = resolveSomeJumps(succInfo.jumps, succ);
@ -1108,6 +1078,7 @@ public class FlowBlock {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0)
GlobalOptions.err.println("before remaining: "+this);
next_jump:
for (; jumps != null; jumps = jumps.next) {
StructuredBlock prevBlock = jumps.prev;
@ -1143,8 +1114,7 @@ public class FlowBlock {
/* Now remove the jump of the lastModified if it points to
* END_OF_METHOD.
*/
if (lastModified.jump != null
&& lastModified.jump.destination == END_OF_METHOD)
if (lastModified.jump.destination == END_OF_METHOD)
lastModified.removeJump();
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_FLOW) != 0)
@ -1208,7 +1178,7 @@ public class FlowBlock {
LoopBlock lb =
(LoopBlock) lastModified.outer.getSubBlocks()[0];
if (lb.cond == LoopBlock.FALSE && lb.type == LoopBlock.DOWHILE) {
if (lb.cond == lb.FALSE && lb.type == lb.DOWHILE) {
/* The jump is directly following a
* do-while(false) block
@ -1344,7 +1314,7 @@ public class FlowBlock {
}
/**
* Search for an appropriate successor.
* Search for an apropriate successor.
* @param prevSucc The successor, that was previously tried.
* @param start The minimum blockNr
* @param end The maximum blockNr + 1.
@ -1378,7 +1348,7 @@ public class FlowBlock {
}
/**
* The main analysis. This calls doT1 and doT2 on appropriate
* The main analyzation. This calls doT1 and doT2 on apropriate
* regions. Only blocks whose block number lies in the given block number
* range are considered.
* @param start the start of the block number range.
@ -1472,6 +1442,7 @@ public class FlowBlock {
* block lie in range [start,end). Otherwise
* we have no chance to combine these two blocks.
*/
boolean predOutOfRange = false;
for (Iterator i = succ.predecessors.iterator();
i.hasNext(); ) {
FlowBlock pred = (FlowBlock)i.next();
@ -1915,62 +1886,4 @@ public class FlowBlock {
return super.toString();
}
}
public void addExceptionHandler(Type excType, FlowBlock handler) {
SuccessorInfo info = (SuccessorInfo) successors.get(handler);
if (info == null) {
info = new SuccessorInfo();
info.gen = (VariableSet) gen.clone();
successors.put(handler, info);
handler.predecessors.add(this);
}
info.kill = new SlotSet();
if (info.catched == null)
info.catched = new ArrayList();
info.catched.add(excType);
}
private void unifyCatchSuccessors(FlowBlock succ) {
Iterator iter = successors.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
FlowBlock dest = (FlowBlock) entry.getKey();
SuccessorInfo myInfo = (SuccessorInfo) entry.getValue();
if (myInfo.catched == null)
continue;
SuccessorInfo succInfo = (SuccessorInfo) succ.successors.get(dest);
Iterator catchedIter = myInfo.catched.iterator();
while (catchedIter.hasNext()) {
Type excType = (Type) catchedIter.next();
if (succInfo != null && succInfo.catched != null
&& succInfo.catched.contains(excType))
continue;
if (!(block instanceof TryBlock))
new TryBlock(this);
TryBlock tryBlock = (TryBlock) block;
if (excType != null) {
CatchBlock catchBlock = new CatchBlock(excType);
tryBlock.addCatchBlock(catchBlock);
Jump jump = new Jump(dest);
jump.next = myInfo.jumps;
myInfo.jumps = jump;
lastModified = new EmptyBlock(jump);
catchBlock.setCatchBlock(lastModified);
catchedIter.remove();
} else {
FinallyBlock catchBlock = new FinallyBlock();
tryBlock.addCatchBlock(catchBlock);
Jump jump = new Jump(dest);
jump.next = myInfo.jumps;
myInfo.jumps = jump;
lastModified = new EmptyBlock(jump);
catchBlock.setCatchBlock(lastModified);
catchedIter.remove();
}
}
if (myInfo.catched.isEmpty())
myInfo.catched = null;
}
}
}

@ -18,8 +18,10 @@
*/
package net.sf.jode.flow;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.decompiler.TabbedPrintWriter;
import net.sf.jode.expr.Expression;
import net.sf.jode.type.Type;
import net.sf.jode.util.SimpleSet;
///#def COLLECTIONS java.util
@ -60,13 +62,6 @@ public class IfThenElseBlock extends StructuredBlock {
this.cond = cond;
}
/**
* Gets the condition. The expression returned has boolean type.
*/
public Expression getCondition() {
return cond;
}
/**
* Sets the then block.
* @param thenBlock the then block, must be non null.
@ -172,7 +167,7 @@ public class IfThenElseBlock extends StructuredBlock {
{
boolean needBrace = thenBlock.needsBraces();
writer.print("if (");
cond.dumpExpression(TabbedPrintWriter.EXPL_PAREN, writer);
cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.print(")");
if (needBrace)
writer.openBrace();

@ -24,6 +24,7 @@ import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.StoreInstruction;
import net.sf.jode.expr.LocalStoreOperator;
import net.sf.jode.util.SimpleSet;
///#def COLLECTIONS java.util
import java.util.Set;
@ -136,12 +137,12 @@ public class InstructionBlock extends InstructionContainer {
StoreInstruction store = (StoreInstruction) instr;
LocalInfo local =
((LocalStoreOperator) store.getLValue()).getLocalInfo();
writer.startOp(TabbedPrintWriter.NO_PAREN, 0);
writer.startOp(writer.NO_PAREN, 0);
local.dumpDeclaration(writer);
writer.breakOp();
writer.print(" = ");
store.getSubExpressions()[1].makeInitializer(local.getType());
store.getSubExpressions()[1].dumpExpression(TabbedPrintWriter.IMPL_PAREN,
store.getSubExpressions()[1].dumpExpression(writer.IMPL_PAREN,
writer);
writer.endOp();
} else {
@ -149,9 +150,9 @@ public class InstructionBlock extends InstructionContainer {
if (instr.getType() != Type.tVoid) {
writer.print("PUSH ");
instr.dumpExpression(TabbedPrintWriter.IMPL_PAREN, writer);
instr.dumpExpression(writer.IMPL_PAREN, writer);
} else
instr.dumpExpression(TabbedPrintWriter.NO_PAREN, writer);
instr.dumpExpression(writer.NO_PAREN, writer);
} catch (RuntimeException ex) {
writer.print("(RUNTIME ERROR IN EXPRESSION)");
}

@ -18,8 +18,10 @@
*/
package net.sf.jode.flow;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.InvokeOperator;
import net.sf.jode.expr.LocalVarOperator;
import net.sf.jode.util.SimpleSet;
///#def COLLECTIONS java.util

@ -18,6 +18,7 @@
*/
package net.sf.jode.flow;
import net.sf.jode.GlobalOptions;
/**
* This class represents an unconditional jump.
@ -62,6 +63,7 @@ public class Jump {
* @param writer The tabbed print writer, where we print to.
*/
public void dumpSource(net.sf.jode.decompiler.TabbedPrintWriter writer)
throws java.io.IOException
{
if (destination == null)
writer.println ("GOTO null-ptr!!!!!");

@ -1,161 +0,0 @@
/* LoopBlock Copyright (C) 1998-2002 Jochen Hoenicke.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2, 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 Lesser General Public License
* along with this program; see the file COPYING.LESSER. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: LoopBlock.java 1411 2012-03-01 22:39:08Z hoenicke $
*/
package net.sf.jode.flow;
import net.sf.jode.decompiler.TabbedPrintWriter;
/**
* This is the structured block for an Loop block.
*/
public class LabelledBlock extends StructuredBlock implements BreakableBlock {
/**
* The body of this labelled block. This is always a valid block and not null.
*/
StructuredBlock bodyBlock;
/**
* The stack after the break.
*/
VariableStack breakedStack;
/**
* The serial number for labels.
*/
static int serialno = 0;
/**
* The label of this instruction, or null if it needs no label.
*/
String label = null;
public LabelledBlock() {
}
public void setBody(StructuredBlock body) {
bodyBlock = body;
bodyBlock.outer = this;
body.setFlowBlock(flowBlock);
}
/**
* Replaces the given sub block with a new block.
* @param oldBlock the old sub block.
* @param newBlock the new sub block.
* @return false, if oldBlock wasn't a direct sub block.
*/
public boolean replaceSubBlock(StructuredBlock oldBlock,
StructuredBlock newBlock) {
if (bodyBlock != oldBlock)
return false;
bodyBlock = newBlock;
newBlock.outer = this;
oldBlock.outer = null;
return true;
}
/**
* Returns all sub block of this structured block.
*/
public StructuredBlock[] getSubBlocks() {
return new StructuredBlock[] { bodyBlock };
}
public void dumpSource(TabbedPrintWriter writer)
throws java.io.IOException
{
super.dumpSource(writer);
}
public void dumpInstruction(TabbedPrintWriter writer)
throws java.io.IOException
{
if (label != null) {
writer.untab();
writer.println(label+":");
writer.tab();
}
boolean needBrace = bodyBlock.needsBraces();
if (needBrace)
writer.openBrace();
else
writer.println();
writer.tab();
bodyBlock.dumpSource(writer);
writer.untab();
writer.closeBrace();
}
/**
* Returns the label of this block and creates a new label, if
* there wasn't a label previously.
*/
public String getLabel() {
if (label == null)
label = "label_"+(serialno++);
return label;
}
/**
* Is called by BreakBlock, to tell us that this block is breaked.
*/
public void setBreaked() {
}
/**
* This is called after the analysis is completely done. It
* will remove all PUSH/stack_i expressions, (if the bytecode
* is correct).
* @param stack the stack at begin of the block
* @return null if there is no way to the end of this block,
* otherwise the stack after the block has executed.
*/
public VariableStack mapStackToLocal(VariableStack stack) {
VariableStack afterBody = bodyBlock.mapStackToLocal(stack);
mergeBreakedStack(afterBody);
return breakedStack;
}
/**
* Is called by BreakBlock, to tell us what the stack can be after a
* break.
* @return false if the stack is inconsistent.
*/
public void mergeBreakedStack(VariableStack stack) {
if (breakedStack != null)
breakedStack.merge(stack);
else
breakedStack = stack;
}
public void removePush() {
bodyBlock.removePush();
}
/**
* Determines if there is a sub block, that flows through to the end
* of this block. If this returns true, you know that jump is null.
* @return true, if the jump may be safely changed.
*/
public boolean jumpMayBeChanged() {
return false;
}
}

@ -19,6 +19,7 @@
package net.sf.jode.flow;
import net.sf.jode.decompiler.TabbedPrintWriter;
import net.sf.jode.type.Type;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.ConstOperator;
@ -315,7 +316,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
writer.print("for (;;)");
else {
writer.print("while (");
cond.dumpExpression(TabbedPrintWriter.EXPL_PAREN, writer);
cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.print(")");
}
break;
@ -324,13 +325,13 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
break;
case FOR:
writer.print("for (");
writer.startOp(TabbedPrintWriter.EXPL_PAREN, 0);
writer.startOp(writer.EXPL_PAREN, 0);
if (initInstr != null) {
if (isDeclaration) {
StoreInstruction store = (StoreInstruction) initInstr;
LocalInfo local = ((LocalStoreOperator) store
.getLValue()).getLocalInfo();
writer.startOp(TabbedPrintWriter.NO_PAREN, 1);
writer.startOp(writer.NO_PAREN, 1);
local.dumpDeclaration(writer);
writer.breakOp();
writer.print(" = ");
@ -339,16 +340,16 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
store.getSubExpressions()[1].dumpExpression(writer, 100);
writer.endOp();
} else
initInstr.dumpExpression(TabbedPrintWriter.NO_PAREN, writer);
initInstr.dumpExpression(writer.NO_PAREN, writer);
} else {
writer.print("/**/");
}
writer.print("; ");
writer.breakOp();
cond.dumpExpression(TabbedPrintWriter.IMPL_PAREN, writer);
cond.dumpExpression(writer.IMPL_PAREN, writer);
writer.print("; ");
writer.breakOp();
incrInstr.dumpExpression(TabbedPrintWriter.NO_PAREN, writer);
incrInstr.dumpExpression(writer.NO_PAREN, writer);
writer.endOp();
writer.print(")");
break;
@ -364,7 +365,7 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock {
if (needBrace)
writer.closeBraceContinue();
writer.print("while (");
cond.dumpExpression(TabbedPrintWriter.EXPL_PAREN, writer);
cond.dumpExpression(writer.EXPL_PAREN, writer);
writer.println(");");
} else if (needBrace)
writer.closeBrace();

@ -63,7 +63,7 @@ public class ReturnBlock extends InstructionContainer {
newStack = stack.pop(params);
}
}
return newStack;
return null;
}
public void removePush() {
@ -85,7 +85,7 @@ public class ReturnBlock extends InstructionContainer {
writer.print("return");
if (instr != null) {
writer.print(" ");
instr.dumpExpression(TabbedPrintWriter.IMPL_PAREN, writer);
instr.dumpExpression(writer.IMPL_PAREN, writer);
}
writer.println(";");
}

@ -19,6 +19,7 @@
package net.sf.jode.flow;
import net.sf.jode.decompiler.TabbedPrintWriter;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.LocalStoreOperator;
import net.sf.jode.expr.StoreInstruction;
import net.sf.jode.util.SimpleSet;

@ -19,8 +19,10 @@
package net.sf.jode.flow;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.util.ArrayEnum;
///#def COLLECTIONS java.util
import java.util.Collection;
import java.util.AbstractSet;
import java.util.Set;
import java.util.Iterator;
@ -205,6 +207,7 @@ public final class SlotSet extends AbstractSet implements Cloneable {
*/
public void mergeKill(Set kill) {
grow(kill.size());
big_loop:
for (Iterator i = kill.iterator(); i.hasNext(); ) {
LocalInfo li2 = (LocalInfo) i.next();
if (!containsSlot(li2.getSlot()))

@ -336,11 +336,8 @@ public abstract class StructuredBlock {
if (jump != null)
outer.getSubBlocks()[0].moveJump(jump);
outer.getSubBlocks()[0].replace(outer);
} else {
if (outer.jump != null)
outer.getSubBlocks()[1].moveJump(outer.jump);
} else
outer.getSubBlocks()[1].replace(outer);
}
return;
}
@ -552,7 +549,7 @@ public abstract class StructuredBlock {
subs[i].checkConsistent();
}
if (jump != null && jump.destination != null) {
Jump jumps = flowBlock.getJumps(jump.destination);
Jump jumps = (Jump) flowBlock.getJumps(jump.destination);
for (; jumps != jump; jumps = jumps.next) {
if (jumps == null)
throw new InternalError("Inconsistency");

@ -91,7 +91,7 @@ public class SynchronizedBlock extends StructuredBlock {
writer.println("MISSING MONITORENTER");
writer.print("synchronized (");
if (object != null)
object.dumpExpression(TabbedPrintWriter.EXPL_PAREN, writer);
object.dumpExpression(writer.EXPL_PAREN, writer);
else
writer.print(local.getName());
writer.print(")");

@ -33,7 +33,7 @@ public class ThrowBlock extends ReturnBlock {
throws java.io.IOException
{
writer.print("throw ");
instr.dumpExpression(TabbedPrintWriter.NO_PAREN, writer);
instr.dumpExpression(writer.NO_PAREN, writer);
writer.println(";");
}
}

@ -20,9 +20,11 @@
package net.sf.jode.flow;
import java.lang.reflect.Modifier;
import net.sf.jode.GlobalOptions;
import net.sf.jode.decompiler.Analyzer;
import net.sf.jode.decompiler.ClassAnalyzer;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.FieldAnalyzer;
import net.sf.jode.decompiler.MethodAnalyzer;
import net.sf.jode.decompiler.Options;
import net.sf.jode.decompiler.OuterValues;
import net.sf.jode.decompiler.OuterValueListener;
@ -34,6 +36,8 @@ import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.bytecode.MethodInfo;
import java.io.IOException;
import java.util.Vector;
import java.util.Enumeration;
/**
* This class will transform the constructors. We differ three types of
@ -436,6 +440,7 @@ public class TransformConstructors {
+ cons[i].getMethodHeader());
MethodAnalyzer constr = cons[i];
MethodType constrType = constr.getType();
/*
* constructor(outerValues, params, opt. jikesAnonInner param) {
@ -457,6 +462,7 @@ public class TransformConstructors {
* constructor$? as Jikes constructor. */
StructuredBlock sb = constr.getMethodHeader().block;
Vector localLoads = null;
InstructionBlock superBlock = null;
InvokeOperator superInvoke = null;
if (i >= type0Count) {
@ -541,6 +547,7 @@ public class TransformConstructors {
int firstParamSlot = slot;
int firstOuterSlot = firstParam;
int slotDist = firstParamSlot - firstOuterSlot;
/* check the remaining parameters.
*/
for (int j=firstParam; j < methodParams.length; j++) {
@ -850,6 +857,8 @@ public class TransformConstructors {
}
private void transformBlockInitializer(StructuredBlock block) {
StructuredBlock start = null;
StructuredBlock tail = null;
int lastField = -1;
while (block instanceof SequentialBlock) {
StructuredBlock ib = block.getSubBlocks()[0];

@ -27,6 +27,7 @@ import net.sf.jode.expr.*;
import java.util.TreeSet;
import java.util.SortedSet;
import java.util.Set;
import java.util.Map;
import java.util.Iterator;
///#enddef
///#def COLLECTIONEXTRA java.lang
@ -583,7 +584,7 @@ public class TransformExceptionHandlers {
* |- monitorexit local_x |
* ` jump after this block (without jsr monexit) |
* |
* catchBlock: |
* catchBlock: |
* local_n = stack |
* monitorexit local_x |
* throw local_n |
@ -598,7 +599,7 @@ public class TransformExceptionHandlers {
/* Merge try and catch flow blocks. No need to insert the
* catchFlow.block into the try flow though, since all its
* instruction are synthetic.
* instructions are synthetic.
*/
mergeTryCatch(tryFlow, catchFlow);
@ -713,7 +714,7 @@ public class TransformExceptionHandlers {
&& doWhileFalse.bodyBlock instanceof SequentialBlock) {
if (transformSubRoutine(catchBlock.getSubBlocks()[1])) {
finallyBlock = catchBlock.getSubBlocks()[1];
catchBlock = doWhileFalse.bodyBlock;
catchBlock = (SequentialBlock) doWhileFalse.bodyBlock;
}
}
}
@ -776,6 +777,7 @@ public class TransformExceptionHandlers {
finallyBlock = subRoutine.block;
DescriptionBlock msg = new DescriptionBlock
("ERROR: Missing return address handling");
StructuredBlock subblock = subRoutine.block;
msg.replace(finallyBlock);
msg.appendBlock(finallyBlock);
}
@ -933,7 +935,7 @@ public class TransformExceptionHandlers {
GlobalOptions.err.println
("Warning: Can't completely analyze try.");
}
new TryBlock(tryFlow);
TryBlock tryBlock = new TryBlock(tryFlow);
} else if (!(tryFlow.block instanceof TryBlock))
throw new InternalError("no TryBlock");

@ -19,6 +19,7 @@
package net.sf.jode.flow;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.util.ArrayEnum;
///#def COLLECTIONS java.util
import java.util.Collection;
@ -192,6 +193,7 @@ public final class VariableSet extends AbstractSet implements Cloneable {
public VariableSet intersect(VariableSet vs) {
VariableSet intersection = new VariableSet();
intersection.grow(Math.min(count, vs.count));
big_loop:
for (int i=0; i<count; i++) {
LocalInfo li = locals[i];
int slot = li.getSlot();
@ -210,6 +212,7 @@ public final class VariableSet extends AbstractSet implements Cloneable {
*/
public void mergeGenKill(Collection gen, SlotSet kill) {
grow(gen.size());
big_loop:
for (Iterator i = gen.iterator(); i.hasNext(); ) {
LocalInfo li2 = (LocalInfo) i.next();
if (!kill.containsSlot(li2.getSlot()))

@ -21,6 +21,7 @@ package net.sf.jode.flow;
import net.sf.jode.decompiler.LocalInfo;
import net.sf.jode.expr.Expression;
import net.sf.jode.expr.LocalLoadOperator;
import net.sf.jode.expr.Operator;
/**
* This class represents the state of the stack at various points in
@ -111,7 +112,7 @@ public class VariableStack {
}
public VariableStack executeSpecial(SpecialBlock special) {
if (special.type == SpecialBlock.POP) {
if (special.type == special.POP) {
int popped = 0;
int newLength = stackMap.length;
while (popped < special.count) {
@ -123,7 +124,7 @@ public class VariableStack {
LocalInfo[] newStack = new LocalInfo[newLength];
System.arraycopy(stackMap, 0, newStack, 0, newLength);
return new VariableStack(newStack);
} else if (special.type == SpecialBlock.DUP) {
} else if (special.type == special.DUP) {
int popped = 0;
int numDup = 0;
int startDup = stackMap.length;
@ -150,7 +151,7 @@ public class VariableStack {
System.arraycopy(stackMap, startDup, newStack, startDup + numDup,
numDup);
return new VariableStack(newStack);
} else if (special.type == SpecialBlock.SWAP) {
} else if (special.type == special.SWAP) {
LocalInfo[] newStack = new LocalInfo[stackMap.length];
System.arraycopy(stackMap, 0, newStack, 0, stackMap.length - 2);
if (stackMap[stackMap.length-2].getType().stackSize() != 1

@ -33,9 +33,12 @@ import net.sf.jode.bytecode.TypeSignature;
import java.io.IOException;
import java.util.BitSet;
///#def COLLECTIONS java.util
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
///#enddef
@ -1142,6 +1145,7 @@ public class CodeVerifier implements Opcodes {
}
if (ref.getName().equals("<init>")) {
Type clazz = info.pop();
String typeSig = clazz.getTypeSig();
String refClazzSig = ref.getClazz();
Type refClazz = tType("N" + refClazzSig.substring(1));
if (opcode != opc_invokespecial
@ -1415,7 +1419,7 @@ public class CodeVerifier implements Opcodes {
if (info.jsrInfo == null || !retVarType.isOfType(tType("R")))
throw new VerifyException(instr.getDescription());
Block jsrTarget = retVarType.getJsrTarget();
BitSet usedLocals = info.jsrInfo.jsrUsed;
BitSet usedLocals = (BitSet) info.jsrInfo.jsrUsed;
for (Block lastTarget = info.jsrInfo.jsrTarget;
jsrTarget != lastTarget;
lastTarget = subInfos[lastTarget.getBlockNr()]

@ -92,6 +92,7 @@ public class Interpreter implements Opcodes {
for (int i=0; i < stack.length; i++)
stack[i] = new Value();
Block[] blocks = bb.getBlocks();
Block nextBlock = bb.getStartBlock();
int stacktop = 0;

@ -18,6 +18,7 @@
*/
package net.sf.jode.jvm;
import net.sf.jode.GlobalOptions;
import net.sf.jode.bytecode.BasicBlocks;
import net.sf.jode.bytecode.Block;
import net.sf.jode.bytecode.ClassInfo;
@ -106,6 +107,7 @@ public class SyntheticAnalyzer implements Opcodes {
BasicBlocks bb = method.getBasicBlocks();
Block[] blocks = bb.getBlocks();
Block startBlock = bb.getStartBlock();
Handler[] excHandlers = bb.getExceptionHandlers();
if (startBlock == null
@ -183,6 +185,7 @@ public class SyntheticAnalyzer implements Opcodes {
Handler[] excHandlers = bb.getExceptionHandlers();
if (excHandlers != null && excHandlers.length != 0)
return false;
Block[] blocks = bb.getBlocks();
Block startBlock = bb.getStartBlock();
if (startBlock == null)
return false;
@ -308,12 +311,12 @@ public class SyntheticAnalyzer implements Opcodes {
}
MethodInfo refMethod
= refClazz.findMethod(ref.getName(), ref.getType());
MethodType refType = Type.tMethod(classInfo.getClassPath(),
ref.getType());
String[] refParams = TypeSignature.getParameterTypes(ref.getType());
String retType = TypeSignature.getReturnType(ref.getType());
if ((refMethod.getModifiers() & modifierMask) != 0
|| refType.getParameterTypes().length != params)
|| refParams.length != params)
return false;
if (refType.getReturnType() == Type.tVoid) {
if (retType.equals("V")) {
if (iter.hasNext())
return false;
} else {
@ -387,12 +390,11 @@ public class SyntheticAnalyzer implements Opcodes {
return false;
MethodInfo refMethod
= refClazz.findMethod(ref.getName(), ref.getType());
MethodType refType = Type.tMethod(classInfo.getClassPath(),
ref.getType());
String[] refParams = TypeSignature.getParameterTypes(ref.getType());
if ((refMethod.getModifiers() & modifierMask) != 0
|| !refMethod.getName().equals("<init>")
|| unifyParam == -1
|| refType.getParameterTypes().length != params - 2)
|| refParams.length != params - 2)
return false;
if (iter.hasNext())
return false;

@ -18,6 +18,7 @@
*/
package net.sf.jode.jvm;
import net.sf.jode.bytecode.*;
/**
* This class represents a stack value.

@ -18,6 +18,7 @@
*/
package net.sf.jode.jvm;
import net.sf.jode.bytecode.*;
/**
* This exception is thrown by the CodeVerifier on various conditions.

@ -20,6 +20,7 @@
package net.sf.jode.obfuscator;
import net.sf.jode.GlobalOptions;
import net.sf.jode.bytecode.ClassPath;
import net.sf.jode.bytecode.ClassInfo;
import net.sf.jode.bytecode.Reference;
import net.sf.jode.obfuscator.modules.WildCard;
import net.sf.jode.obfuscator.modules.MultiIdentifierMatcher;
@ -35,6 +36,10 @@ import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.TreeMap;
///#enddef
///#def COLLECTIONEXTRA java.lang
import java.lang.UnsupportedOperationException;
///#enddef
///#ifdef JDK12

@ -30,6 +30,7 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;
///#enddef
///#def COLLECTIONEXTRA java.lang
@ -393,7 +394,7 @@ public class ClassIdentifier extends Identifier {
initialized = true;
try {
info.load(ClassInfo.ALL);
info.load(info.ALL);
} catch (IOException ex) {
throw new RuntimeException("Can't read class " + info.getName()
+ ": " + ex.getMessage());
@ -748,6 +749,7 @@ public class ClassIdentifier extends Identifier {
* they must be there!).
*/
ClassInfo superInfo = info.getSuperclass();
ClassIdentifier superIdent = this;
while (superInfo != null) {
ClassIdentifier superident = Main.getClassBundle()
.getClassIdentifier(superInfo.getName());

@ -18,12 +18,14 @@
*/
package net.sf.jode.obfuscator;
import java.lang.reflect.Modifier;
import net.sf.jode.bytecode.*;
///#def COLLECTIONS java.util
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.HashSet;
import java.util.Map;
///#enddef

@ -19,6 +19,7 @@
package net.sf.jode.obfuscator;
import net.sf.jode.GlobalOptions;
import java.io.*;
///#def COLLECTIONS java.util
import java.util.Map;
import java.util.Iterator;

@ -23,6 +23,7 @@ import net.sf.jode.GlobalOptions;
import gnu.getopt.LongOpt;
import gnu.getopt.Getopt;
import java.lang.reflect.Modifier;
import java.io.PrintWriter;
import java.io.FileReader;
import java.io.InputStreamReader;

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save