diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs index 91f83ffa0..c27edcc72 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs @@ -11,5 +11,10 @@ { private readonly int dummy; } + + public readonly struct ReadOnlyStruct + { + private readonly int dummy; + } } } diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il index 8a9c4495c..97585d376 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.opt.roslyn.il @@ -33,64 +33,13 @@ // =============== CLASS MEMBERS DECLARATION =================== -.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: ret - } // end of method EmbeddedAttribute::.ctor - -} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute - -.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: ret - } // end of method IsReadOnlyAttribute::.ctor - -} // end of class System.Runtime.CompilerServices.IsReadOnlyAttribute - -.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsByRefLikeAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 7 (0x7) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: ret - } // end of method IsByRefLikeAttribute::.ctor - -} // end of class System.Runtime.CompilerServices.IsByRefLikeAttribute - .class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns extends [mscorlib]System.Object { .class sequential ansi sealed nested public beforefieldinit RefStruct extends [mscorlib]System.ValueType { - .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference @@ -104,7 +53,7 @@ .class sequential ansi sealed nested public beforefieldinit ReadOnlyRefStruct extends [mscorlib]System.ValueType { - .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference @@ -112,10 +61,17 @@ 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp 69 6C 65 72 2E 01 00 00 ) // iler.... - .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) .field private initonly int32 dummy } // end of class ReadOnlyRefStruct + .class sequential ansi sealed nested public beforefieldinit ReadOnlyStruct + extends [mscorlib]System.ValueType + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .field private initonly int32 dummy + } // end of class ReadOnlyStruct + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il index 9dd7c14dd..9ac033006 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.roslyn.il @@ -33,67 +33,13 @@ // =============== CLASS MEMBERS DECLARATION =================== -.class private auto ansi sealed beforefieldinit Microsoft.CodeAnalysis.EmbeddedAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: nop - IL_0007: ret - } // end of method EmbeddedAttribute::.ctor - -} // end of class Microsoft.CodeAnalysis.EmbeddedAttribute - -.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsReadOnlyAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: nop - IL_0007: ret - } // end of method IsReadOnlyAttribute::.ctor - -} // end of class System.Runtime.CompilerServices.IsReadOnlyAttribute - -.class private auto ansi sealed beforefieldinit System.Runtime.CompilerServices.IsByRefLikeAttribute - extends [mscorlib]System.Attribute -{ - .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) - .custom instance void Microsoft.CodeAnalysis.EmbeddedAttribute::.ctor() = ( 01 00 00 00 ) - .method public hidebysig specialname rtspecialname - instance void .ctor() cil managed - { - // Code size 8 (0x8) - .maxstack 8 - IL_0000: ldarg.0 - IL_0001: call instance void [mscorlib]System.Attribute::.ctor() - IL_0006: nop - IL_0007: ret - } // end of method IsByRefLikeAttribute::.ctor - -} // end of class System.Runtime.CompilerServices.IsByRefLikeAttribute - .class private auto ansi beforefieldinit ICSharpCode.Decompiler.Tests.TestCases.Pretty.RefLocalsAndReturns extends [mscorlib]System.Object { .class sequential ansi sealed nested public beforefieldinit RefStruct extends [mscorlib]System.ValueType { - .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference @@ -107,7 +53,7 @@ .class sequential ansi sealed nested public beforefieldinit ReadOnlyRefStruct extends [mscorlib]System.ValueType { - .custom instance void System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsByRefLikeAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.ObsoleteAttribute::.ctor(string, bool) = ( 01 00 52 54 79 70 65 73 20 77 69 74 68 20 65 6D // ..RTypes with em 62 65 64 64 65 64 20 72 65 66 65 72 65 6E 63 65 // bedded reference @@ -115,10 +61,17 @@ 74 65 64 20 69 6E 20 74 68 69 73 20 76 65 72 73 // ted in this vers 69 6F 6E 20 6F 66 20 79 6F 75 72 20 63 6F 6D 70 // ion of your comp 69 6C 65 72 2E 01 00 00 ) // iler.... - .custom instance void System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) .field private initonly int32 dummy } // end of class ReadOnlyRefStruct + .class sequential ansi sealed nested public beforefieldinit ReadOnlyStruct + extends [mscorlib]System.ValueType + { + .custom instance void [mscorlib]System.Runtime.CompilerServices.IsReadOnlyAttribute::.ctor() = ( 01 00 00 00 ) + .field private initonly int32 dummy + } // end of class ReadOnlyStruct + .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs index 2469e2555..2ae8e5b37 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs @@ -634,6 +634,31 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem Assert.IsFalse(p.IsOptional); Assert.IsFalse(p.IsRef); Assert.IsTrue(p.IsOut); + Assert.IsFalse(p.IsIn); + Assert.AreEqual(0, p.GetAttributes().Count()); + Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); + } + + [Test] + public void MethodWithRefParameter() + { + IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithRefParameter").Parameters.Single(); + Assert.IsFalse(p.IsOptional); + Assert.IsTrue(p.IsRef); + Assert.IsFalse(p.IsOut); + Assert.IsFalse(p.IsIn); + Assert.AreEqual(0, p.GetAttributes().Count()); + Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); + } + + [Test] + public void MethodWithInParameter() + { + IParameter p = GetTypeDefinition(typeof(ParameterTests)).Methods.Single(m => m.Name == "MethodWithInParameter").Parameters.Single(); + Assert.IsFalse(p.IsOptional); + Assert.IsFalse(p.IsRef); + Assert.IsFalse(p.IsOut); + Assert.IsTrue(p.IsIn); Assert.AreEqual(0, p.GetAttributes().Count()); Assert.IsTrue(p.Type.Kind == TypeKind.ByReference); } diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs index 6c36c9128..ee8544b04 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs @@ -158,6 +158,8 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem public void MethodWithParamsArray(params object[] x) { } public void MethodWithOptionalParameter(int x = 4) { } public void MethodWithExplicitOptionalParameter([Optional] int x) { } + public void MethodWithRefParameter(ref int x) { } + public void MethodWithInParameter(in int x) { } public void MethodWithEnumOptionalParameter(StringComparison x = StringComparison.OrdinalIgnoreCase) { } public void MethodWithOptionalNullableParameter(int? x = null) { } public void MethodWithOptionalLongParameter(long x = 1) { } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs index 00ebd3088..efc3f8a8c 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultParameter.cs @@ -84,7 +84,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation } public bool IsIn { - get { return IsIn; } + get { return isIn; } } public bool IsParams { diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs index eabc198f4..6bfcefb25 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataParameter.cs @@ -80,7 +80,17 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation #endregion const ParameterAttributes inOut = ParameterAttributes.In | ParameterAttributes.Out; - public bool IsRef => Type.Kind == TypeKind.ByReference && (attributes & inOut) == 0; + + public bool IsRef { + get { + if (!(Type.Kind == TypeKind.ByReference && (attributes & inOut) != ParameterAttributes.Out)) + return false; + var metadata = module.metadata; + var parameterDef = metadata.GetParameter(handle); + return !parameterDef.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly); + } + } + public bool IsOut => Type.Kind == TypeKind.ByReference && (attributes & inOut) == ParameterAttributes.Out; public bool IsOptional => (attributes & ParameterAttributes.Optional) != 0;