diff --git a/ILSpy/ExtensionMethods.cs b/ILSpy/ExtensionMethods.cs index bd460826c..60bb77d40 100644 --- a/ILSpy/ExtensionMethods.cs +++ b/ILSpy/ExtensionMethods.cs @@ -76,11 +76,15 @@ namespace ICSharpCode.ILSpy return result; } - public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file, SettingsService settingsService) + public static ICompilation? GetTypeSystemWithCurrentOptionsOrNull(this MetadataFile file, SettingsService settingsService, LanguageVersion languageVersion) { + var decompilerSettings = settingsService.DecompilerSettings.Clone(); + if (!Enum.TryParse(languageVersion.Version, out Decompiler.CSharp.LanguageVersion csharpLanguageVersion)) + csharpLanguageVersion = Decompiler.CSharp.LanguageVersion.Latest; + decompilerSettings.SetLanguageVersion(csharpLanguageVersion); return file .GetLoadedAssembly() - .GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(settingsService.DecompilerSettings)); + .GetTypeSystemOrNull(DecompilerTypeSystem.GetOptions(decompilerSettings)); } #region DPI independence diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index b1686836c..73336640e 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -578,10 +578,18 @@ namespace ICSharpCode.ILSpy CSharpAmbience ambience = new CSharpAmbience(); // Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewTypeFlags, if this ever changes. ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.PlaceReturnTypeAfterParameterList; - if (SettingsService.DecompilerSettings.LiftNullables) + var decompilerSettings = SettingsService.DecompilerSettings.Clone(); + if (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion)) + languageVersion = Decompiler.CSharp.LanguageVersion.Latest; + decompilerSettings.SetLanguageVersion(languageVersion); + if (decompilerSettings.LiftNullables) { ambience.ConversionFlags |= ConversionFlags.UseNullableSpecifierForValueTypes; } + if (decompilerSettings.IntroducePrivateProtectedAccessibility) + { + ambience.ConversionFlags |= ConversionFlags.UsePrivateProtectedAccessibility; + } return ambience; } @@ -781,7 +789,11 @@ namespace ICSharpCode.ILSpy public override bool ShowMember(IEntity member) { MetadataFile assembly = member.ParentModule.MetadataFile; - return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, SettingsService.DecompilerSettings); + var decompilerSettings = SettingsService.DecompilerSettings.Clone(); + if (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion)) + languageVersion = Decompiler.CSharp.LanguageVersion.Latest; + decompilerSettings.SetLanguageVersion(languageVersion); + return showAllMembers || !CSharpDecompiler.MemberIsHidden(assembly, member.MetadataToken, decompilerSettings); } public override RichText GetRichTextTooltip(IEntity entity) @@ -790,7 +802,10 @@ namespace ICSharpCode.ILSpy var output = new StringWriter(); var decoratedWriter = new TextWriterTokenWriter(output); var writer = new CSharpHighlightingTokenWriter(TokenWriter.InsertRequiredSpaces(decoratedWriter), locatable: decoratedWriter); - var settings = SettingsService.DecompilerSettings; + var settings = SettingsService.DecompilerSettings.Clone(); + if (!Enum.TryParse(AssemblyTreeModel.CurrentLanguageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion)) + languageVersion = Decompiler.CSharp.LanguageVersion.Latest; + settings.SetLanguageVersion(languageVersion); if (!settings.LiftNullables) { flags &= ~ConversionFlags.UseNullableSpecifierForValueTypes; @@ -815,6 +830,10 @@ namespace ICSharpCode.ILSpy { flags |= ConversionFlags.SupportInitAccessors; } + if (settings.IntroducePrivateProtectedAccessibility) + { + flags |= ConversionFlags.UsePrivateProtectedAccessibility; + } if (entity is IMethod m && m.IsLocalFunction) { writer.WriteIdentifier(Identifier.Create("(local)")); diff --git a/ILSpy/Languages/LanguageService.cs b/ILSpy/Languages/LanguageService.cs index 6c116b1ad..7cd6e47e1 100644 --- a/ILSpy/Languages/LanguageService.cs +++ b/ILSpy/Languages/LanguageService.cs @@ -35,10 +35,12 @@ namespace ICSharpCode.ILSpy [Shared] public class LanguageService : ObservableObjectBase { + private readonly SettingsService settingsService; private readonly LanguageSettings languageSettings; public LanguageService(IEnumerable languages, SettingsService settingsService, DockWorkspace dockWorkspace) { + this.settingsService = settingsService; languageSettings = settingsService.SessionSettings.LanguageSettings; var sortedLanguages = languages.ToList(); diff --git a/ILSpy/Metadata/CorTables/EventTableTreeNode.cs b/ILSpy/Metadata/CorTables/EventTableTreeNode.cs index 821a25476..d63ab0ef3 100644 --- a/ILSpy/Metadata/CorTables/EventTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/EventTableTreeNode.cs @@ -94,7 +94,7 @@ namespace ICSharpCode.ILSpy.Metadata IEntity IMemberTreeNode.Member { get { - return ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle); + return ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle); } } diff --git a/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs b/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs index eb48eaec2..345600d7c 100644 --- a/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/FieldTableTreeNode.cs @@ -95,7 +95,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(fieldDef.Name):X} \"{Name}\""; - IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle); + IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle); [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(fieldDef.Signature); diff --git a/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs b/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs index 775661855..4f2d7b712 100644 --- a/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/MethodTableTreeNode.cs @@ -131,7 +131,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle); + IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle); public MethodDefEntry(MetadataFile metadataFile, MethodDefinitionHandle handle) { diff --git a/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs b/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs index 255892ea1..87d187d28 100644 --- a/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/PropertyTableTreeNode.cs @@ -92,7 +92,7 @@ namespace ICSharpCode.ILSpy.Metadata public string NameTooltip => $"{MetadataTokens.GetHeapOffset(propertyDef.Name):X} \"{Name}\""; - IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle); + IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle); [ColumnInfo("X8", Kind = ColumnKind.HeapOffset)] public int Signature => MetadataTokens.GetHeapOffset(propertyDef.Signature); diff --git a/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs b/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs index e7aa7bbd4..d5f51939d 100644 --- a/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs +++ b/ILSpy/Metadata/CorTables/TypeDefTableTreeNode.cs @@ -173,7 +173,7 @@ namespace ICSharpCode.ILSpy.Metadata } } - IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule)?.GetDefinition(handle); + IEntity IMemberTreeNode.Member => ((MetadataModule)metadataFile.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule)?.GetDefinition(handle); public TypeDefEntry(MetadataFile metadataFile, TypeDefinitionHandle handle) { diff --git a/ILSpy/Search/SearchPane.xaml.cs b/ILSpy/Search/SearchPane.xaml.cs index 83ec4cc1e..190d65b81 100644 --- a/ILSpy/Search/SearchPane.xaml.cs +++ b/ILSpy/Search/SearchPane.xaml.cs @@ -266,6 +266,7 @@ namespace ICSharpCode.ILSpy.Search searchTerm, (SearchMode)searchModeComboBox.SelectedIndex, assemblyTreeModel.CurrentLanguage, + assemblyTreeModel.CurrentLanguageVersion, treeNodeFactory, settingsService); currentSearch = startedSearch; @@ -295,6 +296,7 @@ namespace ICSharpCode.ILSpy.Search readonly SearchRequest searchRequest; readonly SearchMode searchMode; readonly Language language; + readonly LanguageVersion languageVersion; readonly ApiVisibility apiVisibility; readonly ITreeNodeFactory treeNodeFactory; readonly SettingsService settingsService; @@ -302,7 +304,7 @@ namespace ICSharpCode.ILSpy.Search public IProducerConsumerCollection ResultQueue { get; } = new ConcurrentQueue(); public RunningSearch(IList assemblies, string searchTerm, SearchMode searchMode, - Language language, ITreeNodeFactory treeNodeFactory, SettingsService settingsService) + Language language, LanguageVersion languageVersion, ITreeNodeFactory treeNodeFactory, SettingsService settingsService) { this.assemblies = assemblies; this.language = language; @@ -471,7 +473,11 @@ namespace ICSharpCode.ILSpy.Search request.RegEx = regex; request.SearchResultFactory = new SearchResultFactory(language); request.TreeNodeFactory = this.treeNodeFactory; - request.DecompilerSettings = settingsService.DecompilerSettings; + var decompilerSettings = settingsService.DecompilerSettings.Clone(); + if (!Enum.TryParse(this.languageVersion?.Version, out Decompiler.CSharp.LanguageVersion languageVersion)) + languageVersion = Decompiler.CSharp.LanguageVersion.Latest; + decompilerSettings.SetLanguageVersion(languageVersion); + request.DecompilerSettings = settingsService.DecompilerSettings.Clone(); return request; } diff --git a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs index c62af32d8..b779350d6 100644 --- a/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs +++ b/ILSpy/TreeNodes/AssemblyReferenceTreeNode.cs @@ -89,7 +89,7 @@ namespace ICSharpCode.ILSpy.TreeNodes var referencedModule = resolver.Resolve(r); if (referencedModule != null) { - var module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule; + var module = (MetadataModule)referencedModule.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule; foreach (var childRef in referencedModule.AssemblyReferences) this.Children.Add(new AssemblyReferenceTreeNode(module, childRef, parentAssembly)); } diff --git a/ILSpy/TreeNodes/EventTreeNode.cs b/ILSpy/TreeNodes/EventTreeNode.cs index ad75b1b5b..1af0a9de3 100644 --- a/ILSpy/TreeNodes/EventTreeNode.cs +++ b/ILSpy/TreeNodes/EventTreeNode.cs @@ -52,7 +52,7 @@ namespace ICSharpCode.ILSpy.TreeNodes private IEvent GetEventDefinition() { return ((MetadataModule)EventDefinition.ParentModule?.MetadataFile - ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService) + ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion) ?.MainModule)?.GetDefinition((EventDefinitionHandle)EventDefinition.MetadataToken) ?? EventDefinition; } diff --git a/ILSpy/TreeNodes/FieldTreeNode.cs b/ILSpy/TreeNodes/FieldTreeNode.cs index 26319a03d..4a086ceb7 100644 --- a/ILSpy/TreeNodes/FieldTreeNode.cs +++ b/ILSpy/TreeNodes/FieldTreeNode.cs @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes private IField GetFieldDefinition() { return ((MetadataModule)FieldDefinition.ParentModule?.MetadataFile - ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService) + ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion) ?.MainModule)?.GetDefinition((FieldDefinitionHandle)FieldDefinition.MetadataToken) ?? FieldDefinition; } diff --git a/ILSpy/TreeNodes/MethodTreeNode.cs b/ILSpy/TreeNodes/MethodTreeNode.cs index f3d2a6daa..1658ac714 100644 --- a/ILSpy/TreeNodes/MethodTreeNode.cs +++ b/ILSpy/TreeNodes/MethodTreeNode.cs @@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpy.TreeNodes private IMethod GetMethodDefinition() { return ((MetadataModule)MethodDefinition.ParentModule?.MetadataFile - ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService) + ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion) ?.MainModule)?.GetDefinition((MethodDefinitionHandle)MethodDefinition.MetadataToken) ?? MethodDefinition; } diff --git a/ILSpy/TreeNodes/PropertyTreeNode.cs b/ILSpy/TreeNodes/PropertyTreeNode.cs index df1a9f473..fc0a0ccbc 100644 --- a/ILSpy/TreeNodes/PropertyTreeNode.cs +++ b/ILSpy/TreeNodes/PropertyTreeNode.cs @@ -54,7 +54,7 @@ namespace ICSharpCode.ILSpy.TreeNodes private IProperty GetPropertyDefinition() { return ((MetadataModule)PropertyDefinition.ParentModule?.MetadataFile - ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService) + ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion) ?.MainModule)?.GetDefinition((PropertyDefinitionHandle)PropertyDefinition.MetadataToken) ?? PropertyDefinition; } diff --git a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs index c8c4dd8d0..61fc007b7 100644 --- a/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs +++ b/ILSpy/TreeNodes/ReferenceFolderTreeNode.cs @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.TreeNodes protected override void LoadChildren() { var metadata = module.Metadata; - var metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull(SettingsService)?.MainModule; + var metadataModule = (MetadataModule)module.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion)?.MainModule; foreach (var r in module.AssemblyReferences.OrderBy(r => r.Name)) this.Children.Add(new AssemblyReferenceTreeNode(metadataModule, r, parentAssembly)); foreach (var r in metadata.GetModuleReferences().OrderBy(r => metadata.GetString(metadata.GetModuleReference(r).Name))) diff --git a/ILSpy/TreeNodes/TypeTreeNode.cs b/ILSpy/TreeNodes/TypeTreeNode.cs index a79b5c654..edb4d3567 100644 --- a/ILSpy/TreeNodes/TypeTreeNode.cs +++ b/ILSpy/TreeNodes/TypeTreeNode.cs @@ -49,7 +49,7 @@ namespace ICSharpCode.ILSpy.TreeNodes { return ((MetadataModule)ParentAssemblyNode.LoadedAssembly .GetMetadataFileOrNull() - ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService) + ?.GetTypeSystemWithCurrentOptionsOrNull(SettingsService, AssemblyTreeModel.CurrentLanguageVersion) ?.MainModule)?.GetDefinition((SRM.TypeDefinitionHandle)TypeDefinition.MetadataToken); }