Browse Source

Say what the code does instead of which app did it first

A comment that justifies behaviour by pointing at the WPF front-end means
nothing to someone reading the file cold: the reason is either already stated
beside it or is not stated anywhere. Each of these now names the constraint
itself - why navigation waits for pointer-release, why a signature block wraps,
why the tree filter ignores the search term.

Comments citing an external product's documented behaviour as the source of a
rule are left alone; there the reference is the reason, not a memory of how the
code arrived.

Assisted-by: Claude:claude-opus-5[1m]:Claude Code
pull/3989/head
Siegfried Pammer 1 month ago committed by Siegfried Pammer
parent
commit
18d960e6b9
  1. 10
      ILSpy.Tests/AssemblyList/AssemblyTreeTests.cs
  2. 3
      ILSpy.Tests/Editor/DocumentationRendererTooltipWidthTests.cs
  3. 6
      ILSpy.Tests/Editor/ReferenceClickTests.cs
  4. 2
      ILSpy.Tests/Navigation/NavigationTests.cs
  5. 23
      ILSpy.Tests/Search/SearchTermFilterTests.cs
  6. 14
      ILSpy/Languages/CSharpLanguage.cs
  7. 9
      ILSpy/TextView/DecompilerTextView.axaml.cs
  8. 5
      ILSpy/TextView/DocumentationRenderer.cs
  9. 2
      ILSpy/TreeNodes/FieldTreeNode.cs

10
ILSpy.Tests/AssemblyList/AssemblyTreeTests.cs

@ -1604,12 +1604,10 @@ public class AssemblyTreeTests @@ -1604,12 +1604,10 @@ public class AssemblyTreeTests
[AvaloniaTest]
public async Task Active_Search_Term_Does_Not_Hide_Member_Tree_Nodes()
{
// Pre-existing port misstep: commit 45461ddde wired the search-pane's term into
// LanguageSettings.SearchTerm and made SearchTermMatches gate visibility on it.
// WPF intentionally makes SearchTermMatches a no-op (returns true) so the assembly
// tree stays independent of the search pane. After fixing parity, FieldTreeNode.Filter
// must NOT return Hidden purely because the field's name doesn't contain the active
// SearchTerm — only ShowApiLevel + ShowMember remain valid hiding criteria.
// SearchTermMatches is deliberately a no-op (returns true) so the assembly tree stays
// independent of the search pane. FieldTreeNode.Filter must therefore NOT return
// Hidden purely because the field's name doesn't contain the active SearchTerm —
// only ShowApiLevel + ShowMember remain valid hiding criteria.
var (_, vm) = await TestHarness.BootAsync();

3
ILSpy.Tests/Editor/DocumentationRendererTooltipWidthTests.cs

@ -40,8 +40,7 @@ namespace ICSharpCode.ILSpy.Tests.TextView; @@ -40,8 +40,7 @@ namespace ICSharpCode.ILSpy.Tests.TextView;
/// Pins the rendering shape of method-signature tooltips so a long signature isn't clipped
/// horizontally: the signature <see cref="SelectableTextBlock"/> must wrap. Created with
/// <see cref="TextWrapping.NoWrap"/>, text past the popup's MaxWidth is simply cut off,
/// because the outer ScrollViewer disables horizontal scrolling. WPF parity is
/// wrap-friendly, so we mirror that.
/// because the outer ScrollViewer disables horizontal scrolling.
/// </summary>
[TestFixture]
public class DocumentationRendererTooltipWidthTests

6
ILSpy.Tests/Editor/ReferenceClickTests.cs

@ -40,9 +40,9 @@ using NUnit.Framework; @@ -40,9 +40,9 @@ using NUnit.Framework;
namespace ICSharpCode.ILSpy.Tests.TextView;
/// <summary>
/// Pins the reference-link click gesture in the decompiled view (WPF parity): navigation
/// happens on mouse-UP and only when the pointer did not drag, so text that belongs to a
/// link can still be selected by press-and-drag.
/// Pins the reference-link click gesture in the decompiled view: navigation happens on
/// mouse-UP and only when the pointer did not drag, so text that belongs to a link can
/// still be selected by press-and-drag.
/// </summary>
[TestFixture]
public class ReferenceClickTests

2
ILSpy.Tests/Navigation/NavigationTests.cs

@ -197,6 +197,6 @@ public class NavigationTests @@ -197,6 +197,6 @@ public class NavigationTests
((string)baseTypesEntry.Header!).Should().Contain("Exception",
"the dropdown header must disambiguate generic grouping nodes via NavigationText");
((string)baseTypesEntry.Header!).Should().NotBe((string)baseTypes.Text,
"falling back to bare Text would reproduce the WPF parity gap");
"falling back to bare Text would leave the grouping nodes indistinguishable");
}
}

23
ILSpy.Tests/Search/SearchTermFilterTests.cs

@ -36,12 +36,12 @@ public class SearchTermFilterTests @@ -36,12 +36,12 @@ public class SearchTermFilterTests
[AvaloniaTest]
public Task SearchTermMatches_Is_A_No_Op_That_Always_Returns_True()
{
// Pins the WPF-parity contract: the search pane drives its own results via the
// ILSpyX search strategies; LanguageSettings.SearchTermMatches deliberately ignores
// SearchTerm so the assembly-tree filter cascade stays independent of the search
// pane. Without this, typing a term into the search box would hide tree rows whose
// names don't match it — including member rows under a type whose own name DOES
// match — because the cascade only resets the match bit one level deep.
// The search pane drives its own results via the ILSpyX search strategies;
// LanguageSettings.SearchTermMatches deliberately ignores SearchTerm so the
// assembly-tree filter cascade stays independent of the search pane. Were it to
// honour the term, typing into the search box would hide tree rows whose names don't
// match it — including member rows under a type whose own name DOES match — because
// the cascade only resets the match bit one level deep.
var settings = AppComposition.Current.GetExport<SettingsService>().SessionSettings.LanguageSettings;
try
@ -54,7 +54,7 @@ public class SearchTermFilterTests @@ -54,7 +54,7 @@ public class SearchTermFilterTests
settings.SearchTerm = "enum";
settings.SearchTermMatches("IEnumerable").Should().BeTrue();
settings.SearchTermMatches("Object").Should().BeTrue(
"WPF parity: SearchTermMatches must NOT honour the SearchTerm — it's a no-op shim");
"SearchTermMatches must NOT honour the SearchTerm — it's a no-op shim");
settings.SearchTerm = "ZZZ_NoMatchAnywhere";
settings.SearchTermMatches("Anything").Should().BeTrue();
@ -69,11 +69,10 @@ public class SearchTermFilterTests @@ -69,11 +69,10 @@ public class SearchTermFilterTests
[AvaloniaTest]
public Task Typing_In_The_Search_Pane_Does_Not_Bleed_Into_LanguageSettings_SearchTerm()
{
// The search pane is decoupled from the assembly-tree filter cascade. Earlier port
// commits pushed SearchPaneModel.SearchTerm into LanguageSettings.SearchTerm to drive
// a tree-filter cascade — that path hid member rows users expected to see (e.g. enum
// literals under their matched-by-name enum type). Reverted to WPF parity: typing in
// the search pane drives the orchestrator only.
// The search pane is decoupled from the assembly-tree filter cascade: typing in it
// drives the orchestrator only. Feeding SearchPaneModel.SearchTerm into
// LanguageSettings.SearchTerm instead would drive the cascade and hide member rows
// users expect to see — e.g. enum literals under their matched-by-name enum type.
var search = AppComposition.Current.GetExport<SearchPaneModel>();
var settings = AppComposition.Current.GetExport<SettingsService>().SessionSettings.LanguageSettings;

14
ILSpy/Languages/CSharpLanguage.cs

@ -112,18 +112,18 @@ namespace ICSharpCode.ILSpy.Languages @@ -112,18 +112,18 @@ namespace ICSharpCode.ILSpy.Languages
public override void WriteCommentLine(ITextOutput output, string comment) => output.WriteLine("// " + comment);
// Parity with WPF's CSharpLanguage: map an IL member back to its C# source via the
// decompiler, so compiler-generated members (lambdas, async/iterator state machines)
// resolve to their declaring method/part rather than only the declaring type (the
// base Language fallback). Used by analyzers / navigation.
// Maps an IL member back to its C# source via the decompiler, so compiler-generated
// members (lambdas, async/iterator state machines) resolve to their declaring
// method/part rather than only the declaring type (the base Language fallback).
// Used by analyzers / navigation.
public override CodeMappingInfo GetCodeMappingInfo(MetadataFile module, EntityHandle member)
{
return CSharpDecompiler.GetCodeMappingInfo(module, member);
}
// Parity with WPF's CSharpLanguage: produce C#-styled entity names (generics as
// <T>, nested types joined with '.'). Without this the base Language emits IL-style
// names (`1 arity suffixes, escaped identifiers).
// Produces C#-styled entity names (generics as <T>, nested types joined with '.').
// Without this the base Language emits IL-style names (`1 arity suffixes, escaped
// identifiers).
public override string GetEntityName(MetadataFile module, EntityHandle handle, bool fullName, bool omitGenerics)
{
MetadataReader metadata = module.Metadata;

9
ILSpy/TextView/DecompilerTextView.axaml.cs

@ -193,11 +193,10 @@ namespace ICSharpCode.ILSpy.TextView @@ -193,11 +193,10 @@ namespace ICSharpCode.ILSpy.TextView
uiElementGenerator = new UIElementGenerator();
Editor.TextArea.TextView.ElementGenerators.Add(uiElementGenerator);
// Reference navigation fires on pointer-RELEASE without drag (WPF parity: the WPF
// view used TextArea.PreviewMouseDown/Up the same way), so a press-and-drag over a
// link starts a text selection instead of navigating away. The press handler only
// records the start position, so tunnel routing (before AvaloniaEdit consumes the
// press) is fine.
// Reference navigation fires on pointer-RELEASE without drag, so a press-and-drag
// over a link starts a text selection instead of navigating away. The press handler
// only records the start position, so tunnel routing (before AvaloniaEdit consumes
// the press) is fine.
Editor.TextArea.AddHandler(InputElement.PointerPressedEvent,
OnTextAreaPointerPressedForReferenceClick,
RoutingStrategies.Tunnel,

5
ILSpy/TextView/DocumentationRenderer.cs

@ -136,9 +136,8 @@ namespace ICSharpCode.ILSpy.TextView @@ -136,9 +136,8 @@ namespace ICSharpCode.ILSpy.TextView
// Wrap rather than NoWrap so a signature wider than the popup's MaxWidth folds
// to multiple lines instead of being clipped at the right edge — the outer
// ScrollViewer disables horizontal scrolling, so NoWrap meant "the right half
// of long generic method signatures is invisible". WPF parity: the equivalent
// FlowDocument Paragraph wraps by default (Paragraph doesn't even support NoWrap).
// ScrollViewer disables horizontal scrolling, so NoWrap would leave the right
// half of long generic method signatures invisible.
var block = new SelectableTextBlock {
FontFamily = codeFont,
FontSize = fontSize,

2
ILSpy/TreeNodes/FieldTreeNode.cs

@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -45,7 +45,7 @@ namespace ICSharpCode.ILSpy.TreeNodes
public override object Icon => GetIcon(FieldDefinition);
// Mirrors WPF's discriminator: enum value, const literal, readonly, plain field.
// Discriminated in this order: enum value, const literal, readonly, plain field.
public static Avalonia.Media.IImage GetIcon(IField field)
{
// EnumValue: declaring type is an enum and the return type is the enum itself --

Loading…
Cancel
Save