Browse Source

Expose IMethod.AccessorKind. This makes it easier to determine if a method is a setter, particular in generic classes where "m.AccessorOwner?.Setter == m" ended up being wrong.

pull/1464/head
Daniel Grunwald 6 years ago
parent
commit
a5505ab00d
  1. 20
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ValueTypes.cs
  2. 15
      ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs
  3. 2
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  4. 18
      ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs
  5. 6
      ICSharpCode.Decompiler/TypeSystem/IMethod.cs
  6. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
  7. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  8. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  9. 15
      ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

20
ICSharpCode.Decompiler.Tests/TestCases/Pretty/ValueTypes.cs

@ -25,6 +25,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -25,6 +25,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public int Field;
public int Property {
get {
return Field;
}
set {
Field = value;
}
}
public S(int field)
{
Field = field;
@ -184,5 +193,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -184,5 +193,16 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
Console.WriteLine("true");
}
}
public static void CallOnTemporary()
{
// Method can be called directly on temporaries
//InitObj2().MethodCalls();
// Setting a property requires a temporary to avoid
// CS1612 Cannot modify the return value of 'InitObj2()' because it is not a variable
S s = InitObj2();
s.Property = 1;
}
}
}

15
ICSharpCode.Decompiler/CSharp/Resolver/ReducedExtensionMethod.cs

@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ICSharpCode.Decompiler.TypeSystem;
namespace ICSharpCode.Decompiler.CSharp.Resolver
@ -172,17 +173,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver @@ -172,17 +173,9 @@ namespace ICSharpCode.Decompiler.CSharp.Resolver
}
}
public bool IsAccessor {
get {
return baseMethod.IsAccessor;
}
}
public IMember AccessorOwner {
get {
return baseMethod.AccessorOwner;
}
}
public bool IsAccessor => baseMethod.IsAccessor;
public IMember AccessorOwner => baseMethod.AccessorOwner;
public MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind;
public IMethod ReducedFrom {
get {

2
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -763,7 +763,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -763,7 +763,7 @@ namespace ICSharpCode.Decompiler.CSharp
return false;
switch (targetMethod.AccessorOwner) {
case IProperty p:
return p.Setter == targetMethod;
return targetMethod.AccessorKind == System.Reflection.MethodSemanticsAttributes.Setter;
default:
return true;
}

18
ICSharpCode.Decompiler/IL/Transforms/AssignVariableNames.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Humanizer;
@ -71,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -71,7 +72,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var lastParameter = f.Method.Parameters.Last();
switch (f.Method.AccessorOwner) {
case IProperty prop:
if (prop.Setter == f.Method) {
if (f.Method.AccessorKind == MethodSemanticsAttributes.Setter) {
if (prop.Parameters.Any(p => p.Name == "value")) {
f.Warnings.Add("Parameter named \"value\" already present in property signature!");
break;
@ -90,7 +91,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -90,7 +91,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
break;
case IEvent ev:
if (f.Method != ev.InvokeAccessor) {
if (f.Method.AccessorKind != MethodSemanticsAttributes.Raiser) {
var variableForLastParameter = f.Variables.FirstOrDefault(v => v.Function == f
&& v.Kind == VariableKind.Parameter
&& v.Index == f.Method.Parameters.Count - 1);
@ -124,11 +125,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -124,11 +125,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
bool IsSetOrEventAccessor(IMethod method)
{
if (method.AccessorOwner is IProperty p)
return p.Setter == method;
if (method.AccessorOwner is IEvent e)
return e.InvokeAccessor != method;
return false;
switch (method.AccessorKind) {
case MethodSemanticsAttributes.Setter:
case MethodSemanticsAttributes.Adder:
case MethodSemanticsAttributes.Remover:
return true;
default:
return false;
}
}
void PerformAssignment(ILFunction function)

6
ICSharpCode.Decompiler/TypeSystem/IMethod.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace ICSharpCode.Decompiler.TypeSystem
{
@ -69,6 +70,11 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -69,6 +70,11 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
IMember AccessorOwner { get; }
/// <summary>
/// Gets the kind of accessor this is.
/// </summary>
MethodSemanticsAttributes AccessorKind { get; }
/// <summary>
/// If this method is reduced from an extension method return the original method, <c>null</c> otherwise.
/// A reduced method doesn't contain the extension method parameter. That means that has one parameter less than it's definition.

2
ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs

@ -18,6 +18,7 @@ @@ -18,6 +18,7 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Util;
@ -144,6 +145,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -144,6 +145,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
bool IMethod.HasBody => false;
bool IMethod.IsAccessor => false;
IMember IMethod.AccessorOwner => null;
MethodSemanticsAttributes IMethod.AccessorKind => 0;
IMethod IMethod.ReducedFrom => null;

3
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs

@ -25,7 +25,6 @@ using System.Reflection.Metadata; @@ -25,7 +25,6 @@ using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.Util;
namespace ICSharpCode.Decompiler.TypeSystem.Implementation
@ -40,6 +39,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -40,6 +39,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
readonly SymbolKind symbolKind;
readonly ITypeParameter[] typeParameters;
readonly EntityHandle accessorOwner;
public MethodSemanticsAttributes AccessorKind { get; }
public bool IsExtensionMethod { get; }
// lazy-loaded fields:
@ -64,6 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -64,6 +64,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
if (semanticsAttribute != 0) {
this.symbolKind = SymbolKind.Accessor;
this.accessorOwner = accessorOwner;
this.AccessorKind = semanticsAttribute;
} else if ((attributes & (MethodAttributes.SpecialName | MethodAttributes.RTSpecialName)) != 0) {
string name = this.Name;
if (name == ".cctor" || name == ".ctor")

3
ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using ICSharpCode.Decompiler.Util;
@ -125,6 +126,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -125,6 +126,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
get { return methodDefinition.IsAccessor; }
}
public MethodSemanticsAttributes AccessorKind => methodDefinition.AccessorKind;
public IMethod ReducedFrom {
get { return null; }
}

15
ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

@ -20,6 +20,7 @@ using System; @@ -20,6 +20,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Text;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
@ -142,14 +143,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -142,14 +143,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
public bool HasBody {
get { return baseMethod.HasBody; }
}
public bool IsAccessor {
get { return baseMethod.IsAccessor; }
}
public IMember AccessorOwner {
get { return baseMethod.AccessorOwner; }
}
public bool IsAccessor => baseMethod.IsAccessor;
public IMember AccessorOwner => baseMethod.AccessorOwner;
public MethodSemanticsAttributes AccessorKind => baseMethod.AccessorKind;
public IMethod ReducedFrom {
get { return baseMethod.ReducedFrom; }
@ -158,7 +155,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -158,7 +155,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
#endregion
#region IMember implementation
IMember IMember.Specialize(TypeParameterSubstitution substitution)
{
return Specialize(substitution);

Loading…
Cancel
Save