47 Commits
Author SHA1 Message Date
Siegfried Pammer d4d430ebe4 Avoid debug assert message allocations
Debug assertions should not allocate formatted messages on successful checks. Route interpolated assertion messages through a DEBUG-only handler so the message is built only when the assertion fails.

Assisted-by: OpenCode:openai/gpt-5.5:OpenCode
2026-10-10 18:34:40 +02:00
Siegfried Pammer 9b16bf3edb Decide extension method syntax in CallBuilder
Every other decision about how a member reference is spelled is made
while the expression is built, behind Disambiguator, and CallBuilder
already writes target.ExtensionMethod for delegate references and method
groups. Extension calls were the last spelling decided afterwards, by an
AST transform that had to rebuild a resolver from a UsingScope
annotation on the tree root and re-derive every argument's resolve
result from AST annotations.

The check now runs against the resolver ExpressionBuilder already owns,
whose using scope is the namespace superset the DecompileRun collected
from the IL. That superset is wider than the imports actually printed,
so it can only refuse infix syntax where the transform allowed it, never
bind a call to a different overload.

Two consequences had to be handled. The declaring type is no longer
named anywhere once the call is infix, so IntroduceUsingDeclarations
would not have imported its namespace and the output would not compile;
it now imports from the invocation itself. And an extension GetEnumerator
in infix form is spelled like an instance call, so the foreach matcher
can no longer read a plain match as an instance method.

Writing the receiver as the target means skipping an argument, which the
argument list only supported where there were neither names nor optional
arguments: it skipped before trimming the optional tail, so a skip past
an omitted argument took one argument too many, and it gave up entirely
on names. Both now skip after trimming, which also settles a latent
off-by-one on the collection-initializer path.

Assisted-by: Claude:claude-opus-5:Claude Code
2026-09-21 16:58:00 +02:00
Daniel Grunwald c760a1d622 Fix "Remove redundant comp(... != 0)" to avoid changing the value
When an IfInstruction was created with resultType=bool, because only
values 0 or 1 are possible, then we need to preserve this property in
transforms -- otherwise the added correctness test would fail.
2026-09-13 11:57:46 +02:00
Siegfried Pammer 48fcf0313e Move UsingScope and CSharpTypeResolveContext into the type system
Both types are consumed well outside the C# output layer - DecompileRun
carries the using scope, and the IL transforms build a resolve context from
it - so living in ICSharpCode.Decompiler.CSharp.TypeSystem misrepresented
where they belong and forced a C#-specific namespace import on every
consumer.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
2026-08-15 11:03:10 +02:00
Siegfried Pammer d3517739ff Add fine-grained C# AST debug steps
Record AST transform groups and mutation steps through the C# pipeline, replay selected steps with the stepper, and carry modified-node ranges through output so the Debug Steps pane can highlight the selected mutation without replacing its full step tree.

Assisted-by: CodeAlta:gpt-5.5:CodeAlta
2026-07-02 01:08:51 +02:00
Siegfried Pammer ed61b8a14e Replace the SlotKind enum with object-identity Slots kinds
The slot kind is now the canonical typed CSharpSlotInfo<T> in Slots, matched by
object identity (the IL SlotInfo model), instead of a parallel SlotKind enum.
CSharpSlotInfo.Kind points at the canonical shared slot; a Slots constant is its
own kind (null Kind, never read -- only per-node slots are asked for their kind),
so there is no self-reference. Child access (GetChild/GetChildren/SetChild,
GetCollectionByKind, AddChild/InsertChild) and the polymorphic
node.Slot.Kind == Slots.X comparisons key on the canonical reference; the
generated SlotKind enum is removed. No behavior change.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
Siegfried Pammer b0c8b7b2e5 Enable nullable reference types across the remaining C# Syntax files
Completes the nullable migration for ICSharpCode.Decompiler/CSharp/Syntax: every
hand-written file now carries #nullable enable. The pattern-matching API
(INode/Pattern/PatternExtensions DoMatch/Match/IsMatch) takes a nullable 'other',
since matching legitimately compares a pattern against a missing child. Members
that genuinely return or accept null are annotated to match (AttributeSection's
target token, IAnnotatable.Annotation<T>, Statement/Expression.ReplaceWith,
SyntaxExtensions.GetNextStatement), and a latent null dereference in
Backreference.DoMatch is fixed.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
Siegfried Pammer 9285a7328d Delete the Role hierarchy; key the child API on SlotKind
Slot identity already lived in node.Slot/CSharpSlotInfo/SlotKind after
the storage flip, so the parallel Role/Role<T> child model was redundant.
The Role-keyed mutation/query API is reexpressed over SlotKind, and the
role-index packing on AstNode flags is gone.

Because a node's Slot is now derived from its index in its parent rather
than stored on the child, the located-AST reattach in
InsertMissingTokensDecorator must capture the child's slot kind before
Remove() detaches it.

Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
Siegfried Pammer 785e36712d Enable nullable reference types across the C# transforms
Turn on #nullable enable across the AST transform pipeline, ahead of
annotating the slot properties themselves. TransformContext now exposes the
nullable CurrentMember/CurrentTypeDefinition/CurrentModule contract already
declared by ITypeResolveContext, and the generated pattern-to-node conversion
returns a non-null node so patterns can be used in collection initializers
without warnings. No IL changes.
Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
Siegfried Pammer 77d57b91dc Drop token nodes and move comments and directives to trivia
Comments and preprocessor directives were positional children interleaved
into the child list, and punctuation, keywords and operators were token-node
children. Add a leading/trailing trivia side-channel for comments and
directives, emit it from the output visitor, and re-home every comment
receiver onto it (including inside-block comments as comment-only empty
statements and undecodable attribute arguments as an ErrorExpression). With
locations and sequence points no longer sourced from token nodes, stop
reconstructing them on the locations path and delete CSharpTokenNode,
CSharpModifierToken and InsertSpecialsDecorator. The AST no longer carries
token children or positional comments; output is byte-identical.
Assisted-by: Claude:claude-opus-4-8:Claude Code
2026-06-23 07:43:42 +02:00
mmusu3 88b2c437a7 Address PR review feedback 2025-11-20 23:23:35 +10:00
mmusu3 22ceb6e7d1 Fix remaining cases with changes to IntroduceUsingDeclarations. 2025-11-20 10:57:42 +01:00
Peter Crabtree e1e16b64f5 dev: Strip BOM mark from text files 2025-08-28 20:56:19 -04:00
Siegfried Pammer 9dde97414a Rename ResolvedUsingScope to UsingScope 2025-08-02 11:02:25 +02:00
Siegfried Pammer c9e3790adc Remove UnresolvedUsingScope 2025-08-02 11:00:31 +02:00
Siegfried Pammer 6c08851cb0 #3209: Only add imports for extension methods. 2024-06-10 00:26:22 +02:00
Siegfried Pammer 972354913e Fix #3209: Ensure using directives are added for extension methods in higher level patterns such as: foreach -> GetEnumerator(), collection initializer -> Add() and deconstruction -> Deconstruct(). 2024-06-09 19:43:36 +02:00
Siegfried Pammer ee160b4e2a #3075: Improve performance of CSharpResolver.LookupSimpleNameOrTypeName in cases with a large number of local variables. 2023-10-14 23:11:52 +02:00
hexafluoride fc6ae4c645 Add option to always fully qualify type names with global:: 2022-08-30 16:15:42 +02:00
Siegfried Pammer a655e35799 Fix ArgumentNullException in IntroduceUsingDeclarations: ignore unnamed variables for the purpose of conflict resolving. 2021-11-17 22:25:58 +01:00
Siegfried Pammer f245d93fef #2128: Adjust formatting settings used in tests to match our new style. 2020-08-28 01:21:05 +02:00
dotnet format 0d9f871a4f #2128: Reformat the whole code base. 2020-08-28 01:05:38 +02:00
Siegfried Pammer df84ab8f6b Fix #1882: Provide a setting to desugar X? into Nullable<X> for value types 2020-02-27 20:43:44 +01:00
Siegfried Pammer 83c525c1c2 Fix #1758: Input var name conflicting with framework class name 2019-10-25 23:20:51 +02:00
Siegfried Pammer 71ffb0183b Fix #1103: Deactivating "Insert using declarations" now uses fully qualified types everywhere. 2018-07-20 19:57:00 +02:00
Daniel Grunwald b396d203bd Merge IDecompilerTypeSystem with ICompilation. 2018-07-14 16:50:36 +02:00
Daniel Grunwald 3b46776c5e Rename IAssembly -> IModule.
While support for multi-module assemblies isn't fully working yet; it is clear at this point that we want
to treat each module in a multi-module assembly separately for the purposes of the type system.
2018-07-13 22:20:49 +02:00
Siegfried Pammer c7c3801ff1 Add TypeSystemAstBuilder.ConvertAttributeType, which deals with all the special cases when referring to attribute types in attribute context. 2018-06-21 16:07:29 +02:00
Siegfried Pammer 023282a50d #1180: Add IsWindowsFormsInitializeComponentMethod and disable some transforms when processing a Windows Forms InitializeComponent method. 2018-06-19 23:06:33 +02:00
Siegfried Pammer a06a04d48b #1080: Add ILTransformContext.RequiredNamespacesSuperset 2018-03-10 02:44:26 +01:00
Siegfried Pammer cdd12ba33b Fix #962: NullReferenceException when setting FullyQualifyAmbiguousTypeNames=false 2017-11-01 23:48:18 +01:00
Daniel Grunwald 7cacd005a6 When decompiling a single method, don't fully-qualify type names in the current namespace. 2017-10-15 21:41:16 +02:00
Siegfried Pammer 9ab7651201 Fix #895: Wrong decompilation of references to inner struct in class. 2017-10-02 20:57:54 +02:00
Siegfried Pammer 112142f147 Handle Settings.UsingDeclarations and Settings.FullyQualifyAmbiguousTypeNames correctly. 2017-09-12 23:06:10 +02:00
Siegfried Pammer dc0a3d0703 Add IntroduceExtensionMethods transform 2017-08-28 17:25:51 +02:00
Daniel Grunwald b254ff667f Remove special case always adding 'using System;' 2016-11-26 16:51:23 +01:00
Siegfried Pammer d8a2d41e83 Added support for ConditionalAttribute 2016-11-26 14:07:06 +01:00
Siegfried Pammer 840ec04fde Namespace adjustments for Syntax classes 2016-11-26 12:06:58 +01:00
Christoph Wille 1ce8349dd9 Adjust namespaces 2016-11-26 11:12:53 +01:00
Daniel Grunwald d4d871631c Fix disambiguation of type names. 2016-06-22 22:34:49 +02:00
Siegfried Pammer bed48beb3d fix unit tests 2015-06-13 16:57:36 +02:00
Siegfried Pammer 5ef12f60c8 simplify FullyQualifyAmbiguousTypeNamesVisitor 2015-06-11 21:44:49 +02:00
Siegfried Pammer 80cebbe448 fix bug in IntroduceUsingDeclarations: use matching ITypeResolveContext for each namespace and type 2015-06-09 22:14:15 +02:00
Siegfried Pammer f554a26a2b replace ambiguous type names with FQNs 2015-06-09 19:28:40 +02:00
Daniel Grunwald 08a5e81517 Re-enable IntroduceUsingDeclarations 2014-11-16 15:41:35 +01:00
Daniel Grunwald fffa297b8f Use ResolveResults as annotations. 2014-11-15 15:53:27 +01:00
Daniel Grunwald e0a1666547 Add back AST transform infrastructure 2014-09-21 12:22:47 +02:00