diff --git a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs index eece5e01a..039230e85 100644 --- a/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs +++ b/ILSpy/Analyzers/AnalyzerEntityTreeNode.cs @@ -17,6 +17,7 @@ // DEALINGS IN THE SOFTWARE. using System.Collections.Generic; +using System.Diagnostics; using System.Windows; using ICSharpCode.Decompiler.TypeSystem; @@ -25,6 +26,8 @@ using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX.TreeView; using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers { /// @@ -34,6 +37,8 @@ namespace ICSharpCode.ILSpy.Analyzers { public abstract IEntity Member { get; } + public IEntity? SourceMember { get; protected set; } + public override void ActivateItem(IPlatformRoutedEventArgs e) { e.Handled = true; @@ -43,10 +48,14 @@ namespace ICSharpCode.ILSpy.Analyzers return; } - MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(this.Member.ParentModule?.MetadataFile, this.Member.MetadataToken))); + var module = this.Member.ParentModule?.MetadataFile; + + Debug.Assert(module != null); + + MessageBus.Send(this, new NavigateToReferenceEventArgs(new EntityReference(module, this.Member.MetadataToken), this.SourceMember)); } - public override object ToolTip => Member?.ParentModule?.MetadataFile?.FileName; + public override object? ToolTip => Member?.ParentModule?.MetadataFile?.FileName; public override bool HandleAssemblyListChanged(ICollection removedAssemblies, ICollection addedAssemblies) { diff --git a/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs b/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs index 2cbb18c87..9af81a856 100644 --- a/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs +++ b/ILSpy/Analyzers/AnalyzerSearchTreeNode.cs @@ -76,29 +76,29 @@ namespace ICSharpCode.ILSpy.Analyzers } } - AnalyzerTreeNode SymbolTreeNodeFactory(ISymbol symbol) + AnalyzerTreeNode SymbolTreeNodeFactory(ISymbol resultSymbol) { - if (symbol == null) + if (resultSymbol == null) { - throw new ArgumentNullException(nameof(symbol)); + throw new ArgumentNullException(nameof(resultSymbol)); } - switch (symbol) + switch (resultSymbol) { case IModule module: - return new AnalyzedModuleTreeNode(module) { }; + return new AnalyzedModuleTreeNode(module, (IEntity)this.symbol); case ITypeDefinition td: - return new AnalyzedTypeTreeNode(td) { }; + return new AnalyzedTypeTreeNode(td, (IEntity)this.symbol); case IField fd: - return new AnalyzedFieldTreeNode(fd) { }; + return new AnalyzedFieldTreeNode(fd, (IEntity)this.symbol); case IMethod md: - return new AnalyzedMethodTreeNode(md) { }; + return new AnalyzedMethodTreeNode(md, (IEntity)this.symbol); case IProperty pd: - return new AnalyzedPropertyTreeNode(pd) { }; + return new AnalyzedPropertyTreeNode(pd, (IEntity)this.symbol); case IEvent ed: - return new AnalyzedEventTreeNode(ed) { }; + return new AnalyzedEventTreeNode(ed, (IEntity)this.symbol); default: - throw new ArgumentOutOfRangeException(nameof(symbol), $"Symbol {symbol.GetType().FullName} is not supported."); + throw new ArgumentOutOfRangeException(nameof(resultSymbol), $"Symbol {resultSymbol.GetType().FullName} is not supported."); } } diff --git a/ILSpy/Analyzers/AnalyzerTreeViewModel.cs b/ILSpy/Analyzers/AnalyzerTreeViewModel.cs index c008c0f74..30ef87c99 100644 --- a/ILSpy/Analyzers/AnalyzerTreeViewModel.cs +++ b/ILSpy/Analyzers/AnalyzerTreeViewModel.cs @@ -109,20 +109,20 @@ namespace ICSharpCode.ILSpy.Analyzers switch (entity) { case ITypeDefinition td: - AddOrSelect(new AnalyzedTypeTreeNode(td)); + AddOrSelect(new AnalyzedTypeTreeNode(td, null)); break; case IField fd: if (!fd.IsConst) - AddOrSelect(new AnalyzedFieldTreeNode(fd)); + AddOrSelect(new AnalyzedFieldTreeNode(fd, null)); break; case IMethod md: - AddOrSelect(new AnalyzedMethodTreeNode(md)); + AddOrSelect(new AnalyzedMethodTreeNode(md, null)); break; case IProperty pd: - AddOrSelect(new AnalyzedPropertyTreeNode(pd)); + AddOrSelect(new AnalyzedPropertyTreeNode(pd, null)); break; case IEvent ed: - AddOrSelect(new AnalyzedEventTreeNode(ed)); + AddOrSelect(new AnalyzedEventTreeNode(ed, null)); break; default: throw new ArgumentOutOfRangeException(nameof(entity), $@"Entity {entity.GetType().FullName} is not supported."); diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs index 64a65633b..08b44dabe 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedAccessorTreeNode.cs @@ -24,8 +24,8 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { readonly string name; - public AnalyzedAccessorTreeNode(IMethod analyzedMethod, string name) - : base(analyzedMethod) + public AnalyzedAccessorTreeNode(IMethod analyzedMethod, IEntity source, string name) + : base(analyzedMethod, source) { if (string.IsNullOrWhiteSpace(name)) { diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs index dc8ec7714..3ef317edc 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedEventTreeNode.cs @@ -21,6 +21,8 @@ using System; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { internal sealed class AnalyzedEventTreeNode : AnalyzerEntityTreeNode @@ -28,11 +30,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes readonly IEvent analyzedEvent; readonly string prefix; - public AnalyzedEventTreeNode(IEvent analyzedEvent, string prefix = "") + public AnalyzedEventTreeNode(IEvent analyzedEvent, IEntity? source, string prefix = "") { this.analyzedEvent = analyzedEvent ?? throw new ArgumentNullException(nameof(analyzedEvent)); this.prefix = prefix; this.LazyLoading = true; + this.SourceMember = source; } public override IEntity Member => analyzedEvent; @@ -45,11 +48,11 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes protected override void LoadChildren() { if (analyzedEvent.CanAdd) - this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.AddAccessor, "add")); + this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.AddAccessor, this.SourceMember, "add")); if (analyzedEvent.CanRemove) - this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.RemoveAccessor, "remove")); + this.Children.Add(new AnalyzedAccessorTreeNode(analyzedEvent.RemoveAccessor, this.SourceMember, "remove")); if (TryFindBackingField(analyzedEvent, out var backingField)) - this.Children.Add(new AnalyzedFieldTreeNode(backingField)); + this.Children.Add(new AnalyzedFieldTreeNode(backingField, this.SourceMember)); foreach (var lazy in Analyzers) { diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs index 89858ef8c..acfe6880b 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedFieldTreeNode.cs @@ -21,15 +21,18 @@ using System; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { class AnalyzedFieldTreeNode : AnalyzerEntityTreeNode { readonly IField analyzedField; - public AnalyzedFieldTreeNode(IField analyzedField) + public AnalyzedFieldTreeNode(IField analyzedField, IEntity? source) { this.analyzedField = analyzedField ?? throw new ArgumentNullException(nameof(analyzedField)); + this.SourceMember = source; this.LazyLoading = true; } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs index 2186517bf..711ffd05c 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedMethodTreeNode.cs @@ -21,6 +21,8 @@ using System; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { internal class AnalyzedMethodTreeNode : AnalyzerEntityTreeNode @@ -28,9 +30,10 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes readonly IMethod analyzedMethod; readonly string prefix; - public AnalyzedMethodTreeNode(IMethod analyzedMethod, string prefix = "") + public AnalyzedMethodTreeNode(IMethod analyzedMethod, IEntity? source, string prefix = "") { this.analyzedMethod = analyzedMethod ?? throw new ArgumentNullException(nameof(analyzedMethod)); + this.SourceMember = source; this.prefix = prefix; this.LazyLoading = true; } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs index 8a9030d0e..cde606d36 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedModuleTreeNode.cs @@ -25,15 +25,18 @@ using ICSharpCode.ILSpyX; using ICSharpCode.ILSpyX.TreeView; using ICSharpCode.ILSpyX.TreeView.PlatformAbstractions; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { internal class AnalyzedModuleTreeNode : AnalyzerEntityTreeNode { readonly IModule analyzedModule; - public AnalyzedModuleTreeNode(IModule analyzedModule) + public AnalyzedModuleTreeNode(IModule analyzedModule, IEntity? source) { this.analyzedModule = analyzedModule ?? throw new ArgumentNullException(nameof(analyzedModule)); + this.SourceMember = source; this.LazyLoading = true; } diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs index 537a166cb..c306caf82 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedPropertyTreeNode.cs @@ -21,6 +21,8 @@ using System; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { sealed class AnalyzedPropertyTreeNode : AnalyzerEntityTreeNode @@ -28,11 +30,12 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes readonly IProperty analyzedProperty; readonly string prefix; - public AnalyzedPropertyTreeNode(IProperty analyzedProperty, string prefix = "") + public AnalyzedPropertyTreeNode(IProperty analyzedProperty, IEntity? source, string prefix = "") { this.analyzedProperty = analyzedProperty ?? throw new ArgumentNullException(nameof(analyzedProperty)); this.prefix = prefix; this.LazyLoading = true; + this.SourceMember = source; } public override object Icon => PropertyTreeNode.GetIcon(analyzedProperty); @@ -43,9 +46,9 @@ namespace ICSharpCode.ILSpy.Analyzers.TreeNodes protected override void LoadChildren() { if (analyzedProperty.CanGet) - this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, "get")); + this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Getter, this.SourceMember, "get")); if (analyzedProperty.CanSet) - this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, "set")); + this.Children.Add(new AnalyzedAccessorTreeNode(analyzedProperty.Setter, this.SourceMember, "set")); foreach (var lazy in Analyzers) { diff --git a/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs b/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs index e87fb9938..7ae84a094 100644 --- a/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs +++ b/ILSpy/Analyzers/TreeNodes/AnalyzedTypeTreeNode.cs @@ -21,15 +21,18 @@ using System; using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.ILSpy.TreeNodes; +#nullable enable + namespace ICSharpCode.ILSpy.Analyzers.TreeNodes { internal class AnalyzedTypeTreeNode : AnalyzerEntityTreeNode { readonly ITypeDefinition analyzedType; - public AnalyzedTypeTreeNode(ITypeDefinition analyzedType) + public AnalyzedTypeTreeNode(ITypeDefinition analyzedType, IEntity? source) { this.analyzedType = analyzedType ?? throw new ArgumentNullException(nameof(analyzedType)); + this.SourceMember = source; this.LazyLoading = true; } diff --git a/ILSpy/AssemblyTree/AssemblyTreeModel.cs b/ILSpy/AssemblyTree/AssemblyTreeModel.cs index 43a5be4d9..0e9b98f30 100644 --- a/ILSpy/AssemblyTree/AssemblyTreeModel.cs +++ b/ILSpy/AssemblyTree/AssemblyTreeModel.cs @@ -67,6 +67,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree private readonly NavigationHistory history = new(); private NavigationState? navigatingToState; + private object? sourceOfReference; private readonly SettingsService settingsService; private readonly LanguageService languageService; private readonly IExportProvider exportProvider; @@ -262,7 +263,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree found = true; if (SelectedItem == initialSelection) { - await JumpToReferenceAsync(mr); + await JumpToReferenceAsync(mr, null); } } } @@ -642,7 +643,7 @@ namespace ICSharpCode.ILSpy.AssemblyTree private void JumpToReference(object? sender, NavigateToReferenceEventArgs e) { - JumpToReferenceAsync(e.Reference, e.InNewTabPage).HandleExceptions(); + JumpToReferenceAsync(e.Reference, e.Source, e.InNewTabPage).HandleExceptions(); IsActive = true; } @@ -653,8 +654,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree /// Returns a task that will signal completion when the decompilation of the jump target has finished. /// The task will be marked as canceled if the decompilation is canceled. /// - private Task JumpToReferenceAsync(object? reference, bool inNewTabPage = false) + private Task JumpToReferenceAsync(object? reference, object? source, bool inNewTabPage = false) { + this.sourceOfReference = source; var decompilationTask = Task.CompletedTask; switch (reference) @@ -804,6 +806,8 @@ namespace ICSharpCode.ILSpy.AssemblyTree public void DecompileSelectedNodes(ViewState? newState = null) { + object? source = this.sourceOfReference; + this.sourceOfReference = null; var activeTabPage = DockWorkspace.ActiveTabPage; if (activeTabPage.FrozenContent) @@ -831,7 +835,9 @@ namespace ICSharpCode.ILSpy.AssemblyTree var options = activeTabPage.CreateDecompilationOptions(); options.TextViewState = newState as DecompilerTextViewState; - activeTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, options)); + activeTabPage.ShowTextViewAsync(textView => { + return textView.DecompileAsync(this.CurrentLanguage, this.SelectedNodes, source, options); + }); } public void RefreshDecompiledView() diff --git a/ILSpy/TextView/AvalonEditTextOutput.cs b/ILSpy/TextView/AvalonEditTextOutput.cs index d3d8efbba..6882b2c8b 100644 --- a/ILSpy/TextView/AvalonEditTextOutput.cs +++ b/ILSpy/TextView/AvalonEditTextOutput.cs @@ -312,6 +312,13 @@ namespace ICSharpCode.ILSpy.TextView references.Add(new ReferenceSegment { StartOffset = start, EndOffset = end, Reference = reference, IsLocal = true, IsDefinition = isDefinition }); } + internal object InitialHighlightReference = null; + + public void SetInitialHighlight(object reference) + { + this.InitialHighlightReference = reference; + } + public void MarkFoldStart(string collapsedText = "...", bool defaultCollapsed = false, bool isDefinition = false) { WriteIndent(); diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs index 55c97088d..5ad397a07 100644 --- a/ILSpy/TextView/DecompilerTextView.cs +++ b/ILSpy/TextView/DecompilerTextView.cs @@ -802,6 +802,7 @@ namespace ICSharpCode.ILSpy.TextView currentAddress = textOutput.Address; currentTitle = textOutput.Title; expandMemberDefinitions = settingsService.DisplaySettings.ExpandMemberDefinitions; + SetLocalReferenceMarks(textOutput.InitialHighlightReference); } #endregion @@ -817,7 +818,7 @@ namespace ICSharpCode.ILSpy.TextView [Obsolete("Use DecompileAsync() instead")] public void Decompile(ILSpy.Language language, IEnumerable treeNodes, DecompilationOptions options) { - DecompileAsync(language, treeNodes, options).HandleExceptions(); + DecompileAsync(language, treeNodes, null, options).HandleExceptions(); } /// @@ -826,7 +827,7 @@ namespace ICSharpCode.ILSpy.TextView /// If any errors occur, the error message is displayed in the text view, and the task returned by this method completes successfully. /// If the operation is cancelled (by starting another decompilation action); the returned task is marked as cancelled. /// - public Task DecompileAsync(ILSpy.Language language, IEnumerable treeNodes, DecompilationOptions options) + public Task DecompileAsync(ILSpy.Language language, IEnumerable treeNodes, object? source, DecompilationOptions options) { // Some actions like loading an assembly list cause several selection changes in the tree view, // and each of those will start a decompilation action. @@ -834,7 +835,7 @@ namespace ICSharpCode.ILSpy.TextView bool isDecompilationScheduled = this.nextDecompilationRun != null; if (this.nextDecompilationRun != null) this.nextDecompilationRun.TaskCompletionSource.TrySetCanceled(); - this.nextDecompilationRun = new DecompilationContext(language, treeNodes.ToArray(), options); + this.nextDecompilationRun = new DecompilationContext(language, treeNodes.ToArray(), options, source); var task = this.nextDecompilationRun.TaskCompletionSource.Task; if (!isDecompilationScheduled) { @@ -857,12 +858,14 @@ namespace ICSharpCode.ILSpy.TextView public readonly ILSpyTreeNode[] TreeNodes; public readonly DecompilationOptions Options; public readonly TaskCompletionSource TaskCompletionSource = new TaskCompletionSource(); + public readonly object? Source; - public DecompilationContext(ILSpy.Language language, ILSpyTreeNode[] treeNodes, DecompilationOptions options) + public DecompilationContext(ILSpy.Language language, ILSpyTreeNode[] treeNodes, DecompilationOptions options, object? source = null) { this.Language = language; this.TreeNodes = treeNodes; this.Options = options; + this.Source = source; } } @@ -914,6 +917,7 @@ namespace ICSharpCode.ILSpy.TextView { AvalonEditTextOutput textOutput = new AvalonEditTextOutput(); textOutput.LengthLimit = outputLengthLimit; + textOutput.SetInitialHighlight(context.Source); DecompileNodes(context, textOutput); textOutput.PrepareDocument(); tcs.SetResult(textOutput); @@ -994,19 +998,7 @@ namespace ICSharpCode.ILSpy.TextView if (referenceSegment.IsLocal) { ClearLocalReferenceMarks(); - if (references != null) - { - foreach (var r in references) - { - if (reference.Equals(r.Reference)) - { - - var mark = textMarkerService.Create(r.StartOffset, r.Length); - mark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor)); - localReferenceMarks.Add(mark); - } - } - } + SetLocalReferenceMarks(reference); return; } if (definitionLookup != null) @@ -1027,6 +1019,23 @@ namespace ICSharpCode.ILSpy.TextView MessageBus.Send(this, new NavigateToReferenceEventArgs(reference, openInNewTab)); } + private void SetLocalReferenceMarks(object reference) + { + if (references == null || reference == null) + { + return; + } + foreach (var r in references) + { + if (reference.Equals(r.Reference)) + { + var mark = textMarkerService.Create(r.StartOffset, r.Length); + mark.BackgroundColor = (Color)(r.IsDefinition ? FindResource(ResourceKeys.TextMarkerDefinitionBackgroundColor) : FindResource(ResourceKeys.TextMarkerBackgroundColor)); + localReferenceMarks.Add(mark); + } + } + } + Point? mouseDownPos; void TextAreaMouseDown(object sender, MouseButtonEventArgs e) diff --git a/ILSpy/Util/MessageBus.cs b/ILSpy/Util/MessageBus.cs index 871205901..c6c24b362 100644 --- a/ILSpy/Util/MessageBus.cs +++ b/ILSpy/Util/MessageBus.cs @@ -79,10 +79,10 @@ namespace ICSharpCode.ILSpy.Util public class SettingsChangedEventArgs(PropertyChangedEventArgs e) : WrappedEventArgs(e); - public class NavigateToReferenceEventArgs(object reference, bool inNewTabPage = false) : EventArgs + public class NavigateToReferenceEventArgs(object reference, object? source = null, bool inNewTabPage = false) : EventArgs { public object Reference { get; } = reference; - + public object? Source { get; } = source; public bool InNewTabPage { get; } = inNewTabPage; } diff --git a/ILSpy/Views/DebugSteps.xaml.cs b/ILSpy/Views/DebugSteps.xaml.cs index da9940c3a..87bcd0859 100644 --- a/ILSpy/Views/DebugSteps.xaml.cs +++ b/ILSpy/Views/DebugSteps.xaml.cs @@ -140,7 +140,7 @@ namespace ICSharpCode.ILSpy } var state = dockWorkspace.ActiveTabPage.GetState(); - dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, + dockWorkspace.ActiveTabPage.ShowTextViewAsync(textView => textView.DecompileAsync(assemblyTreeModel.CurrentLanguage, assemblyTreeModel.SelectedNodes, null, new DecompilationOptions(assemblyTreeModel.CurrentLanguageVersion, settingsService.DecompilerSettings, settingsService.DisplaySettings) { StepLimit = step, IsDebug = isDebug,