Browse Source

Fix #2389: missing extern keyword for properties and events.

pull/2408/head
Siegfried Pammer 4 years ago
parent
commit
aa147870a2
  1. 2
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  2. 10
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/MemberTests.cs
  3. 21
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  4. 3
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

2
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -191,7 +191,7 @@ @@ -191,7 +191,7 @@
<Compile Include="TestCases\Pretty\CustomAttributeConflicts.cs" />
<Compile Include="TestCases\Pretty\DynamicTests.cs" />
<Compile Include="TestCases\Pretty\Issue1080.cs" />
<Compile Include="TestCases\Pretty\MemberTests.cs" />
<None Include="TestCases\Pretty\MemberTests.cs" />
<Compile Include="TestCases\Pretty\NamedArguments.cs" />
<Compile Include="TestCases\Pretty\QualifierTests.cs" />
<Compile Include="TestCases\Pretty\RefLocalsAndReturns.cs" />

10
ICSharpCode.Decompiler.Tests/TestCases/Pretty/MemberTests.cs

@ -30,11 +30,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -30,11 +30,13 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
#if ROSLYN
public int this[int index] => 0;
#else
#pragma warning disable format
public int this[int index] {
get {
return 0;
}
}
#pragma warning restore format
#endif
}
@ -49,11 +51,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -49,11 +51,19 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private volatile int volatileField = 3;
private static volatile int staticVolatileField = 4;
public extern int ExternGetOnly { get; }
public extern int ExternSetOnly { set; }
public extern int ExternProperty { get; set; }
public extern event EventHandler Event;
public void UseVolatileFields()
{
Console.WriteLine(volatileField + staticVolatileField);
volatileField++;
staticVolatileField++;
}
public extern void ExternMethod();
}
}

21
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -1735,14 +1735,21 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1735,14 +1735,21 @@ namespace ICSharpCode.Decompiler.CSharp
getter = ((IndexerDeclaration)propertyDecl).Getter;
setter = ((IndexerDeclaration)propertyDecl).Setter;
}
if (property.CanGet && property.Getter.HasBody)
bool getterHasBody = property.CanGet && property.Getter.HasBody;
bool setterHasBody = property.CanSet && property.Setter.HasBody;
if (getterHasBody)
{
DecompileBody(property.Getter, getter, decompileRun, decompilationContext);
}
if (property.CanSet && property.Setter.HasBody)
if (setterHasBody)
{
DecompileBody(property.Setter, setter, decompileRun, decompilationContext);
}
if (!getterHasBody && !setterHasBody && !property.IsAbstract && property.DeclaringType.Kind != TypeKind.Interface)
{
propertyDecl.Modifiers |= Modifiers.Extern;
}
var accessorHandle = (MethodDefinitionHandle)(property.Getter ?? property.Setter).MetadataToken;
var accessor = metadata.GetMethodDefinition(accessorHandle);
if (!accessorHandle.GetMethodImplementations(metadata).Any() && accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))
@ -1768,14 +1775,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1768,14 +1775,20 @@ namespace ICSharpCode.Decompiler.CSharp
{
eventDecl.Name = ev.Name.Substring(lastDot + 1);
}
if (ev.CanAdd && ev.AddAccessor.HasBody)
bool adderHasBody = ev.CanAdd && ev.AddAccessor.HasBody;
bool removerHasBody = ev.CanRemove && ev.RemoveAccessor.HasBody;
if (adderHasBody)
{
DecompileBody(ev.AddAccessor, ((CustomEventDeclaration)eventDecl).AddAccessor, decompileRun, decompilationContext);
}
if (ev.CanRemove && ev.RemoveAccessor.HasBody)
if (removerHasBody)
{
DecompileBody(ev.RemoveAccessor, ((CustomEventDeclaration)eventDecl).RemoveAccessor, decompileRun, decompilationContext);
}
if (!adderHasBody && !removerHasBody && !ev.IsAbstract && ev.DeclaringType.Kind != TypeKind.Interface)
{
eventDecl.Modifiers |= Modifiers.Extern;
}
var accessor = metadata.GetMethodDefinition((MethodDefinitionHandle)(ev.AddAccessor ?? ev.RemoveAccessor).MetadataToken);
if (accessor.HasFlag(System.Reflection.MethodAttributes.Virtual) == accessor.HasFlag(System.Reflection.MethodAttributes.NewSlot))
{

3
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -986,7 +986,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -986,7 +986,8 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
{
if (!ev.PrivateImplementationType.IsNull)
return null;
if (!ev.Modifiers.HasFlag(Modifiers.Abstract))
const Modifiers withoutBody = Modifiers.Abstract | Modifiers.Extern;
if ((ev.Modifiers & withoutBody) == 0 && ev.GetSymbol() is IEvent symbol && symbol.DeclaringType.Kind != TypeKind.Interface)
{
if (!CheckAutomaticEventV4AggressivelyInlined(ev) && !CheckAutomaticEventV4(ev) && !CheckAutomaticEventV2(ev) && !CheckAutomaticEventV4MCS(ev))
return null;

Loading…
Cancel
Save