CFR - another java decompiler
CFR will decompile modern Java features - up to and including much of Java 9, 10, 12 and beyond, but is written entirely in Java 6, so will work anywhere! (FAQ) - It'll even make a decent go of turning class files from other JVM languages back into java!
To use, simply run the specific version jar, with the class name(s) you want to decompile (either as a path to a class file, or as a fully qualified classname on your classpath).
(--help to list arguments).
Alternately, to decompile an entire jar, simply provide the jar path, and if you want to emit files (which you probably do!) add --outputdir /tmp/putithere
- cfr-0.148.jar (October 2019) md5: 44d5bc109860c486c8d89b58abe853d6
- cfr-0.146.jar (July 2019) (I suggest using latest, but if you spot a regression, it means I'm missing a test... so please shout!)
- Older versions
- Or get it from maven.
- ...or just go to github. (yup, new since 0.145).
FAQ is here
Contact / Updates
Feel free to drop me a line (firstname.lastname@example.org) if there's anything you think is particularly broken, bear in mind it's a work in progress (but I'd say on a par with others!) - Or if you want to know when an update is out, I've finally started announcing on twitter - (@LeeAtBenf)
Observations about syntactic sugar in compilation.
All of this stuff is documented (links where I find them); these are things I found particularly interesting while messing around with this.
.... and other observations.....
It's got a lot of things missing, which I'm messing with, as and when time makes itself available ;)
- Generic reverse inference (forward inference works... getting better!)
- Correct generic inference for locals which don't escape scope. Without trusting localVariableTypeTable, this is hard. I may have to use it :(
- More Java 9+ improvements (java's a moving target these days!)
- And more....
- Adapt to changes in ecj's output of switch-on-enum (Thanks Marcono1234)
- Many small fixes for handling obfuscation mapping files (--obfuscationpath file.txt)(Thanks Marcono1234)
- Work on (unfinished) token output stream (Thanks cubixity)
- Fix for regression on pretty printing of inner classes
- Support for deobfuscation mapping files with --obfuscationpath file.txt (Thanks samuel)
- Fix extraneous array creation (Thanks caagr98)
- Handle duplicate target shared between disconnected switches (Thanks evelynsubarrow)
- Reduce over-aggressive eclipse pass (Thanks caagr98)
- Allow try resources to be collapsed
- Fail gracefully if a lambda body is recursive (what, scala?!) (Thanks kolanich)
- Handle module definition classes (Thanks metatech)
- Fix for effectively empty try requiring topsort
- Allow filter on imports, to force FQN.
- Fix overuse of boxed constant names.
- Tweak to improve hex usage
- Fix bound on unicode (Thanks lab13ru)
- Less paranoia with regards to operation exceptions. (Thanks itzsomebody)
- Add recovery phase which tweaks heuristics for topsort
- Fix issue with member lifting (Thanks grahamedgecombe)
- Handle odd kotlin explicit generic return type from constructor
- Introduce explicitly ignored variables if we need to preserve a calculation (Thanks lab13ru)
- Handle a form of string switch in java more like kotlin's (don't know origin!) (Thanks totemo)
- Fix incorrect use of explicit super type what calling indirect super methods. (Thanks jredman)
- Improve support for JVM9+'s multi version jar.
- Fix bug in nested string resugaring. (Thanks dmitryg)
- Improve sugaring around some bad bool casts.
- Some tidying to improve decompilation of hand written classfiles. (See SootOptimisationTests).
- Where possible, collapse multiple JSRs.
- Fix bad preincrement in some java6 code.
- Fix typo in java 12+ switch expressions. (Thanks timothyp)
- Improve iter loops where we can unbox immediately.
- Remove more pointless super()s
- Fix leakage of internal class names in accesses of enclosing anonymous classes. (Thanks dmitryg)
- Pseudocode support for JVM11+'s dynamic constants. (Thanks JavierM)
- Fix regression from 142 which can duplicate declarations inside a case, sad face. (Thanks anyay)
- Don't allow variable declarations to be hoisted before super. (Thanks anyay)
- Small improvement to conditional extraction, Just Another Edge Case...
- More improvements to Switch expressions - Kotlin comes back as switch expressions!
- Improve handling (and commenting) of experimental jdk features.
- Handle naughty ofbuscators illegally marking a method varargs. (Thanks taile)
- Improvement to variable scoping inside case statements (Thanks anyay)
- Improvement to SSA analysis in copy propagation (Thanks harrand)
- Switch expressions in Java 13 (and with --switchexpression true for earlier)!
- Improved reconstruction of Jdk 13 try-resource blocks. (bytecode style has changed...)
- Fix regresssion with splitting exception handler. (Thanks scoleman)
- Nop isolated stack variables to avoid reordering under a nasty obfuscation. (Thanks yanwentao)
- Fix non determinism in resolving type clash in multi-exception handler. (Thanks borisk
- Warn if type clash resolution leads to void variables.
- Fix truncation issue with naming under huge bytecode.
- Improve type clash behaviour. (Thanks anyay)
- Improve type clashes in iterated arrays.
- Reduce aggressive lifting of field init from constructor.
- Remove varargs spam.
- Remove truncation which can break *HUGE* exception handlers. (Thanks Janosz)
- Loosen lambda capture restriction (improves lambda resugaring for deeply nested lambdas).
- Handle possible NPE in local expression rewriter.
- Infer a little more information about unavailable-but-caught types. (Thanks zbzzn)
- Tidied help. (Thanks dearappauthors)
- Double comparison inversion is not always safe wrt NaN - (a < b) is NOT !(a >= b). (Thanks abec)
- Handle (with warning) some code that (naughtily, but obviously) splits exceptions across unsafe operations.
- More aggressive inlining of switch code for cases that would fail to decompile. (Thanks brandonr)
- Handle corrupt class signatures (Thanks itzsomebody)
- Be more lenient with mismatching bootstrap arguments ( " )
- Fix precedence issue with unary minus. (Thanks littlestar)
- If we've failed to split lifetimes, leaving too narrow a type, force explicit casts. (Thanks hostalp)
- Fix for failure when validating casts against missing class.
- Fix for NPE when explicitly decompiling an inner class with missing outer. (Thanks abec)
- Improve displayed class name for anonymous classes (normally won't appear, but could be forced) ( " )
- Fix for ordering of inlined lvalue mutations (Thanks abec, karls)
- Improvement to lifetime auditing allows inlining of anonymous arrays with mutators.
- Improve generated code for prechange assignments. (check out IncrTest5!!)
- Reconsider JSRs if they've been expanded.
- Relabel private static accessors if they're lifted to an outer class.
- Improve lambda desugaring when we don't have target class available (improves reconstruction of java8+ code using jre6!)
- Improve lifetime auditing on ternary roll-up.
- Now being released to maven central repos. Hence the naming style change - it's time to be a little more consistent with the rest of the world!
- Finally improved and documented an API!
- Fixed incorrect complaints of case insensitive fs (Thanks nathanf)
- Fixed a possible incorrect generic binding.
- Improve scoping of some method-scoped classes.
- External references to methods / fields of anonymous classes, if you're in J10+ - use var where appropriate. (Thanks abec)
- Improvements to explicit type access to members (Force slicing to correct type).
- Handle marker interfaces in lambdametafactory.
- Other fixes for intersection types. (Thanks abec) ... (eg this)
- --jarfilter allows negative filter when prefixed with ! (Thanks gar)
- ... a whole bunch of tidying ...
- Resugar java9 indified strings - either indy or indyWithConstants.
- Improve handling of anonymous class constructors.
- Ensure intermediate goto after finally is tagged in correct block (Thanks kalhauge)
- Improve assert resugaring.
- Handle assert detail messages. (Thanks abec)
- Fix issue with method scoped classes in lambdas
- Fix spurious NOP after invokedynamic. (Improves lambda resugaring, yay!)
- Improve error on read of uninitialized local. (Thanks qwm)
- Fix issue with batch processing on windows.
- No-op changes to allow CFR to run fully under Apache Harmony's Java 6 implementation (I did say it will run on any old Java!) (Thanks abec)
- Improvement to Java9+ loading from modules. (Thanks stefanr)
- Improvements to method scoped classes. (Thanks abec)
- Prefer classes from explicitly searched jars. ( " )
- Fix missing cast in immediately evaluated functional interface method. (Thanks abec)
- Fix over eager redundant code removal. ( " )
- Remove incorrect stripping of anonymous array around varargs call. ( " )
- Fix lambda resugaring bug around new Object::clone ( " )
- Improve ternary casting. ( " )
- Handle a particularly painful ternary style.
- Fix missing cast when array type requires de-clashing.
- Improve iterated loop resugaring when loop variable is updated.
- Improve type inference.
- Collapse try resources.
- Accept multiple class/jars on command line.
- Remove horrid reflection to allow java6 to read java9 code. (Thanks comatrices)
- Fix a few grotty inference bugs. (Thanks jstokes)
- Handle when-string - kotlin's switch on string - nicely.
- Tidy jdk9 requireNotNull artifacts.
- Tidy lambda whitespace.
- Fix issue lifting members out of constructors in function-scoped classes.
- Fix scope issue with variable incorrectly captured in loop (Thanks jstokes)
...somehow, I manged to release an ancient version as 0_126! 0_127 is the real thing!
Thanks jstokes for pointing out that bit of idiocy!
- Fix possible NPE rebuilding string constant references.
- Add a very silly option to allow you to completely --ignoreexceptions. This is useful when the exception table is so confusing that nothing sensible can be retrieved.
- Remove pointless assignments when dealing with very large bytecode to clean output.
- Allow jimage files to be used when running under JRE9 to read base classes.
- Fix issue with an inner class constructor not having synthetic argument removed.
- Fix anonymous inner not being collapsed across constructors and extracted into field (Thanks jstokes)
- Better handle lack of static marker on anonymous classes with JDK9.
- Handle mutating synthetic friend accessors in JDK9.
- Handle try-with-resources in both JDK<9 and JDK9.
- Change visibility of static bridge methods (impossible in java, used for defaults in Kotlin!)
- Fix accidental signed short usage ... oops.... causes index exception on huge tables. (Thanks Bchong)
- Where unambiguous (though you can never be sure!), replace string constants with guessed source static finals. (disable with -relinkconststring false) (Thanks Matti)
0_124 (2018-01-04) - A flurry of mails!
- Improvements to boxing around Bytes, missing explicit up and down casts. (Thanks AbeC)
- Handle empty enum switches (Thanks AbeC)
- Removed slightly misguided pretty print of long constants without L where possible
- Ensure method scoped classes are displayed if they're only referred to via teir type constants. (Thanks AbeC)
- Improvement to assert rewriter (Thanks abec - lots of tests!)
- Fix for boolean constant in attribute being treated as int (")
- Don't display defensive cast to anonymous type (")
- More aggressive anonymous block jumps (")
- Fix for monadic op on bool casting to int (")
- Fix classpath issue (Thanks ken)
- Avoid collapsing compound assignment operators where rhs involves further mutation (thanks michaln)
- Don't detect class as anonymous inner class of object in scala (Thanks sarahg)
- Basic support for varargs bootstrap factories (only seen thus far in scala) (Thanks sarahg)
- Fix for boolean default elementvalue - use hint from returntype (Thanks caoli5288)
- Fix for OuterClass.this() when OuterClass.super() specifically invoked. (Thanks littlestar)
- Don't mark static methods with implementations in interfaces (yeuch!) as default (Thanks caoli)
- Fix for missed dropped jump in finally analysis. (Thanks lee_zhou)
- Reduce emission of uneccessary break/continue statements.
- Fix an issue where obfuscated code with an odd unreachable jump structure can cause failure. (Thanks testsubject)
- Fix spurious 'default' on static interface method. (Thanks caoli)
- Fix for loop in copy propagation (Thanks dequis)
- Improvements in scope handling (Thanks pokechu22)
- Minor tweak to plugin runner interface (which I really should document)
- Fix for NPE processing bad classpath directories. (Thanks mkraus)
- Optionally, (warn if applicable and you're unlucky enough to be using a case insensitive fs) rename classes to avoid MixED case clash (wuth --caseinsensitivefs true) (Thanks testsubject, chases)
- Tidy up help. (Thanks michaelf)
- Correctly specify explicit super calls to default interface methods (Thanks dmitryp)
- --elidescala helper option to make reading decompiled scala easier by removing serialVersionUID and ScalaSignature (may help in other languages). (Thanks sarahg)
- Fix for nested lambdas (Thanks abec)
- Fix bracketing for lambda precedence, improvement to use of method references.
- Basic support for runtime visible type annotations (currently on local variables, not on pure expressions) (Thanks abec)
- Fix for NPE handling bad annotations.
- Tweak to finally detection.
- Don't remove nested anonymous array qualifiers when assignment target is of incorrect arity. (Thanks abec)
- Bugfix to finally analyser (thanks thelaser)
- Improvement to JSR analysis to untangle some simple deliberate obfuscations (thanks sun)
- Diagnostic comment when we lose an exception.
- Support '--clobber' to avoid overwriting files. (defaults to true). (thanks dloyall)
- Fix an NPE. (thanks sun)
- Fix for a stack overflow in copy propagation on a handwritten edge case. (thanks sun)
- Fixed issue with incorrectly parsing a Stack map attribute. (thanks sun)
- Fix for variable clash resolution which could lead to parse error. (Thanks knotovna)
- Improvement in array type collision resolution (thanks abec)
- Improvement to plugin runner (thanks sun)
- Handle illegal identifiers in obfuscated enums. (thanks krisa)
- Allow recovery of obfuscated enum identifiers (where name text and field don't match)
- Tweak to finally detection for case blocks.
- Improvement to ident naming clashes.
- Fix issue where iterator reconstruction would be applied uneccesarily.
- Tweak to check if aggressive exception aggregation improves things (fallback pass).
- Improve type detection (note - I'm still avoiding using type tables etc. This is a conscious choice - they can be faked with possible obfuscation).
- Fix for an illegal forward reordering in some for loop detection.
- Check raw (stack type int) type is implicitly castable on return (Thanks thedmitriyk).
- Fix to dead node removal (led to exception analysing some classes of finally statement)
- Tweaks to finally analysis (thanks abec)
- If reconstructed string switch is on a literal null, force explicit cast (")
- Tidy imports (thanks rillig)
- Fix issue with assert detection. (")
- Improve names on certain FP constants (")
- Force RHS of shift ops to int, if type is indeterminate from elsewhere. (")
- Split lifetimes if final type misdetected as reference due to clash.
- Fix bug allowing primitive arrays in constructor to be lifted erroneously. (thanks rillig)
- Tidy arguments/errors.
- Allow reference placeholders to be treated as arrays. (Strange, but allows some otherwise failing Kotlin code to decompile)
- Option to allow code to be aggressively pulled into case statements. Not enabled by default/recovery yet (useful for Kotlin)
- Improve assertion normalisation. (thanks abec)
- Make push through goto slightly more aggressive.
- Allow unstructured gotos to be nopped if they fall into successor in same block (pass 4).
- Move if body to after else, if else has no exits, and if has foreign entrants which would cause issues.
- Fix for incorrect target on jsr_w (thanks esnow)
- Small improvement to conditional aggregation. (thanks thelaser)
- Poison hidden iterators when rebuilding for (x:...)
- Tweak to demorgan conditional simplifier to take precedence into account when working out best representation.
- Fix asymmetry in some cases of basic block collapse.
- Improve bad cast chains (if a crazy cast via 'Object' is required') (thanks abec)
- Don't discard necessary extra casts with lambda methods ("")
- Fix for some cases where switch literals weren't detected from bool->int ("")
- Fix for bad names with literals not in the identifier set ("")
- Add --extraclasspath to allow helper jars to be searched for analysis (thanks jozko)
- Handle unknown bootstrap metafactories more gracefully
- Take lambda variables into account when assigning names (thanks wbeuchner)
- Fix for preop >>= being displayed incorrectly in some circumstances. (thanks jhadrava)
- Attempt to remove spurious returns from clinit, as it leads to illegal java. (thanks rbalerdi)
- Fix for wildcards in some inappropriate places (thanks (again!) abec)
- Bad catch name in some cases
- Fix some NPEs (edge case with missing dependency, edge anonymous array rewrite) (thanks choonster)
- Fix some missing WIDE opcode handling (you need a LOT of locals to trigger that!) (thanks alexnguyen)
beta 100! I promise, I'll release a verision 1 at some point, when I'm happy with the code!!
- Fix for explicit constpool literals (not initialised by code) being displayed as int when they could be narrowed to bool. (thanks abec, malter)
- Helpful little tweak to cause CFR to emit more descriptive local names, by optionally triggering the illegal name rewriter when variable names are less than a certain size (see --renamesmallmembers). (idea from xryl)
- Fix for regression in which cast -> ConstantPoolEntryMethodRef exception is thrown. (thanks adamp)
- Fix for --renamedupmembers failing when some base classes don't exist
- Handle enormous code blocks better, by aggressively applying semantically safe but destructive transforms, such as removing ignored stores, to simplify static assignment analysis. (Controlled with --aggressivesizethreshold, defaults to 15000 instructions.) (thanks vbabenko)
- Better error reporting for illegal bytecode. (thanks dpetrashko)
- Improvements to missing disambiguation casts when using explicit nulls (thanks abec)
- Fix for inverted condition on empty while loops with a special case structure (thanks abec)
- Fix for explicit null callees (thanks abec)
- Fix for some missed loops. (Thanks rossmck)
- Fix for some bad naming collisions, over aggressive imports. (Thanks malter)
- Tweak disambiguated variable names so they won't collide with methods (Thanks abecker)
- Fix for missed detection of an anonymous array initialiser (Thanks maxl)
- Fixes for some incorrect @Overrides
- Normalise some parse trees, to improve detection of some assert patterns.
- Improvements to bad member name detection - see this. Examples here and here. Use --renamedupmembers true to enable. (Thanks abecker)
- Small improvement to restructuring of breaks.
- Fix to daft unicode regression in 0_93 leaving trailing unicode marker on extracted jar content. (thanks abecker)
- If a goto can be transformed into a break of the tightest breakable block - do so.
- Better handling of type names when renaming duplicate members. (thanks abecker)
- Detect and offer to rename illegal identifiers (illegal idents in local variables are always dropped).
- Handle pre 1.0 java class files. (But warn, as your recompilation with a modern compiler is unlikely to be compatible!)
- Improve topsort - if there's an orphan block, force it early.
- Fix bad chained goto removal, where it appears to leave an uneccessary loop.
- Remove references to labelled blocks if a labelled block break would end up in the same place as a natural scoped break.
- Reduce goto chain condensing in the presence of break statements.
- Handle (Only if explicitly selected) duplicate field names (thanks cliffh)
- Allow jar processing to take a regex of which classes to extract (--jarfilter)
- Tidy errors
- Push returns early when reordering to make control flow as simple as possible. Explicit support for ternaries which jump into identical returns. (improves quality of some dex2jar code).
- Shrink catch block if it's over aggressive.
- Improve trailing goto removal once code at structurable stage.
- Handle conditionals that jump straight into a fall through (was leaving a goto)
- Don't allow static initialiser to be marked as an override (oops!)
- Fix issue where aggressive conditional to return pushing was dropping a side effect, when inside a block with a finally clause.
- Fix over extension of switch contained in finally affected block, leading to default block adopting code outside switch. (thanks abec)
- Fix case where unbound generic with no typing info could suggest a variable name of '$'.
- Improvements to SSA analysis (see IncrTest5, thanks hgraf).
- (minor) improvement to handling some obfuscated switches which caused failure. (thanks abec)
- Don't force parameter type - allow parameters to be displaced in code. (Thanks lefevrol)
- Improve explicit generics for java 1.6 function args
- Cope (but not particularly well yet) with groovy invokedynamics. (Thanks franze)
- Fix issue where explicit classfile permissions are more generous than inner class permissions.
- Explicit cast if we're returning a generic place holder.
- Fix uneccessary redundant bracing
- Fix a precedence issue
- Check for correct overload calling POST erasure - means less explicit argument casting.
- Explicit final on loop iters, when forced by inner class usage
- Change placeholder binding collision policy
- Fix possible illegal rewrite of ternaries when de-inlining assignments
- Improve synthetic accessor rewriter.
- Feed back type information from detected loops
- Extract aggressive inlining of assignments, if it can no longer help simplifying code
- Tidy statics so we use simple name where possible
- Fix bad type on unused null argument
- Attempt to resolve any outstanding type clashes at scope discovery time
- Rewrite variable definitions if anonymous inners are inadvertently causing scope hiding.
- Better guess for anonymous inner types.
- Don't remove unused function args from ident set, as it causes them to have ugly idents set (and causes bad behaviour with jre8's broken (still in the wild, alas) HashMap implementation.) (Thanks srborlongan).
- Fix precedence issue on instanceof.
- Tidy some character quoting where I \uXXXX unicode instead of simple char literals.
- Improve the way outer class this references are processed - more efficient.
- Hide inner class friend helper classes (see fake friendship).
- Remove some illegal wildcards when generating LValue types.
- Handle empty switches better - don't always remove them, as that leaves odd code lying around in switch-on-enum case.
- Better inferrence of final for anonymous class outer references.
- Improvements to implicit cast checking.
- Fix bug which could cause some switch-on-enum statements not to be resugared.
- Fix issue with possible unstructured break on switch.
- Fixed issue causing failure of lambda methods with > 127 captures. (Thanks srborlongan).
- Fix some false sharing scenarios.
- Handle even more complex conditionals with ludicrous inline assignment. ShortCircuitAssignTest4e(!).
- Fix issues with ugly code from early-detected ternaries
- Allow for loops to capture multiple updates, (but only if they're involved in the predicate, for cleaner code. Override with --forloopaggcapture to capture all possible updates).
- Fix bug whereby conditionals were being too aggressively merged.
- Other improvements to conditional merging.
- Yet more fixes for nasty topsort edge cases (again, mostly exhibited in dex2jar).
- Improve error when magic is wrong.
- Allow force class/jar.
- Only enable rolling returns up to conditional if necessary in recovery pass. (or manually selected)
- Another dex2jar optimisation - handle conditionals which jump into middle of later conditionals - if the latter can be rewritten as a block escape. (Thanks MCirsta)
- Minor formatting improvements.
0_80 (2014-07-07) ... been a while!
- Switch fixes
- Improve top sort block emission - allow emission when not all sources satisfied, if it would cause us to save known block ordering
- Several improvements for dex'd code ( thanks pcreath )
- Fix bug with overly aggressive push-through-goto
- Enable tautology conditional recovery pass - will slice out comparisons which are tautologies and move the jump back as far as possible.
- Fix for dup2_x2 sometimes generating weird assignments. ( thanks jmcgowan )
- Lots of code refactoring...
- Handle dex2jar style finally (where try blocks jump between each other, and non-throwing content is often outside a try regime) (Thanks pcreath)
- Fix for bug in copy propagation (Thanks jmcgowan)
- Fix for NPE regression when displaying some missing anonymous inner classes. (Thanks atanasn)
- For for type being displayed as null. (Thanks jarrkos)
- Minor improvement to type inference.
- Tweaks to boxing for nicer output.
- Fix missing labels on switch statements when necessary for block-break. (Thanks nilsandre)
- Fix typing issue with some argument types. (Thanks jarrkos)
- Misc improvements to labelled block breaks.
- Fix for missing annotations on fields.
- Now that java 8 correctly fills in lambda arg names, trust them a little more. (Thanks mstrobel)
- Remaining untranslated stack vars get turned into locals.
- Improve cast insertion logic around generic wildcarding, generic arrays.
- Handle trailing dead bytecode at the end of methods. (Thanks mcirsta)
- Fix small issue where some post-operations weren't recognised, leaving annoying temporaries. (Thanks mkiersch)
- Fixed (one) issue with structured goto removal. (Thanks jarrkos)
- Fixed regression with standalone inner class analysis. (String exception)
- Fix for exception when performing some cases of try block merging.
- Fix type promotion issue. (Thanks jarrkos)
- Improvement to time complexity in boxing removal and alias removal. (Thanks nnelous)
- Fix for uneccessary fully qualified types in enum arguments
- Fix for chained enum constructors.
- Fix for precedence issue on locally casted field access.
- Handle possible CannotLoadClass exception for scala style bytecode.
- Change inner class name processing logic - handles scala style inner classes better. (Here's an icky test.... ) (Thanks leat)
- Another small change to exception block extension.
- Improvement to topsort heuristics, significantly improves handling of some dex2jar output. (Thanks pcreath)
- Improvement to impossible exception block extension. (Allows statements to be brought inside an exception block if this can't affect semantics).
- Fix for precedence issue.
- Resugar java 1.4 class constants (did you know they did this?)
- Change java.lang imports to hidden by default (controlled with --hidelangimports)
- Honour old Synthetic attribute.
- Fix regression in 0_63, when backjump occurs to target of forward jump labelled-goto.
- Fix integral cast missing explicit promotion.
- Fix for unsupported operation exception on bad inner class info.
- Tidy float output.
- Fix for bad type inference in some boolean ops.
- Labelled blocks (to support fake-goto) I've been holding off on this because it allows output which could be improved by reordering, but I guess it's time.
- Fix incorrect preop output.
- Tweak int^-1 -> ~int.
- Tidy up help display.
- Remove bad backjumps to exception handlers when topsorted - shouldn't be valid, but seen in obfuscated (or dex2jar!!) code. (Thanks pcreath)
- Fix for incorrect variable scoping in exception handlers (Thanks jarrkos)
- Finally implemented more sensible precedence handling, eliminates lots of redundant braces, and fixes precedence bug on casting. (Thanks jarrkos)
- Fix issue with overlapping but non-nested while loops causing exception. (generally when final backjump to earlier loop is a continue, and end of earlier loop is break; while(true), meaning it appears to have a shorter scope)
- Fix for switch incorrectly marking some sources of break targets as breaks, leading to unstructured output.
- Fix for missing assert pattern (some cases of assert not resugared).
- Normalise try blocks to improve conditional detection.
- Recover from out of order constructor parameters (warn in comment if this happens).
- Tweak argument help (--help xxx)
- Improve classification of some escapes from catch blocks. (Thanks chrixian)
- Stack discovery is no longer recursive, to avoid blowup on Humungous stack walks
- Work around for file names FS can't support due to length. (Thanks SvenB)
- Fix NPE on while-as-for detection.
- Fix annotation enum values display.
- Significant internal tidying of recovery passes.
- Added iterative fallback passes, with more aggressive options.
- Added (pretty desparate if we get here!) monitor commenting fallback. (significantly improves readability of some nastier dex2jar output).
- Fix issue where unstructured code was failing to display a block.
- Minor fixes to synchronized block handling.
- Interface for plugin use
- Push literal manipulations when in recovery
- Gracefully handle messed up Scala signatures. Multiple improvements to allow better emission of ScalaJava.
- Finally decode unicode literals nicely. (or leave it as it was with - --hideutf false)
- Fix (oops!) instance of English spelling of synchroni(S|Z)ed. (Thanks Jwalter)
- Be more lenient when removing array indirection - helps recover when we've incorrectly merged stackvars.
- Fix instances of loops at top of case statements emitting Duff's device!
- Rebuild switch blocks after forcing a topsort.
- Fix bug caused by agressive 'through jump' pushing (regression in 0_53). (LoopTest47 - Thanks chrixian)
- Improve switch block contiguity checking
- Improve finally handling
- Allow LDC through aggressive synchronised exit removal.
- Avoid stack overflow on odd Scala anonymous classes
- Handle dodgy Scala generic signatures (If you want ScalaJavatm ;) )
- Improve aggressive exception aggregation
- Display multiple cases in a more sane way.
- Default iterated loop resugaring to java 5 (!), as a lot of test classes which require it are marked as 49.
- Admit in comments/summary.txt when we emit orphaned catch blocks.
- Much more aggressive exception block aggregation/expansion, in cases where we can prove the adopted instructions can't change semantics.
- Recovery enables lenient flag, to allow wierdly ordered exception handlers to get sorted.
- Fix regression - when moving blocks through a goto, update block start information - (otherwise a break out of a loop was being left as a GOTO, leading to unstructured code/fallback sorting.
- Fix stack overflow where a local class returns a new instance of itself.
- Fix bug which causes while loop to be pulled out of conditional in odd circumstances
- Fix bug which inverts test when a block is switched in a topsort (again, odd circumstances, but... :P )
- Handle enums implementing interfaces.
- Generate @Override annotations (if code was compiled for Java6+, and the class files for the super classes are available....) Disable with --override false (or force earlier java with --override true, if you feel odd).
- Remove support for disabling per method failure, unused.
- Tidy up errors a bit
- More minor typing issues
- Local classes were being treated as anonymous - oops! Pull out local classes correctly, define in as tight a scope as possible. (interesting tests InnerClassTest28 & InnerClassTest25)
- Fix possible infinite loop on confused finally detection
- Remove bad brace in enum definition (!) (Thanks kkiehne)
- Several more tweaks to handle the sheer horror that is eclipse. Who needs an obfuscator? Most CFR tests are now happy with eclipse. (Some sync ones still grumpy)
- Finally removed hack which stops (local) a = i[x], if (a) being rolled into the conditional if appropriate. (Was causing iterator loop rewriting to fail).
- Misc control flow improvements to tidy dex2jar decompilation
- Fix NPE where attempting to resolve a typeclash with incomplete information (output code will be odd but readable!)
- Fix bug whereby a package-free class gets the class name as its package. (oops.) (Thanks Adrian)
- Handle (one) case where topsorting introduces confusing ordering, and made things worse!
- Added --eclipse option to allow disabling of transforms which normalise eclipse output (enabled by default)
- Fixed gnarly generic bug which failed to select (or selected non-deterministic) specific type instance for generic binding. (In rare circumstances!)
- Handle eclipse style loops. (step 1, more to go maybe!) (Thanks nkniazev)
- --recover option stops any attempt to override with extra options in