From a7ad5990ac678cb75c95e2fe151b938f6f53d708 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Tue, 7 Aug 2018 14:10:23 +0200 Subject: [PATCH] CSharpAmbience: Add ConversionFlags.ShowParameterModifiers and ShowTypeParameterVarianceModifier to make labels in ILSpy main tree view more concise. + Added Tests. --- .../Output/CSharpAmbienceTests.cs | 274 +++++++++++------- .../CSharp/OutputVisitor/CSharpAmbience.cs | 36 ++- ICSharpCode.Decompiler/Output/IAmbience.cs | 15 +- ILSpy/Languages/CSharpLanguage.cs | 11 +- 4 files changed, 215 insertions(+), 121 deletions(-) diff --git a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs index 79eee0a22..e403b3b26 100644 --- a/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs +++ b/ICSharpCode.Decompiler.Tests/Output/CSharpAmbienceTests.cs @@ -26,6 +26,8 @@ using ICSharpCode.Decompiler.TypeSystem; using ICSharpCode.Decompiler.TypeSystem.Implementation; using NUnit.Framework; +using static ICSharpCode.Decompiler.Output.ConversionFlags; + namespace ICSharpCode.Decompiler.Tests.Output { [TestFixture] @@ -43,156 +45,201 @@ namespace ICSharpCode.Decompiler.Tests.Output TypeSystemLoaderTests.Mscorlib.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.OnlyPublicAPI)); } - #region ITypeDefinition tests - [Test] - public void GenericType() + ITypeDefinition GetDefinition(Type type) { - var typeDef = compilation.FindType(typeof(Dictionary<,>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); + if (type == null) { + throw new ArgumentNullException(nameof(type)); + } - Assert.AreEqual("System.Collections.Generic.Dictionary", result); + var foundType = compilation.FindType(type).GetDefinition(); + Assert.IsNotNull(foundType); + return foundType; } - [Test] - public void GenericTypeShortName() - { - var typeDef = compilation.FindType(typeof(Dictionary<,>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); + const ConversionFlags ILSpyMainTreeViewTypeFlags = ShowTypeParameterList | PlaceReturnTypeAfterParameterList; + const ConversionFlags ILSpyMainTreeViewMemberFlags = ILSpyMainTreeViewTypeFlags | ShowParameterList | ShowReturnType | ShowParameterModifiers; - Assert.AreEqual("Dictionary", result); + #region ITypeDefinition tests + [TestCase(None, "Dictionary")] + [TestCase(ShowDefinitionKeyword, "class Dictionary")] + [TestCase(ShowAccessibility, "public Dictionary")] + [TestCase(ShowDefinitionKeyword | ShowAccessibility, "public class Dictionary")] + [TestCase(ShowTypeParameterList, "Dictionary")] + [TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "public class Dictionary")] + [TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, "System.Collections.Generic.Dictionary")] + [TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "public class System.Collections.Generic.Dictionary")] + [TestCase(ILSpyMainTreeViewTypeFlags, "Dictionary")] + public void GenericType(ConversionFlags flags, string expectedOutput) + { + var typeDef = GetDefinition(typeof(Dictionary<,>)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void SimpleType() + [TestCase(None, "Object")] + [TestCase(ShowDefinitionKeyword, "class Object")] + [TestCase(ShowAccessibility, "public Object")] + [TestCase(ShowDefinitionKeyword | ShowAccessibility, "public class Object")] + [TestCase(ShowTypeParameterList, "Object")] + [TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "public class Object")] + [TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, "System.Object")] + [TestCase(All, "public class System.Object")] + [TestCase(ILSpyMainTreeViewTypeFlags, "Object")] + public void SimpleType(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(Object)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("System.Object", result); + var typeDef = GetDefinition(typeof(object)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void SimpleTypeDefinition() + [TestCase(None, "IEnumerable")] + [TestCase(ShowTypeParameterList, "IEnumerable")] + [TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, "IEnumerable")] + [TestCase(All, "public interface System.Collections.Generic.IEnumerable")] + [TestCase(ILSpyMainTreeViewTypeFlags, "IEnumerable")] + public void GenericInterface(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(Object)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedEntityNames); - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("public class Object", result); + var typeDef = GetDefinition(typeof(IEnumerable<>)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void SimpleTypeDefinitionWithoutModifiers() + [TestCase(None, "Enumerator")] + [TestCase(ShowDefinitionKeyword, "struct Enumerator")] + [TestCase(ShowAccessibility, "public Enumerator")] + [TestCase(ShowDefinitionKeyword | ShowAccessibility, "public struct Enumerator")] + [TestCase(ShowTypeParameterList, "Enumerator")] + [TestCase(ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "public struct Enumerator")] + [TestCase(UseFullyQualifiedEntityNames | ShowTypeParameterList, "System.Collections.Generic.List.Enumerator")] + [TestCase(ShowDeclaringType | ShowTypeParameterList, "List.Enumerator")] + [TestCase(All, "public struct System.Collections.Generic.List.Enumerator")] + [TestCase(ILSpyMainTreeViewTypeFlags, "Enumerator")] + public void GenericTypeWithNested(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(Object)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility); - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("class Object", result); + var typeDef = GetDefinition(typeof(List<>.Enumerator)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void GenericTypeDefinitionFull() + [TestCase(None, "StaticClass")] + [TestCase(ShowDefinitionKeyword, "class StaticClass")] + [TestCase(ShowModifiers | ShowDefinitionKeyword, "static class StaticClass")] + [TestCase(ShowModifiers | ShowAccessibility, "private static StaticClass")] + [TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, "private static class StaticClass")] + [TestCase(ShowModifiers | ShowTypeParameterList, "static StaticClass")] + [TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "private static class StaticClass")] + [TestCase(All, "private static class ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.StaticClass")] + [TestCase(ILSpyMainTreeViewTypeFlags, "StaticClass")] + public void StaticClassTest(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(List<>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.All; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("public class System.Collections.Generic.List", result); + var typeDef = GetDefinition(typeof(StaticClass)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void GenericInterfaceFull() + [TestCase(None, "SealedClass")] + [TestCase(ShowDefinitionKeyword, "class SealedClass")] + [TestCase(ShowModifiers | ShowDefinitionKeyword, "sealed class SealedClass")] + [TestCase(ShowModifiers | ShowAccessibility, "private sealed SealedClass")] + [TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, "private sealed class SealedClass")] + [TestCase(ShowModifiers | ShowTypeParameterList, "sealed SealedClass")] + [TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "private sealed class SealedClass")] + [TestCase(All, "private sealed class ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.SealedClass")] + [TestCase(ILSpyMainTreeViewTypeFlags, "SealedClass")] + public void SealedClassTest(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(IEnumerable<>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.All; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("public interface System.Collections.Generic.IEnumerable", result); + var typeDef = GetDefinition(typeof(SealedClass)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void SimpleTypeShortName() + [TestCase(None, "RefStruct")] + [TestCase(ShowDefinitionKeyword, "struct RefStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword, "ref struct RefStruct")] + [TestCase(ShowModifiers | ShowAccessibility, "private ref RefStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, "private ref struct RefStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList, "ref RefStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "private ref struct RefStruct")] + [TestCase(All, "private ref struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.RefStruct")] + [TestCase(ILSpyMainTreeViewTypeFlags, "RefStruct")] + public void RefStructTest(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(Object)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("Object", result); + var typeDef = GetDefinition(typeof(RefStruct)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void GenericTypeWithNested() + [TestCase(None, "ReadonlyStruct")] + [TestCase(ShowDefinitionKeyword, "struct ReadonlyStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword, "readonly struct ReadonlyStruct")] + [TestCase(ShowModifiers | ShowAccessibility, "private readonly ReadonlyStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, "private readonly struct ReadonlyStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList, "readonly ReadonlyStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "private readonly struct ReadonlyStruct")] + [TestCase(All, "private readonly struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.ReadonlyStruct")] + [TestCase(ILSpyMainTreeViewTypeFlags, "ReadonlyStruct")] + public void ReadonlyStructTest(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(List<>.Enumerator)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedEntityNames | ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("System.Collections.Generic.List.Enumerator", result); + var typeDef = GetDefinition(typeof(ReadonlyStruct)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } - [Test] - public void GenericTypeWithNestedShortName() + [TestCase(None, "ReadonlyRefStruct")] + [TestCase(ShowDefinitionKeyword, "struct ReadonlyRefStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword, "readonly ref struct ReadonlyRefStruct")] + [TestCase(ShowModifiers | ShowAccessibility, "private readonly ref ReadonlyRefStruct")] + [TestCase(ShowModifiers | ShowDefinitionKeyword | ShowAccessibility, "private readonly ref struct ReadonlyRefStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList, "readonly ref ReadonlyRefStruct")] + [TestCase(ShowModifiers | ShowTypeParameterList | ShowDefinitionKeyword | ShowAccessibility, "private readonly ref struct ReadonlyRefStruct")] + [TestCase(All, "private readonly ref struct ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.ReadonlyRefStruct")] + [TestCase(ILSpyMainTreeViewTypeFlags, "ReadonlyRefStruct")] + public void ReadonlyRefStructTest(ConversionFlags flags, string expectedOutput) { - var typeDef = compilation.FindType(typeof(List<>.Enumerator)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.ShowDeclaringType | ConversionFlags.ShowTypeParameterList; - string result = ambience.ConvertSymbol(typeDef); - - Assert.AreEqual("List.Enumerator", result); + var typeDef = GetDefinition(typeof(ReadonlyRefStruct)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(typeDef)); } #endregion #region Delegate tests - [Test] - public void DelegateName() - { - var func = compilation.FindType(typeof(Func<,>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; - - Assert.AreEqual("Func", ambience.ConvertSymbol(func)); - } - - [Test] - public void FullDelegate() + [TestCase(None, "Func")] + [TestCase(ShowTypeParameterList, "Func")] + [TestCase(ShowTypeParameterList | ShowTypeParameterVarianceModifier, "Func")] + [TestCase(ShowTypeParameterList | ShowReturnType | ShowTypeParameterVarianceModifier, "TResult Func")] + [TestCase(ShowTypeParameterList | ShowParameterList | ShowTypeParameterVarianceModifier, "Func(T)")] + [TestCase(ShowTypeParameterList | ShowParameterList | ShowReturnType | ShowTypeParameterVarianceModifier, "TResult Func(T)")] + [TestCase(All & ~PlaceReturnTypeAfterParameterList, "public delegate TResult System.Func(T arg);")] + [TestCase(All, "public delegate System.Func(T arg) : TResult;")] + [TestCase(ILSpyMainTreeViewTypeFlags, "Func")] + public void FuncDelegate(ConversionFlags flags, string expectedOutput) { - var func = compilation.FindType(typeof(Func<,>)).GetDefinition(); - ambience.ConversionFlags = ConversionFlags.All; - Assert.AreEqual("public delegate TResult System.Func(T arg);", ambience.ConvertSymbol(func)); + var func = GetDefinition(typeof(Func<,>)); + ambience.ConversionFlags = flags; + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(func)); } #endregion #region IField tests - [Test] - public void SimpleField() + [TestCase(All & ~PlaceReturnTypeAfterParameterList, "private int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.test;")] + [TestCase(ILSpyMainTreeViewMemberFlags, "test : int")] + [TestCase(ConversionFlags.All & ~(ConversionFlags.ShowDeclaringType | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility | ConversionFlags.PlaceReturnTypeAfterParameterList), "int test;")] + public void SimpleField(ConversionFlags flags, string expectedOutput) { - var field = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "test").Single(); - ambience.ConversionFlags = ConversionFlags.All; - string result = ambience.ConvertSymbol(field); + var field = GetDefinition(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "test").Single(); + ambience.ConversionFlags = flags; - Assert.AreEqual("private int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.test;", result); + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(field)); } - [Test] - public void SimpleConstField() + [TestCase(All & ~PlaceReturnTypeAfterParameterList, "private const int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.TEST2;")] + [TestCase(ILSpyMainTreeViewMemberFlags, "TEST2 : int")] + public void SimpleConstField(ConversionFlags flags, string expectedOutput) { var field = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "TEST2").Single(); - ambience.ConversionFlags = ConversionFlags.All; - string result = ambience.ConvertSymbol(field); + ambience.ConversionFlags = flags; - Assert.AreEqual("private const int ICSharpCode.Decompiler.Tests.Output.CSharpAmbienceTests.Program.TEST2;", result); - } - - [Test] - public void SimpleFieldWithoutModifiers() - { - var field = compilation.FindType(typeof(CSharpAmbienceTests.Program)).GetFields(f => f.Name == "test").Single(); - ambience.ConversionFlags = ConversionFlags.All & ~(ConversionFlags.ShowDeclaringType | ConversionFlags.ShowModifiers | ConversionFlags.ShowAccessibility); - string result = ambience.ConvertSymbol(field); - - Assert.AreEqual("int test;", result); + Assert.AreEqual(expectedOutput, ambience.ConvertSymbol(field)); } #endregion @@ -240,10 +287,22 @@ namespace ICSharpCode.Decompiler.Tests.Output } #endregion + #region IMethod tests + [Test] + public void ConstructorTests() + { + } + #endregion + #region Test types #pragma warning disable 169, 67 class Test { } + static class StaticClass { } + sealed class SealedClass { } + ref struct RefStruct { } + readonly struct ReadonlyStruct { } + readonly ref struct ReadonlyRefStruct { } class Program { @@ -297,6 +356,11 @@ namespace ICSharpCode.Decompiler.Tests.Output Console.Write("Press any key to continue . . . "); Console.ReadKey(true); } + + public static void InParameter(in int a) + { + + } } #endregion } diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs index 98b4cf466..6c43ef6d3 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpAmbience.cs @@ -17,7 +17,10 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; using System.IO; +using System.Linq; + using ICSharpCode.Decompiler.CSharp.Syntax; using ICSharpCode.Decompiler.Output; using ICSharpCode.Decompiler.TypeSystem; @@ -109,6 +112,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor writer.WriteToken(symbol.SymbolKind == SymbolKind.Indexer ? Roles.LBracket : Roles.LPar, symbol.SymbolKind == SymbolKind.Indexer ? "[" : "("); bool first = true; foreach (var param in node.GetChildrenByRole(Roles.Parameter)) { + if ((ConversionFlags & ConversionFlags.ShowParameterModifiers) == 0) { + param.ParameterModifier = ParameterModifier.None; + } if (first) { first = false; } else { @@ -186,7 +192,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); EntityDeclaration node = astBuilder.ConvertEntity(typeDef); - if (typeDef.DeclaringTypeDefinition != null && + if (typeDef.DeclaringTypeDefinition != null && ((ConversionFlags & ConversionFlags.ShowDeclaringType) == ConversionFlags.ShowDeclaringType || (ConversionFlags & ConversionFlags.UseFullyQualifiedEntityNames) == ConversionFlags.UseFullyQualifiedEntityNames)) { WriteTypeDeclarationName(typeDef.DeclaringTypeDefinition, writer, formattingPolicy); @@ -198,12 +204,9 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor } } writer.WriteIdentifier(node.NameToken); - if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList) { - var outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy); - outputVisitor.WriteTypeParameters(node.GetChildrenByRole(Roles.TypeParameter)); - } + WriteTypeParameters(node, writer, formattingPolicy); } - + void WriteMemberDeclarationName(IMember member, TokenWriter writer, CSharpFormattingOptions formattingPolicy) { TypeSystemAstBuilder astBuilder = CreateAstBuilder(); @@ -254,12 +257,27 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor writer.WriteIdentifier(Identifier.Create(member.Name)); break; } - if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList && member.SymbolKind == SymbolKind.Method) { + WriteTypeParameters(node, writer, formattingPolicy); + } + + void WriteTypeParameters(EntityDeclaration node, TokenWriter writer, CSharpFormattingOptions formattingPolicy) + { + if ((ConversionFlags & ConversionFlags.ShowTypeParameterList) == ConversionFlags.ShowTypeParameterList) { var outputVisitor = new CSharpOutputVisitor(writer, formattingPolicy); - outputVisitor.WriteTypeParameters(node.GetChildrenByRole(Roles.TypeParameter)); + IEnumerable typeParameters = node.GetChildrenByRole(Roles.TypeParameter); + if ((ConversionFlags & ConversionFlags.ShowTypeParameterVarianceModifier) == 0) { + typeParameters = typeParameters.Select(RemoveVarianceModifier); + } + outputVisitor.WriteTypeParameters(typeParameters); + } + + TypeParameterDeclaration RemoveVarianceModifier(TypeParameterDeclaration decl) + { + decl.Variance = VarianceModifier.Invariant; + return decl; } } - + void PrintModifiers(Modifiers modifiers, TokenWriter writer) { foreach (var m in CSharpModifierToken.AllModifiers) { diff --git a/ICSharpCode.Decompiler/Output/IAmbience.cs b/ICSharpCode.Decompiler/Output/IAmbience.cs index fa6f8d0f6..19bbd9f45 100644 --- a/ICSharpCode.Decompiler/Output/IAmbience.cs +++ b/ICSharpCode.Decompiler/Output/IAmbience.cs @@ -79,17 +79,28 @@ namespace ICSharpCode.Decompiler.Output /// append it after the parameter list, preceeded by a colon. /// PlaceReturnTypeAfterParameterList = 0x800, - + /// + /// Show the variance modifier of the type parameter. + /// If active, shows 'Func<in T, out TResult>' instead of 'Func<T, TResult>'. + /// + ShowTypeParameterVarianceModifier = 0x1000, + /// + /// Show modifiers of parameters, e.g. 'this', 'params', 'ref', 'out' and 'in'. + /// + ShowParameterModifiers = 0x2000, + StandardConversionFlags = ShowParameterNames | ShowAccessibility | ShowParameterList | + ShowParameterModifiers | ShowReturnType | ShowModifiers | ShowTypeParameterList | + ShowTypeParameterVarianceModifier | ShowDefinitionKeyword | ShowBody, - All = 0x7ff, + All = 0x7ffff, } /// diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index ac4b99a75..26b4532ad 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -429,16 +429,16 @@ namespace ICSharpCode.ILSpy static CSharpAmbience CreateAmbience() { CSharpAmbience ambience = new CSharpAmbience(); - ambience.ConversionFlags = ConversionFlags.ShowParameterList - | ConversionFlags.ShowReturnType - | ConversionFlags.ShowTypeParameterList - | ConversionFlags.PlaceReturnTypeAfterParameterList; + // Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewTypeFlags, if this ever changes. + ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList | ConversionFlags.PlaceReturnTypeAfterParameterList; return ambience; } static string EntityToString(IEntity entity, bool includeDeclaringTypeName, bool includeNamespace, bool includeNamespaceOfDeclaringTypeName) { + // Do not forget to update CSharpAmbienceTests, if this ever changes. var ambience = CreateAmbience(); + ambience.ConversionFlags |= ConversionFlags.ShowReturnType | ConversionFlags.ShowParameterList | ConversionFlags.ShowParameterModifiers; if (includeDeclaringTypeName) ambience.ConversionFlags |= ConversionFlags.ShowDeclaringType; if (includeNamespace) @@ -453,6 +453,7 @@ namespace ICSharpCode.ILSpy if (type == null) throw new ArgumentNullException(nameof(type)); var ambience = CreateAmbience(); + // Do not forget to update CSharpAmbienceTests.ILSpyMainTreeViewFlags, if this ever changes. if (includeNamespace) ambience.ConversionFlags |= ConversionFlags.UseFullyQualifiedTypeNames; if (type is ITypeDefinition definition) { @@ -584,7 +585,7 @@ namespace ICSharpCode.ILSpy public override string GetTooltip(IEntity entity) { - var flags = ConversionFlags.All & ~ConversionFlags.ShowBody; + var flags = ConversionFlags.All & ~(ConversionFlags.ShowBody | ConversionFlags.PlaceReturnTypeAfterParameterList); return new CSharpAmbience() { ConversionFlags = flags }.ConvertSymbol(entity); }