1
0
Fork 0
mirror of https://github.com/Vineflower/vineflower.git synced 2026-06-05 21:54:13 +02:00
Modern Java decompiler aiming to be as accurate as possible, with an emphasis on output quality. Fork of the Fernflower decompiler. https://vineflower.org
  • Java 98.7%
  • Kotlin 1.2%
Find a file
Jasmine Karthikeyan b8273988af
Release 1.12.0 (#566)
* Start 1.12.0

* [Kotlin] Fix some generics issues

* Reduce filesizes, update Kotlin metadata to 2.1.20 (#473)

* Reduce filesizes, update Kotlin metadata to 2.1.20

* Fix issue with unintended additional metadata removals

* [Kotlin] Fix full decompiler crash caused by missing Protobuf classes in metadata jar

This was a fix from regenerating after 592068d931

* Fix do while loops inside of other loops being negated (#486)

* Fix do while loops inside of other loops

* Fix testjava11stringconcat

* Fix test4

* Adjust publishing for new Central endpoint (#490)

* chore(build): Adjust publishing for new Central endpoint

* chore(build): Bump test-only deps, use lazy task realization in a few places

* chore(build): gradle 9.0.0

* Get children methods for vararg calls (#483)

* Recursively get methods through getMethodRecursive

* fix test

* bump ci

* Improve decompiling fields (#482)

* Clean up field writing to reduce redundancies

* Add line numbers to field declarations when feasible

* Port changes to Kotlin plugin

* Revert failing tests

These reverted versions fail on my machine, but Actions might think otherwise

* Handle Kotlin's statements and their frequent sugar (#472)

* [Kotlin] Add support for downTo, fix non-KExprent instances in other "do" statements

# Conflicts:
#	plugins/kotlin/src/main/java/org/vineflower/kotlin/stat/KDoStatement.java
#	plugins/kotlin/testData/results/pkg/TestForRange.dec
#	plugins/kotlin/testData/results/pkg/TestFunVarargs.dec
#	plugins/kotlin/testData/results/pkg/TestNonInlineLambda.dec

* [Kotlin] Improve for-loop resugaring

* [Kotlin] Fix objects, companion object members, and whitespace

* [Kotlin] Update tests

* Subclass statement types instead of a custom one in its entirety

* Add tests for compiling a `when` statement to switch blocks

* Modify exprent replacement logic

* Add accessibility to some private members

* `switch` statement decompilation to `when`

* Update test results and statement stuff after merge

* Fix jmpWrapper calls, add `if` statement support

* Update tests

* Fix some instances of odd spacing in `when` blocks

I should look into this more and see why it's seemingly quite inconsistent

* Add test cases to `TestWhen`

* Even more `when` tests

* Fix additional `when` issues

* Update test case

* Reconfigure Kotlin variable references for more versatility in the many ways they're used

* Add replace stats pass

This existed prior to the rebase, but something went amiss and I'm not quite sure what

* Be more lenient on allowed loops

This also fixes a potential issue where `repeat` would be generated despite counting down

* Fix plugins not loading when a ZipFS has already been opened for the current Jar (#475)

* Add flag to detect wrong variable merges (#477)

* Add flag to detect wrong variable merges

* Copy dec file from ci

* Add checks for generic types and discard any unexpected types (#430)

* Add corrupted signature test

* Add mismatched generics catches

* Fix all the cases where the tests indicated I messed up

Also upload the intended test result for TestCorruptedSignatures

* Delegate semicolons to plugins when possible (#471)

* Delegate statement semicolon appending to plugins when possible

* Update Kotlin tests (now without semicolons)

* Add cautionary tale

* Compact canonical constructor support (#484)

* Add support for compact constructors

* Support private constructors

* Cleanup

* comment

* Rename method

* Remove public + static from class definitions in interfaces (#491)

* Remove public + static from class definitions in interfaces

* Fix tests

* Fix build

* Improve annotation formatting (#497)

* Fix desync of exception tracking (#494)

* Be more forgiving when parsing arguments for paths (#493)

Instead of counting the non-options and using that to determine the last
file path for the destination, instead store the last file path and
process that lazily.

This accounts for the cases where a single 'pseudo-options' (--only,
--silent, --add-external) is specified alongside a single file path,
where it previously incorrectly determined the file path to be the
destination.

This also accounts for the case where pseudo-options are specified at
the end of the command-line invocation, rather than before all file
paths.

Fixes #492

* Add new test

* Properly fix bug that led switch on string to produce null with tableswitches

* Remove field debug, fix lambda CME, and try to improve nested lambda var handling

* Initial if statement prettifier based on heuristics

* Attempt to appease Github Actions

* Fix generic erasure for nested generics and add test cases (#503)

* Add type annotations test, always run gradle tests

* Implement type annotations

* Fix writing array types with type annotations

* Fix generic erasure for lambdas (#504)

* Account members for enum + hide private for enum constructors (#502)

* Account members for enum, + hide private for enum constructors

* Revert test

* Fix terrible merge

* Fix exception variables losing their LVT

* Make stack processing keep track of the lvts that it replaces

* Add nodebug lvt test, fix some NPEs

* Cleanup, document, and improve variable processing

* Refactor the way bytecode offsets are tracked.

* Split SimpleInstructionSequence and FullInstructionSequence
* Remove usages of VBStyleCollection
* Instructions now track their own bytecode offsets.

* Don't inline returns in switch expressions

* Undo test change

* Rename illegal methods at callsites, don't write illegal variable names

* Add comma separation support to -e and --only, improve class allowlisting

* Fix improper elision of varargs, always cast nulls in varargs

* Fix wrong method being called for overloads with arrays

* Cleanup bugs in previous patches

* Fix IOOBE

* Fix string concat with 1 element not being recognized

* Don't crash when encountering condys in indys

* Properly propagate upper bounds through ternaries

* Fix int constants in ternaries becoming chars, fix cases of lower > upper bound in type analysis

* Make assertion into validation again

* Modify Kotlin flag handling (#474)

* Convert to using metadata's Flags util class universally

Modified metadata jar made in 5bd17512ff

* Fix incorrect `inline` treatments

Also whoops classes never had `inline` (they've had `value` this whole time)

* Update metadata to 2.2.20

* Fix a bunch of incorrect variables (#507)

* add catchtempvar

* Fix synchronized and foreach

* Fixes for record pattern matching and fix for synchronized block

* Fix switch on string

* Fix try with resources that only reference a variable

* Some more fixes

* Update tests

* Update tests again

* Update TestLVTReassignmentNoDebug

* Fix TestDoubleForEach

* Fix switch pattern matching

* Fix switch tests

* Fix TestSwitchPatternMatching21

* Fix TestSwitchPatternMatching6

* Update kotlin tests

* Add some comments and improve synthetic variable detection on enum
switches

* Add comments

* Add monitor bytecode offsets and comment about broken test

* Fix multi exception catches losing their type, write them in the right order

* Fix writing text token class names

* Fix errors in Kotlin's decompilation caused by 31d9e1c5ca (#511)

* Close copyEntry output streams, reorganize tests

* Fix LVT names being used when LVT names are disabled

* Add unknown variable test

* Fix parsing error with switches inside a finally

* Fix tests

* Fix many validation bugs

* Unify and optimize try with resources processing

* Fix errors from decompiling Kotlin classes (#513)

* Fix the generics checker crashing on mismatched generic counts

* Don't handle bytecode offsets in KProperty
they're already handled by KotlinWriter whoops

* Try to fix generics erasure from synthetic parameters

* Allow for mismatches on the assumption it won't crash and burn as a result

* Unify try merging, fix stat/expr toString changing imports

* Remove getSequentialObjects

* Fix infinite loop in generic arg mapping

* Fix array type assertion in invocation type inference

* Fix NPE in generics processing

* Test `lcmp`, `fcmp` and `dcmp` to `boolean` in TestNumberCompareToBoolean (#518)

* test: Test `lcmp`, `fcmp` and `dcmp` to `boolean` in TestNumberCompareToBoolean

All the tests are functionally `number == number && number != 0`, baking in a NaN check.

For the extra curious, the NaN checks in the floating point tests work by taking advantage
of the same fcmp insn will always send NaN to 1 or -1, allowing for xor to collapse it to 0.

`iconst_1`, `iand` are evidently redundant but can be helpful if you need to strictly fit in one bit.

* test: Add commented decompiled sequences to TestNumberCompareToBoolean

* Add more unit tests

* Prefix counter to exported dot files, so they appear in chronological order (#520)

* Prefix counter to exported dot files, so they appear in chronological order

* Use CounterContainer

* Use remapped Kotlin metadata

* Aggressively optimize Kotlin metadata size

* Show try catch blocks in bytecode dump

* Add Java 25 tests and PPMM tests

* Include Java Runtime classes by default

* Use the right index for writing type annotations

* Add --method-to-decompile option (#519)

* Move metadata out of global state (#515)

* De-globalize Kotlin metadata

* Add missing null checks

* Move wrapper requirements to support earlier extra parsing

* Pull higher-level objects into Kotlin metadata attribute

* Refactor struct attributes, optimize attribute construction

* Add more record tests, move some processor packages

* Fix patterns with primitives and nested patterns in a switch (#530)

* Fix patterns with primitives and nested patterns in a switch

* Remove debug print

* Add a list for StatEdges to remove

* Remove synthetic Objects.requireNonNull from constructors

* Add dark theme for dot exports (#526)

* Fix primitives in pattern with an if statement with `false` (#531)

* Fix primitives in patterns when the if statement has `false`

* Add null check

* Add test

* Add tests for java 25 method references

* Add more method reference tests

* Remove ARM checks to fix old Java tests

Foojay Disco API supports aarch64 builds of Java 9 and 10 for Linux, and Gradle supports x86_64 builds on macOS

* Add support for markdown javadoc (#533)

* Add helper case functions (#545)

* feat: Add helper case functions

Signed-off-by: aoqia <aoqia@aoqia.dev>
(cherry picked from commit decdb6efbe849567c4dbb01bf82a653cf39e2b80)

* docs: Add method docstrings for case helper methods

Signed-off-by: aoqia <aoqia@aoqia.dev>

* refactor: Use variable instead of redundant check

Signed-off-by: aoqia <aoqia@aoqia.dev>

* fix: Place default case at start instead of end

Signed-off-by: aoqia <aoqia@aoqia.dev>

* style: Remove accidental whitespace

Signed-off-by: aoqia <aoqia@aoqia.dev>

* style: Remove unnecessary annotations

Signed-off-by: aoqia <aoqia@aoqia.dev>

* style: Make method a little more readable

Signed-off-by: aoqia <aoqia@aoqia.dev>

* refactor: Remove uses of final and var

Signed-off-by: aoqia <aoqia@aoqia.dev>

---------

Signed-off-by: aoqia <aoqia@aoqia.dev>

* Improve synthetic non-null checks generated by modern javac

* Cleanup redundant requireNonNull checks

* Inline synthetic vars before method reference lambdas

Co-Authored-By: coehlrich <coehlrich@users.noreply.github.com>

* Remove dead code

* Using pattern matching (#546)

* Using pattern matching

* Remove extra indentation

* Remove extra indentation and further cleanup

* Kotlin: decompile most lambdas and anonymous objects (#525)

* De-globalize Kotlin metadata

* Add missing null checks

* Move wrapper requirements to support earlier extra parsing

* Pull higher-level objects into Kotlin metadata attribute

* Initial work on Kotlin lambdas

* Handle lambda classes, mostly

* Fix zero-parameter formatting

* Fix post-merge issues

* Handle lambdas a bit better

* Improve exit detection

* Function reference support

* Anonymous object hack

* Fix wrong parameter names, add ignored parameters test

* Revert removing some requireNonNull checks

* Properly implement assert decompilation

- Fixed asserts in interface default methods not decompiling
- Fixed assignment asserts not decompiling properly
- Removed empty space between asserts
- Fixed asserts being pulled into loops
- Fixed if statements with a single assert from creating an invalid assert
- Added support for marking improper assert decompilation

* Fix invalid ppmm creation with floats and doubles

* Simplify break structure for string switches (#544)

* feat: Simplify break structure for string switches

As a reference, this is found in TestEclipseSwitchString.

Signed-off-by: aoqia <aoqia@aoqia.dev>
(cherry picked from commit cedf7038ae024272afb1df281a6fbb8fb9e6871d)

* style: Use 2 spaces indent

Signed-off-by: aoqia <aoqia@aoqia.dev>

* feat: Improve exit helper break structure

Signed-off-by: aoqia <aoqia@aoqia.dev>

* fix: Prevent if statements without a basichead from being processed

Signed-off-by: aoqia <aoqia@aoqia.dev>

* style: Remove left-in note tag

Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* refactor: Change variable names and comments for clarity

Signed-off-by: aoqia <aoqia@aoqia.dev>

* docs(code): Clean up some code comments

Signed-off-by: aoqia <aoqia@aoqia.dev>

* style: Invert if guard for parity with rest of func

Signed-off-by: aoqia <aoqia@aoqia.dev>

* chore: Add null check and nullable

Signed-off-by: aoqia <aoqia@aoqia.dev>

---------

Signed-off-by: aoqia <aoqia@aoqia.dev>
Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* Fix pattern match asserts from dropping code

* Fix NPE in assert processing

* Add include classes option and external test

* Fix missing successor in ExitHelper

* Fix exprent list NPE in ExitHelper

* Fix infinite looping during generics checking (#549)

* Fix crashes when encountering CONSTANT_MethodType

* Fix incorrectly renamed variables (#551)

* Fix incorrectly renamed variables

* Fix switches and tests

* Fix test

* Handle object construction and related constructs (#550)

* Handle object construction (in theory) universally

* Fix array creation

* Fix array creation in annotation class declarations

# Conflicts:
#	plugins/kotlin/src/main/java/org/vineflower/kotlin/KotlinWriter.java

* Fix foreach loop creation when iterator is used afterwards

* Fix unit test

* Fix finally processing in plugins (#554)

* Fix missing if successor after loop elimination

* Fix regression with patch

* Kotlin metadata rework, part 2 (#552)

* Metadata rework p2: metadata now lives with the objects they represent!

this is largely for allowing invocation exprents and such resugar into their Kotlin counterparts much more easily (less guessing)

* Hide EnumEntries synthetic field

* Fix issues stemming from companion object fields

* Fix specific oddities relating to property backing field identification

* Fix crashes from unsigned constants

* Improve plugin support and hooks (#523)

* Changes to plugins

* More plugin work, add root processor support

* Improve class pass api

* Fix merge

* Fix unit tests

* [Kotlin] Fix regressions from metadata rework

* Kotlin properties and infix functions (#556)

* Property access test

* Add property and infix fun support

* Fix crashes from static method calls

* Fix precedence for properties

* writing code is hard

* Missed a test?

* Decompile Kotlin's JVM multifile classes (#557)

* Multi-file decompilation

* Add multifile test

* Add tests for finally vars

* Recognize iinc in finally block

* Fix NPE in Kotlin annotation processing

* Add test for switch pattern matching with string

* Improve heuristic for creating for loops

* Fix NPE in mapGenVarsTo

* Fix empty super() not removed when constructor has label

* Fix stack vars processing unable to inline into foreach loops

* Fix incorrectly renaming pattern match variables (#555)

* Fix incorrectly renaming pattern match variables

* Add test and indent switch

* Avoid pruning most user written variables with no use

* Identify more ternaries and ppmm in Kotlin, add newline for labeled ifs

* Don't inline variables in StackVars if the target is ppmm

* Fix NPE when checking generics

* Reduce the amount of exported dots

* Rewrite string-switch processing (#558)

* chore: Move changes over from feat/string-switch-rewrite

* fix: Dup var not being found sometimes

* chore: Generate test dec

* chore: Add test dec changes

* refactor: Remove now-useless code

* fix: Default case edge not being added with addCase

* style: Remove noinspection IDEA comment

Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* refactor: Remove unnecessary block

* style: Remove comment

Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* style: Remove extra whitespace

Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* style: Remove accidental formatting

* chore: Revert implementation of VBCollection#remove

* refactor: Remove all usage of Optional

* style: Remove name and commit hash in comment

fix: Add an extra null check just in case

* fix: Use removeWithKey instead of deprecated remove

* refactor: Use removeCase helper function

---------

Co-authored-by: Jasmine Karthikeyan <25208576+jaskarth@users.noreply.github.com>

* Add Automatic-Module-Name to the manifest (#559)

* add Automatic-Module-Name to both slim and all jars

* Change the module name to match fernflower

* Fix not being able to find the while true loop for switches with a (#561)

return

* Inline returns in try with finally (#562)

* Inline returns for try with resources

* Inline returns in finally

* Remove unused label

* Add return positioning test for try with resources and add support for
inline returns when the try with resources has multiple resources

* Update tests

* Revert "Update tests"

This reverts commit 194f89d67c.

* Revert "Add return positioning test for try with resources and add support for"

This reverts commit d1dcacef9f.

* Revert "Inline returns for try with resources"

This reverts commit d39ce608c9.

* Fix switch expressions not being inlined when none of the case statements directly contain `yield` (#563)

* Fix switch expressions not being inlined when none of the case
statements directly contain `yield`

* Removed old loop

* Update TestUnknownCastJ17

* Add plugin hook just before decompilation

* Allow for introspection of units

* Implement return inlining for try-with-resources

Co-authored-by: jaidaken <jamiehewitt@pm.me>
Co-authored-by: coehlrich <coehlrich@users.noreply.github.com>

* Add PR templates and clarify AI policy

* Fix index out of bounds with switch-on-string with null

* Fix NPE in clashing var remapping

* Fix NPE in kotlin for each loop processing

* Fix Kotlin NPE with companion classes

---------

Signed-off-by: aoqia <aoqia@aoqia.dev>
Co-authored-by: sschr15 <steven.sschr15@hotmail.com>
Co-authored-by: coehlrich <coehlrich@users.noreply.github.com>
Co-authored-by: zml <zml@stellardrift.ca>
Co-authored-by: Owen <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: shartte <shartte@users.noreply.github.com>
Co-authored-by: Kroppeb <7889478+Kroppeb@users.noreply.github.com>
Co-authored-by: Joseph Burton <burtonjae@hotmail.co.uk>
Co-authored-by: sciwhiz12 <sciwhiz12@gmail.com>
Co-authored-by: Ampflower <ampflower@outlook.com>
Co-authored-by: aoqia194 <30682549+aoqia194@users.noreply.github.com>
Co-authored-by: aoqia <aoqia@aoqia.dev>
Co-authored-by: TropheusJ <60247969+TropheusJ@users.noreply.github.com>
Co-authored-by: jaidaken <jamiehewitt@pm.me>
2026-04-28 20:12:35 -04:00
.github Add PR templates and clarify AI policy 2026-04-27 18:54:14 -04:00
buildSrc Adjust publishing for new Central endpoint (#490) 2025-11-02 00:32:01 -04:00
gradle/wrapper Add Java 25 tests and PPMM tests 2025-11-18 13:26:42 -05:00
plugins Fix Kotlin NPE with companion classes 2026-04-28 18:02:14 -04:00
src Fix Kotlin NPE with companion classes 2026-04-28 18:02:14 -04:00
test/org/jetbrains/java/decompiler Fix switch expressions not being inlined when none of the case statements directly contain yield (#563) 2026-04-14 08:52:33 -04:00
testData Fix index out of bounds with switch-on-string with null 2026-04-27 20:26:15 -04:00
testFixtures/org/jetbrains/java/decompiler Include Java Runtime classes by default 2025-11-18 17:56:04 -05:00
.editorconfig [java decompiler] updates Gradle project 2017-11-28 15:42:02 +01:00
.gitattributes Quick dependency refresh (#427) 2024-09-04 21:31:01 -07:00
.gitignore Add gitignore and improve support for Eclipse and VSCode 2023-10-16 22:45:15 +01:00
ARCHITECTURE.md Make attributes and savers more extensible, improve readme 2025-11-04 19:02:29 -05:00
build.gradle Add Automatic-Module-Name to the manifest (#559) 2026-04-08 22:40:12 -04:00
CONTRIBUTING.md Add PR templates and clarify AI policy 2026-04-27 18:54:14 -04:00
gradle.properties Adjust publishing for new Central endpoint (#490) 2025-11-02 00:32:01 -04:00
gradlew Adjust publishing for new Central endpoint (#490) 2025-11-02 00:32:01 -04:00
gradlew.bat Adjust publishing for new Central endpoint (#490) 2025-11-02 00:32:01 -04:00
LICENSE.md Add contributing and architecture 2021-06-11 16:53:39 -04:00
README.md Make attributes and savers more extensible, improve readme 2025-11-04 19:02:29 -05:00
settings.gradle Adjust publishing for new Central endpoint (#490) 2025-11-02 00:32:01 -04:00

Vineflower

Vineflower is a modern general purpose Java & JVM language decompiler focused on providing the best quality, speed, and usability.

Vineflower's features include:

  • Java 21+ support, including records, sealed classes, switch expressions, pattern matching, and more
  • Clean code generation and output, with automatic output formatting
  • Multithreaded decompilation

Examples of Vineflower's output compared to other decompilers can be found on the website.

Use

Vineflower can be used from the console or as a library. To run Vineflower from the command line, download the latest release from the Releases tab. You can then run Vineflower with java -jar vineflower.jar <arguments> <source> <destination>. <arguments> is the list of commandline arguments that you want to pass to the decompiler. <source> can be a jar, zip, folder, or class file, and <destination> can be a folder, zip, jar, or omitted to print to the console.

To use Vineflower as a library, you can find distributions on maven central. Vineflower 1.9+ requires Java 11 or higher to run, and Vineflower 1.11+ requires Java 17 or higher to run. Vineflower can be addded as a dependency in gradle with:

dependencies {
    implementation 'org.vineflower:vineflower:<version>'
}

More instructions on how to interface with Vineflower can be found on the website.

For IDE use, the Vineflower Intellij IDEA plugin replaces Fernflower in IDEA with Vineflower.

Please report any issues to the Issues tab!

Building

Vineflower can be built simply with ./gradlew build.

Support

For support or questions, please join one of the listed social platforms.

Contributing

Contributions are always welcome! The website has detailed instructions on how to set up Vineflower development, as well as information on debugging. When submitting pull requests, please target the latest develop/1.xx.y branch.

Special Thanks

Vineflower is a fork of Jetbrains' Fernflower, MinecraftForge's ForgeFlower, FabricMC's fork of Fernflower, and a direct continuation of work on Quiltflower. Special thanks to:

  • Stiver, for creating Fernflower
  • JetBrains, for maintaining Fernflower
  • MinecraftForge Team, for maintaining ForgeFlower
  • FabricMC Team, for maintaining Fabric's fork of Fernflower
  • CFR, for its large suite of very useful tests