Browse Source

Fix CSharpDecompiler.SetNewModifier: follow rules stated in the language specification.

pull/1440/head
Siegfried Pammer 6 years ago
parent
commit
545be6d133
  1. 1
      ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
  2. 93
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeMemberTests.cs
  3. 322
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeMemberTests.roslyn.il
  4. 67
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

1
ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs

@ -409,7 +409,6 @@ namespace ICSharpCode.Decompiler.Tests @@ -409,7 +409,6 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
[Ignore("missing 'new' modifiers in a lot of contexts.")]
public void TypeMemberTests([ValueSource(nameof(defaultOptions))] CompilerOptions cscOptions)
{
RunForLibrary(cscOptions: cscOptions);

93
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeMemberTests.cs

@ -22,11 +22,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -22,11 +22,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
public class IndexerWithGetOnly
{
#if ROSLYN
public int this[int i] => i;
#else
public int this[int i] {
get {
return i;
}
}
#endif
}
public class IndexerWithSetOnly
{
@ -38,28 +42,40 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -38,28 +42,40 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public class IndexerWithMoreParameters
{
#if ROSLYN
public int this[int i, string s, Type t] => 0;
#else
public int this[int i, string s, Type t] {
get {
return 0;
}
}
#endif
}
public class IndexerInGenericClass<T>
{
#if ROSLYN
public int this[T t] => 0;
#else
public int this[T t] {
get {
return 0;
}
}
#endif
}
public class OverloadedIndexer
{
{
#if ROSLYN
public int this[int t] => 0;
#else
public int this[int t] {
get {
return 0;
}
}
#endif
public int this[string s] {
get {
return 0;
@ -70,7 +86,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -70,7 +86,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
public interface IIndexerInInterface
{
{
int this[string s, string s2] {
set;
}
@ -83,11 +99,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -83,11 +99,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class MyClass_IndexerInterfaceExplicitImplementation : IMyInterface_IndexerInterfaceExplicitImplementation
{
#if ROSLYN
int IMyInterface_IndexerInterfaceExplicitImplementation.this[string s] => 3;
#else
int IMyInterface_IndexerInterfaceExplicitImplementation.this[string s] {
get {
return 3;
}
}
#endif
}
public interface IMyInterface_IndexerInterfaceImplementation
{
@ -97,11 +117,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -97,11 +117,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class MyClass_IndexerInterfaceImplementation : IMyInterface_IndexerInterfaceImplementation
{
#if ROSLYN
public int this[string s] => 3;
#else
public int this[string s] {
get {
return 3;
}
}
#endif
}
public abstract class MyClass_IndexerAbstract
{
@ -223,11 +247,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -223,11 +247,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class Derived_PropertyOverrideDefaultAccessorOnly : MyClass_PropertyOverrideDefaultAccessorOnly
{
#if ROSLYN
public override int MyProperty => 4;
#else
public override int MyProperty {
get {
return 4;
}
}
#endif
}
public class MyClass_PropertyOverrideRestrictedAccessorOnly
{
@ -325,6 +353,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -325,6 +353,10 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public class A_HideMembers
{
public int F;
#if ROSLYN
public int Prop => 3;
public int G => 3;
#else
public int Prop {
get {
return 3;
@ -335,9 +367,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -335,9 +367,14 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return 3;
}
}
#endif
}
public class B_HideMembers : A_HideMembers
{
#if ROSLYN
public new int F => 3;
public new string Prop => "a";
#else
public new int F {
get {
return 3;
@ -348,6 +385,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -348,6 +385,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
return "a";
}
}
#endif
}
public class C_HideMembers : A_HideMembers
{
@ -371,51 +409,75 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -371,51 +409,75 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class G_HideMembers2
{
#if ROSLYN
public int Item => 1;
#else
public int Item {
get {
return 1;
}
}
#endif
}
public class G2_HideMembers2 : G_HideMembers2
{
#if ROSLYN
public int this[int i] => 2;
#else
public int this[int i] {
get {
return 2;
}
}
#endif
}
public class G3_HideMembers2 : G2_HideMembers2
{
#if ROSLYN
public new int Item => 4;
#else
public new int Item {
get {
return 4;
}
}
#endif
}
public class H_HideMembers2
{
#if ROSLYN
public int this[int j] => 0;
#else
public int this[int j] {
get {
return 0;
}
}
#endif
}
public class H2_HideMembers2 : H_HideMembers2
{
#if ROSLYN
public int Item => 2;
#else
public int Item {
get {
return 2;
}
}
#endif
}
public class H3_HideMembers2 : H2_HideMembers2
{
#if ROSLYN
public new string this[int j] => null;
#else
public new string this[int j] {
get {
return null;
}
}
#endif
}
public interface IA_HideMembers2a
{
@ -433,11 +495,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -433,11 +495,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class A1_HideMembers2a : A_HideMembers2a
{
#if ROSLYN
public int this[int i] => 3;
#else
public int this[int i] {
get {
return 3;
}
}
#endif
}
public class G_HideMembers3<T>
{
@ -469,15 +535,20 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -469,15 +535,20 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class J_HideMembers3
{
#if ROSLYN
public int P => 2;
#else
public int P {
get {
return 2;
}
}
#endif
}
public class J2_HideMembers3 : J_HideMembers3
{
#pragma warning disable 0108 // Deliberate bad code for test case
#pragma warning disable 0108
// Deliberate bad code for test case
public int get_P;
#pragma warning restore 0108
}
@ -563,11 +634,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -563,11 +634,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
public class A_HideMemberSkipNotVisible
{
protected int F;
#if ROSLYN
protected string P => null;
#else
protected string P {
get {
return null;
}
}
#endif
}
public class B_HideMemberSkipNotVisible : A_HideMemberSkipNotVisible
{
@ -605,11 +680,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -605,11 +680,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class A_HidePropertyReservedMethod
{
#if ROSLYN
public int P => 1;
#else
public int P {
get {
return 1;
}
}
#endif
}
public class B_HidePropertyReservedMethod : A_HidePropertyReservedMethod
{
@ -623,11 +702,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -623,11 +702,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class A_HideIndexerDiffAccessor
{
#if ROSLYN
public int this[int i] => 2;
#else
public int this[int i] {
get {
return 2;
}
}
#endif
}
public class B_HideIndexerDiffAccessor : A_HideIndexerDiffAccessor
{
@ -828,11 +911,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -828,11 +911,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
public class A_HideMethodStatic
{
#if ROSLYN
public int N => 0;
#else
public int N {
get {
return 0;
}
}
#endif
}
public class B_HideMethodStatic
{

322
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TypeMemberTests.roslyn.il

@ -40,16 +40,10 @@ @@ -40,16 +40,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 i) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldarg.1
IL_0001: ret
} // end of method IndexerWithGetOnly::get_Item
.method public hidebysig specialname rtspecialname
@ -110,16 +104,10 @@ @@ -110,16 +104,10 @@
string s,
class [mscorlib]System.Type t) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: ret
} // end of method IndexerWithMoreParameters::get_Item
.method public hidebysig specialname rtspecialname
@ -150,16 +138,10 @@ @@ -150,16 +138,10 @@
.method public hidebysig specialname instance int32
get_Item(!T t) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: ret
} // end of method IndexerInGenericClass`1::get_Item
.method public hidebysig specialname rtspecialname
@ -186,16 +168,10 @@ @@ -186,16 +168,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 t) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: ret
} // end of method OverloadedIndexer::get_Item
.method public hidebysig specialname instance int32
@ -296,16 +272,10 @@ @@ -296,16 +272,10 @@
instance int32 ICSharpCode.Decompiler.Tests.TestCases.Pretty.IMyInterface_IndexerInterfaceExplicitImplementation.get_Item(string s) cil managed
{
.override ICSharpCode.Decompiler.Tests.TestCases.Pretty.IMyInterface_IndexerInterfaceExplicitImplementation::get_Item
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method MyClass_IndexerInterfaceExplicitImplementation::ICSharpCode.Decompiler.Tests.TestCases.Pretty.IMyInterface_IndexerInterfaceExplicitImplementation.get_Item
.method public hidebysig specialname rtspecialname
@ -347,16 +317,10 @@ @@ -347,16 +317,10 @@
.method public hidebysig newslot specialname virtual final
instance int32 get_Item(string s) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method MyClass_IndexerInterfaceImplementation::get_Item
.method public hidebysig specialname rtspecialname
@ -845,16 +809,10 @@ @@ -845,16 +809,10 @@
.method public hidebysig specialname virtual
instance int32 get_MyProperty() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.4
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.4
IL_0001: ret
} // end of method Derived_PropertyOverrideDefaultAccessorOnly::get_MyProperty
.method public hidebysig specialname rtspecialname
@ -1292,31 +1250,19 @@ @@ -1292,31 +1250,19 @@
.method public hidebysig specialname instance int32
get_Prop() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method A_HideMembers::get_Prop
.method public hidebysig specialname instance int32
get_G() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method A_HideMembers::get_G
.method public hidebysig specialname rtspecialname
@ -1346,31 +1292,19 @@ @@ -1346,31 +1292,19 @@
.method public hidebysig specialname instance int32
get_F() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method B_HideMembers::get_F
.method public hidebysig specialname instance string
get_Prop() cil managed
{
// Code size 11 (0xb)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldstr "a"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
// Code size 6 (0x6)
.maxstack 8
IL_0000: ldstr "a"
IL_0005: ret
} // end of method B_HideMembers::get_Prop
.method public hidebysig specialname rtspecialname
@ -1491,16 +1425,10 @@ @@ -1491,16 +1425,10 @@
.method public hidebysig specialname instance int32
get_Item() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: ret
} // end of method G_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1527,16 +1455,10 @@ @@ -1527,16 +1455,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 i) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.2
IL_0001: ret
} // end of method G2_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1562,16 +1484,10 @@ @@ -1562,16 +1484,10 @@
.method public hidebysig specialname instance int32
get_Item() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.4
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.4
IL_0001: ret
} // end of method G3_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1598,16 +1514,10 @@ @@ -1598,16 +1514,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 j) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: ret
} // end of method H_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1633,16 +1543,10 @@ @@ -1633,16 +1543,10 @@
.method public hidebysig specialname instance int32
get_Item() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.2
IL_0001: ret
} // end of method H2_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1669,16 +1573,10 @@ @@ -1669,16 +1573,10 @@
.method public hidebysig specialname instance string
get_Item(int32 j) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: ret
} // end of method H3_HideMembers2::get_Item
.method public hidebysig specialname rtspecialname
@ -1751,16 +1649,10 @@ @@ -1751,16 +1649,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 i) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.3
IL_0001: ret
} // end of method A1_HideMembers2a::get_Item
.method public hidebysig specialname rtspecialname
@ -1903,16 +1795,10 @@ @@ -1903,16 +1795,10 @@
.method public hidebysig specialname instance int32
get_P() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.2
IL_0001: ret
} // end of method J_HideMembers3::get_P
.method public hidebysig specialname rtspecialname
@ -2263,16 +2149,10 @@ @@ -2263,16 +2149,10 @@
.method family hidebysig specialname instance string
get_P() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (string V_0)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldnull
IL_0001: ret
} // end of method A_HideMemberSkipNotVisible::get_P
.method public hidebysig specialname rtspecialname
@ -2445,16 +2325,10 @@ @@ -2445,16 +2325,10 @@
.method public hidebysig specialname instance int32
get_P() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.1
IL_0001: ret
} // end of method A_HidePropertyReservedMethod::get_P
.method public hidebysig specialname rtspecialname
@ -2521,16 +2395,10 @@ @@ -2521,16 +2395,10 @@
.method public hidebysig specialname instance int32
get_Item(int32 i) cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.2
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.2
IL_0001: ret
} // end of method A_HideIndexerDiffAccessor::get_Item
.method public hidebysig specialname rtspecialname
@ -3361,16 +3229,10 @@ @@ -3361,16 +3229,10 @@
.method public hidebysig specialname instance int32
get_N() cil managed
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int32 V_0)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0005
IL_0005: ldloc.0
IL_0006: ret
// Code size 2 (0x2)
.maxstack 8
IL_0000: ldc.i4.0
IL_0001: ret
} // end of method A_HideMethodStatic::get_N
.method public hidebysig specialname rtspecialname

67
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -889,34 +889,55 @@ namespace ICSharpCode.Decompiler.CSharp @@ -889,34 +889,55 @@ namespace ICSharpCode.Decompiler.CSharp
/// <param name="member">The node of the member which new modifier state should be determined.</param>
void SetNewModifier(EntityDeclaration member)
{
bool addNewModifier = false;
var entity = (IEntity)member.GetSymbol();
var lookup = new MemberLookup(entity.DeclaringTypeDefinition, entity.ParentModule);
var baseTypes = entity.DeclaringType.GetNonInterfaceBaseTypes().Where(t => entity.DeclaringType != t);
if (entity is ITypeDefinition) {
addNewModifier = baseTypes.SelectMany(b => b.GetNestedTypes(t => t.Name == entity.Name && lookup.IsAccessible(t, true))).Any();
} else {
var members = baseTypes.SelectMany(b => b.GetMembers(m => m.Name == entity.Name).Where(m => lookup.IsAccessible(m, true)));
switch (entity.SymbolKind) {
case SymbolKind.Field:
case SymbolKind.Property:
case SymbolKind.Event:
addNewModifier = members.Any();
break;
case SymbolKind.Method:
case SymbolKind.Constructor:
case SymbolKind.Indexer:
case SymbolKind.Operator:
addNewModifier = members.Any(m => SignatureComparer.Ordinal.Equals(m, (IMember)entity));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
var baseTypes = entity.DeclaringType.GetNonInterfaceBaseTypes().Where(t => entity.DeclaringType != t).ToList();
if (addNewModifier)
// A constant, field, property, event, or type introduced in a class or struct hides all base class members with the same name.
bool hideBasedOnSignature = !(entity is ITypeDefinition
|| entity.SymbolKind == SymbolKind.Field
|| entity.SymbolKind == SymbolKind.Property
|| entity.SymbolKind == SymbolKind.Event);
const GetMemberOptions options = GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions;
if (HidesMemberOrTypeOfBaseType())
member.Modifiers |= Modifiers.New;
bool HidesMemberOrTypeOfBaseType()
{
var parameterListComparer = ParameterListComparer.WithOptions(includeModifiers: true);
foreach (IType baseType in baseTypes) {
if (!hideBasedOnSignature) {
if (baseType.GetNestedTypes(t => t.Name == entity.Name && lookup.IsAccessible(t, true), options).Any())
return true;
if (baseType.GetMembers(m => m.Name == entity.Name && m.SymbolKind != SymbolKind.Indexer && lookup.IsAccessible(m, true), options).Any())
return true;
} else {
if (entity.SymbolKind == SymbolKind.Indexer) {
// An indexer introduced in a class or struct hides all base class indexers with the same signature (parameter count and types).
if (baseType.GetProperties(p => p.SymbolKind == SymbolKind.Indexer && lookup.IsAccessible(p, true))
.Any(p => parameterListComparer.Equals(((IProperty)entity).Parameters, p.Parameters)))
{
return true;
}
} else if (entity.SymbolKind == SymbolKind.Method) {
// A method introduced in a class or struct hides all non-method base class members with the same name, and all
// base class methods with the same signature (method name and parameter count, modifiers, and types).
if (baseType.GetMembers(m => m.SymbolKind != SymbolKind.Indexer && m.Name == entity.Name && lookup.IsAccessible(m, true))
.Any(m => m.SymbolKind != SymbolKind.Method || (((IMethod)entity).TypeParameters.Count == ((IMethod)m).TypeParameters.Count
&& parameterListComparer.Equals(((IMethod)entity).Parameters, ((IMethod)m).Parameters))))
{
return true;
}
}
}
}
return false;
}
}
void FixParameterNames(EntityDeclaration entity)

Loading…
Cancel
Save