Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy

pull/1728/head
Siegfried Pammer 6 years ago
parent
commit
8b8569bfce
  1. 1
      ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
  2. 4
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 48
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs
  4. 15
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  5. 3
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs
  6. 17
      ICSharpCode.Decompiler/DecompilerSettings.cs
  7. 2
      ICSharpCode.Decompiler/IL/ILReader.cs
  8. 4
      ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs
  9. 12
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  10. 6
      ICSharpCode.Decompiler/TypeSystem/IMethod.cs
  11. 11
      ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs
  12. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/FakeMember.cs
  13. 1
      ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs
  14. 18
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataMethod.cs
  15. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/SpecializedMethod.cs
  16. 1
      ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs
  17. 4
      ILSpy.Tests/ILSpy.Tests.csproj

1
ICSharpCode.Decompiler.Tests/Helpers/Tester.cs

@ -224,6 +224,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers @@ -224,6 +224,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
preprocessorSymbols.Add("CS71");
preprocessorSymbols.Add("CS72");
preprocessorSymbols.Add("CS73");
preprocessorSymbols.Add("CS80");
preprocessorSymbols.Add("VB11");
preprocessorSymbols.Add("VB14");
preprocessorSymbols.Add("VB15");

4
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -42,8 +42,8 @@ @@ -42,8 +42,8 @@
<ItemGroup>
<PackageReference Include="DiffLib" Version="2017.7.26.1241" />
<PackageReference Include="Microsoft.Build.Locator" Version="1.2.2" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.0-beta1-final" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.3.0-beta1-final" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.1" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.3.1" />
<PackageReference Include="Microsoft.DiaSymReader.Converter.Xml" Version="1.1.0-beta1-63314-01" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />

48
ICSharpCode.Decompiler.Tests/TestCases/Pretty/RefLocalsAndReturns.cs

@ -63,9 +63,57 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -63,9 +63,57 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
private readonly int dummy;
public int Property {
get {
return 1;
}
set {
}
}
#if CS80
public readonly int ReadOnlyProperty {
get {
return 1;
}
set {
}
}
public int PropertyWithReadOnlyGetter {
readonly get {
return 1;
}
set {
}
}
public int PropertyWithReadOnlySetter {
get {
return 1;
}
readonly set {
}
}
public event EventHandler NormalEvent;
public readonly event EventHandler ReadOnlyEvent {
add {
}
remove {
}
}
#endif
public void Method()
{
}
#if CS80
public readonly void ReadOnlyMethod()
{
}
#endif
}
public readonly struct ReadOnlyStruct

15
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -1522,6 +1522,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1522,6 +1522,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
Accessor decl = new Accessor();
if (this.ShowAccessibility && accessor.Accessibility != ownerAccessibility)
decl.Modifiers = ModifierFromAccessibility(accessor.Accessibility);
if (accessor.ThisIsRefReadOnly && accessor.DeclaringTypeDefinition?.IsReadOnly == false)
decl.Modifiers |= Modifiers.Readonly;
if (ShowAttributes) {
decl.Attributes.AddRange(ConvertAttributes(accessor.GetAttributes()));
decl.Attributes.AddRange(ConvertAttributes(accessor.GetReturnTypeAttributes(), "return"));
@ -1551,9 +1553,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1551,9 +1553,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Getter = ConvertAccessor(property.Getter, property.Accessibility, false);
decl.Setter = ConvertAccessor(property.Setter, property.Accessibility, true);
decl.PrivateImplementationType = GetExplicitInterfaceType (property);
MergeReadOnlyModifiers(decl, decl.Getter, decl.Setter);
return decl;
}
static void MergeReadOnlyModifiers(EntityDeclaration decl, Accessor accessor1, Accessor accessor2)
{
if (accessor1.HasModifier(Modifiers.Readonly) && accessor2.HasModifier(Modifiers.Readonly)) {
accessor1.Modifiers &= ~Modifiers.Readonly;
accessor2.Modifiers &= ~Modifiers.Readonly;
decl.Modifiers |= Modifiers.Readonly;
}
}
IndexerDeclaration ConvertIndexer(IProperty indexer)
{
IndexerDeclaration decl = new IndexerDeclaration();
@ -1571,6 +1582,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1571,6 +1582,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.Getter = ConvertAccessor(indexer.Getter, indexer.Accessibility, false);
decl.Setter = ConvertAccessor(indexer.Setter, indexer.Accessibility, true);
decl.PrivateImplementationType = GetExplicitInterfaceType (indexer);
MergeReadOnlyModifiers(decl, decl.Getter, decl.Setter);
return decl;
}
@ -1590,6 +1602,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1590,6 +1602,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl.AddAccessor = ConvertAccessor(ev.AddAccessor, ev.Accessibility, true);
decl.RemoveAccessor = ConvertAccessor(ev.RemoveAccessor, ev.Accessibility, true);
decl.PrivateImplementationType = GetExplicitInterfaceType (ev);
MergeReadOnlyModifiers(decl, decl.AddAccessor, decl.RemoveAccessor);
return decl;
} else {
EventDeclaration decl = new EventDeclaration();
@ -1759,6 +1772,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -1759,6 +1772,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
m |= Modifiers.Virtual;
if (member.IsSealed)
m |= Modifiers.Sealed;
if (member is IMethod method && method.ThisIsRefReadOnly && method.DeclaringTypeDefinition?.IsReadOnly == false)
m |= Modifiers.Readonly;
}
}
return m;

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

@ -571,11 +571,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -571,11 +571,14 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
}
if (field == null)
return null;
if (propertyDeclaration.Setter.HasModifier(Modifiers.Readonly))
return null;
if (field.IsCompilerGenerated() && field.DeclaringTypeDefinition == property.DeclaringTypeDefinition) {
RemoveCompilerGeneratedAttribute(propertyDeclaration.Getter.Attributes);
RemoveCompilerGeneratedAttribute(propertyDeclaration.Setter.Attributes);
propertyDeclaration.Getter.Body = null;
propertyDeclaration.Setter.Body = null;
propertyDeclaration.Getter.Modifiers &= ~Modifiers.Readonly;
// Add C# 7.3 attributes on backing field:
var attributes = field.GetAttributes()

17
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -107,12 +107,13 @@ namespace ICSharpCode.Decompiler @@ -107,12 +107,13 @@ namespace ICSharpCode.Decompiler
}
if (languageVersion < CSharp.LanguageVersion.CSharp8_0) {
nullableReferenceTypes = false;
readOnlyMethods = false;
}
}
public CSharp.LanguageVersion GetMinimumRequiredVersion()
{
if (nullableReferenceTypes)
if (nullableReferenceTypes || readOnlyMethods)
return CSharp.LanguageVersion.CSharp8_0;
if (introduceUnmanagedConstraint || tupleComparisons || stackAllocInitializers)
return CSharp.LanguageVersion.CSharp7_3;
@ -842,6 +843,20 @@ namespace ICSharpCode.Decompiler @@ -842,6 +843,20 @@ namespace ICSharpCode.Decompiler
}
}
bool readOnlyMethods = true;
[Category("C# 8.0 / VS 2019")]
[Description("DecompilerSettings.IsReadOnlyAttributeShouldBeReplacedWithReadonlyInModifiersOnStructsParameters")]
public bool ReadOnlyMethods {
get { return readOnlyMethods; }
set {
if (readOnlyMethods != value) {
readOnlyMethods = value;
OnPropertyChanged();
}
}
}
bool introduceUnmanagedConstraint = true;
/// <summary>

2
ICSharpCode.Decompiler/IL/ILReader.cs

@ -191,7 +191,7 @@ namespace ICSharpCode.Decompiler.IL @@ -191,7 +191,7 @@ namespace ICSharpCode.Decompiler.IL
declaringType = new ParameterizedType(declaringType, declaringType.TypeParameters);
}
ILVariable ilVar = CreateILVariable(-1, declaringType, "this");
ilVar.IsRefReadOnly = declaringType.GetDefinition()?.IsReadOnly == true;
ilVar.IsRefReadOnly = method.ThisIsRefReadOnly;
parameterVariables[paramIndex++] = ilVar;
}
while (paramIndex < parameterVariables.Length) {

4
ICSharpCode.Decompiler/IL/Transforms/ILInlining.cs

@ -272,8 +272,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -272,8 +272,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
var type = method.DeclaringType;
if (type.IsReferenceType == true)
return false; // reference types are never implicitly copied
if (type.GetDefinition()?.IsReadOnly == true)
return false; // readonly structs are never implicitly copied
if (method.ThisIsRefReadOnly)
return false; // no copies for calls on readonly structs
return true;
}

12
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -84,7 +84,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -84,7 +84,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
KeepModifiers = 0x40,
/// <summary>
/// If this option is active, [IsReadOnlyAttribute] is removed and parameters are marked as in, structs as readonly.
/// If this option is active, [IsReadOnlyAttribute] on parameters+structs is removed
/// and parameters are marked as in, structs as readonly.
/// Otherwise, the attribute is preserved but the parameters and structs are not marked.
/// </summary>
ReadOnlyStructsAndParameters = 0x80,
@ -104,10 +105,15 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -104,10 +105,15 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
NullabilityAnnotations = 0x400,
/// <summary>
/// If this option is active, [IsReadOnlyAttribute] on methods is removed
/// and the method marked as ThisIsRefReadOnly.
/// </summary>
ReadOnlyMethods = 0x800,
/// <summary>
/// Default settings: typical options for the decompiler, with all C# languages features enabled.
/// </summary>
Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants | ReadOnlyStructsAndParameters
| RefStructs | UnmanagedConstraints | NullabilityAnnotations
| RefStructs | UnmanagedConstraints | NullabilityAnnotations | ReadOnlyMethods
}
/// <summary>
@ -137,6 +143,8 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -137,6 +143,8 @@ namespace ICSharpCode.Decompiler.TypeSystem
typeSystemOptions |= TypeSystemOptions.UnmanagedConstraints;
if (settings.NullableReferenceTypes)
typeSystemOptions |= TypeSystemOptions.NullabilityAnnotations;
if (settings.ReadOnlyMethods)
typeSystemOptions |= TypeSystemOptions.ReadOnlyMethods;
return typeSystemOptions;
}

6
ICSharpCode.Decompiler/TypeSystem/IMethod.cs

@ -40,6 +40,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -40,6 +40,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// </summary>
bool ReturnTypeIsRefReadOnly { get; }
/// <summary>
/// Gets whether the method accepts the 'this' reference as ref readonly.
/// This can be either because the method is C# 8.0 'readonly', or because it is within a C# 7.2 'readonly struct'
/// </summary>
bool ThisIsRefReadOnly { get; }
/// <summary>
/// Gets the type parameters of this method; or an empty list if the method is not generic.
/// </summary>

11
ICSharpCode.Decompiler/TypeSystem/Implementation/AttributeListBuilder.cs

@ -201,7 +201,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -201,7 +201,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
case "DecimalConstantAttribute":
return (options & TypeSystemOptions.DecimalConstants) != 0 && (target == SymbolKind.Field || target == SymbolKind.Parameter);
case "IsReadOnlyAttribute":
return (options & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0;
switch (target) {
case SymbolKind.TypeDefinition:
case SymbolKind.Parameter:
return (options & TypeSystemOptions.ReadOnlyStructsAndParameters) != 0;
case SymbolKind.Method:
case SymbolKind.Accessor:
return (options & TypeSystemOptions.ReadOnlyMethods) != 0;
default:
return false;
}
case "IsByRefLikeAttribute":
return (options & TypeSystemOptions.RefStructs) != 0 && target == SymbolKind.TypeDefinition;
case "IsUnmanagedAttribute":

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

@ -133,6 +133,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -133,6 +133,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => EmptyList<IAttribute>.Instance;
bool IMethod.ReturnTypeIsRefReadOnly => false;
bool IMethod.ThisIsRefReadOnly => false;
public IReadOnlyList<ITypeParameter> TypeParameters { get; set; } = EmptyList<ITypeParameter>.Instance;

1
ICSharpCode.Decompiler/TypeSystem/Implementation/LocalFunctionMethod.cs

@ -117,6 +117,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -117,6 +117,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();
bool IMethod.ReturnTypeIsRefReadOnly => baseMethod.ReturnTypeIsRefReadOnly;
bool IMethod.ThisIsRefReadOnly => baseMethod.ThisIsRefReadOnly;
/// <summary>
/// We consider local functions as always static, because they do not have a "this parameter".
/// Even local functions in instance methods capture this.

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

@ -49,6 +49,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -49,6 +49,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
IParameter[] parameters;
IType returnType;
byte returnTypeIsRefReadonly = ThreeState.Unknown;
byte thisIsRefReadonly = ThreeState.Unknown;
internal MetadataMethod(MetadataModule module, MethodDefinitionHandle handle)
{
@ -424,6 +425,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -424,6 +425,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
return hasReadOnlyAttr;
}
}
public bool ThisIsRefReadOnly {
get {
if (thisIsRefReadonly != ThreeState.Unknown) {
return thisIsRefReadonly == ThreeState.True;
}
var metadata = module.metadata;
var methodDefinition = metadata.GetMethodDefinition(handle);
bool hasReadOnlyAttr = DeclaringTypeDefinition?.IsReadOnly ?? false;
if ((module.TypeSystemOptions & TypeSystemOptions.ReadOnlyMethods) != 0) {
hasReadOnlyAttr |= methodDefinition.GetCustomAttributes().HasKnownAttribute(metadata, KnownAttribute.IsReadOnly);
}
this.thisIsRefReadonly = ThreeState.From(hasReadOnlyAttr);
return hasReadOnlyAttr;
}
}
#endregion
public Accessibility Accessibility => GetAccessibility(attributes);

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

@ -97,6 +97,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -97,6 +97,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IEnumerable<IAttribute> GetReturnTypeAttributes() => methodDefinition.GetReturnTypeAttributes();
public bool ReturnTypeIsRefReadOnly => methodDefinition.ReturnTypeIsRefReadOnly;
bool IMethod.ThisIsRefReadOnly => methodDefinition.ThisIsRefReadOnly;
public IReadOnlyList<ITypeParameter> TypeParameters {
get {
return specializedTypeParameters ?? methodDefinition.TypeParameters;

1
ICSharpCode.Decompiler/TypeSystem/VarArgInstanceMethod.cs

@ -114,6 +114,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -114,6 +114,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
IEnumerable<IAttribute> IEntity.GetAttributes() => baseMethod.GetAttributes();
IEnumerable<IAttribute> IMethod.GetReturnTypeAttributes() => baseMethod.GetReturnTypeAttributes();
bool IMethod.ReturnTypeIsRefReadOnly => baseMethod.ReturnTypeIsRefReadOnly;
bool IMethod.ThisIsRefReadOnly => baseMethod.ThisIsRefReadOnly;
public IReadOnlyList<ITypeParameter> TypeParameters {
get { return baseMethod.TypeParameters; }

4
ILSpy.Tests/ILSpy.Tests.csproj

@ -42,8 +42,8 @@ @@ -42,8 +42,8 @@
<ItemGroup>
<PackageReference Include="DiffLib" Version="2017.7.26.1241" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.0.0-beta4-final" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.0.0-beta4-final" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.1" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic" Version="3.3.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
<PackageReference Include="NUnit" Version="3.11.0" />

Loading…
Cancel
Save