In this point release, we kept focussing on improving decompilation accuracy and performance (raw performance as well as memory usage) across the board. This is why again a lot of work went in the category Testing / Infrastructure.
One major performance win to point out is that we now ship ilspycmd with native AOT packages for linux-x64 and win-x64. Measured on win-x64 against the same 3 MB input (ICSharpCode.Decompiler.dll), medians of five runs:
| Call shape | managed tool | AOT package |
|---|---|---|
--version | 219 ms | 45 ms |
-l c (list classes) | 384 ms | 93 ms |
--type one large class | 1,446 ms | 199 ms |
--type one small class | 1,797 ms | 315 ms |
-p whole project (881 files) | 6.3 s | 2.9 s |
For an agent loop that spawns ilspycmd per question that is a 4x to 7x reduction per call!
New Features
- PR #4248: Add a search box to the Options tab
- PR #4241: Add opt-in RID-specific and Native AOT packages for ilspycmd
- PR #4197: Add cross-platform PDB dumping to ilspycmd
Enhancements
- PR #4268: Native AOT fidelity follow-up: resolver lookup, culture independence, gate coverage
- PR #4259: Native AOT fidelity for the ICSharpCode.Decompiler package
- PR #4256: Make ilspycmd -il honor the --type and --member selection
- PR #4247: Report ilspycmd usage mistakes instead of crashing
- PR #4236: Transform
value.<Clone>$()intovalue with {}even if there are no initializers - PR #4222: Improved decompilation support for VB.NET closures
- PR #4201: Rewrite VB WithEvents WinForms initialization
- PR #4160: Decide extension method syntax in CallBuilder
- PR #4188: Detect generated closure cache types
- PR #4185: Handle required members on record copy constructors
- PR #4179: Include member context in decompilation error comments
- PR #4171: Recognize metadata property backing fields
Testing / Infrastructure
- PR #4285: Fix decompdiff platform reference staging
- PR #4283: Improve Debug Steps and decompdiff workflows
- PR #4276: nugetfuzz: add parallelization + report caught exceptions
- PR #4274: Migrate ILSpy.sln to the SLNX solution format
- PR #4269: Cut the ILSpy.Tests wall clock: cheap fixtures, dead waits, duplicate tests, and process sharding
- PR #4261: Keep tests off the network unless a toolset download is actually needed
- PR #4255: Add top 500 NuGet package list
- PR #4254: Reenable LiftedOperators tests
- PR #4230: Add allocation trace viewer
- PR #4240: Use local .NET Framework assemblies in nugetfuzz
- PR #4235: Fallback from unsupported netcoreapp assets in nugetfuzz
- PR #4205: Clean up package restore (Diasymreader)
- PR #4187: Let decompdiff reports use full width
- PR #4184: Separate obfuscated names in nugetfuzz
- PR #4183: Stream nugetfuzz HTML report generation
- PR #4177: Index NuGet assemblies by contained name in decompdiff
Contributions
- PR #4253: Fix #3702: Don't rewrite GetValueOrDefault() to == true in ?. chains — @dualfroz, thank you!
- PR #4251: Fix #4017: Look through LdObjIfRef on the operand of await — @dualfroz, thank you!
- PR #4231: Fix #4135: Keep bool-to-int conditional in its local — @dualfroz, thank you!
- PR #4216: Add option to highlight usages of the symbol at the caret — @pieroviano, thank you!
- PR #4228: Fix #4153: keep foreach when a named argument inlines the loop variable — @LiquidSnake0, thank you!
- PR #4232: Fix #4137: Keep nint in conditionals with mixed native int branches — @dualfroz, thank you!
Performance
- PR #4266: Start the startup warm-ups before Avalonia's setup
- PR #3963: Substring optimizations: eliminate hot-path allocations (audit top 8)
- PR #4229: Avoid cloning settings for every method
- PR #4164: Coalesce the global command re-query
- PR #4157: Coalesce the assembly tree's selection and removal fan-out
Bug Fixes
- PR #4286: Apply type transformations to fake member signatures
- PR #4288: Fix exceptions on obfuscated code
- PR #4250: Fix #4245: Ignore find-panel clicks when resolving reference clicks
- PR #4249: Fix #4246: Scope prefixes no longer leak into search keywords
- PR #4225: Fix #2829: Emit continue for leave through try-finally
- PR #4223: Fix ResXResourceWriter empty output and type names
- PR #4220: Fix #3180: avoid invalid null-conditional extension calls
- PR #4206: Fix startup binding errors and background load sweep failure
- PR #4204: Keep package entry selections decompilable
- PR #4202: Fix mixed array initializers
- PR #4200: Reserve captured local names in declaring scope
- PR #4194: Fix UTF-8 literal span initializers
- PR #4181: Ignore missing runtime files in XML doc ref-pack lookup
- PR #4163: Ignore detached tree rows when showing selection
- PR #4178: Handle expression-tree null conversions
- PR #4182: Fix #4180: Parenthesize negated negative constants
- PR #4165: Do not apply cancelled decompilation output
For a full list of changes click here.
This release is based on .NET 10.0. Please make sure that you have it installed on your machine beforehand.
Note for Mac users: see https://github.com/icsharpcode/ILSpy/wiki/Build-Artifacts#running-the-macos-artifact because the ILSpy.app is neither signed nor notarized.
Want to learn how we do PR reviews these days? Check out Stampeded.