@ -21,6 +21,7 @@ using System.Collections.Generic;
@@ -21,6 +21,7 @@ using System.Collections.Generic;
using System.Collections.Immutable ;
using System.Diagnostics ;
using System.Linq ;
using System.Reflection ;
using ICSharpCode.Decompiler.CSharp.Resolver ;
using ICSharpCode.Decompiler.CSharp.TypeSystem ;
using ICSharpCode.Decompiler.Semantics ;
@ -205,6 +206,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -205,6 +206,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
/// The default value is <see langword="false" />.
/// </summary>
public bool PrintIntegralValuesAsHex { get ; set ; }
/// <summary>
/// Controls whether C# 9 "init;" accessors are supported.
/// If disabled, emits "set /*init*/;" instead.
/// </summary>
public bool SupportInitAccessors { get ; set ; }
#endregion
#region Convert Type
@ -1363,7 +1370,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1363,7 +1370,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ConvertDestructor ( ( IMethod ) entity ) ;
case SymbolKind . Accessor :
IMethod accessor = ( IMethod ) entity ;
return ConvertAccessor ( accessor , accessor . AccessorOwner ! = null ? accessor . AccessorOwner . Accessibility : Accessibility . None , false ) ;
Accessibility ownerAccessibility = accessor . AccessorOwner ? . Accessibility ? ? Accessibility . None ;
return ConvertAccessor ( accessor , accessor . AccessorKind , ownerAccessibility , false ) ;
default :
throw new ArgumentException ( "Invalid value for SymbolKind: " + entity . SymbolKind ) ;
}
@ -1554,15 +1562,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1554,15 +1562,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
Accessor ConvertAccessor ( IMethod accessor , Accessibility ownerAccessibility , bool addParameterAttribute )
Accessor ConvertAccessor ( IMethod accessor , MethodSemanticsAttributes kind , Accessibility ownerAccessibility , bool addParameterAttribute )
{
if ( accessor = = null )
return Accessor . Null ;
Accessor decl = new Accessor ( ) ;
if ( this . ShowAccessibility & & accessor . Accessibility ! = ownerAccessibility )
decl . Modifiers = ModifierFromAccessibility ( accessor . Accessibility ) ;
if ( accessor . HasReadonlyModifier ( ) )
decl . Modifiers | = Modifiers . Readonly ;
if ( ShowAttributes ) {
decl . Attributes . AddRange ( ConvertAttributes ( accessor . GetAttributes ( ) ) ) ;
decl . Attributes . AddRange ( ConvertAttributes ( accessor . GetReturnTypeAttributes ( ) , "return" ) ) ;
@ -1570,10 +1574,35 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1570,10 +1574,35 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
decl . Attributes . AddRange ( ConvertAttributes ( accessor . Parameters . Last ( ) . GetAttributes ( ) , "param" ) ) ;
}
}
if ( this . ShowAccessibility & & accessor . Accessibility ! = ownerAccessibility )
decl . Modifiers = ModifierFromAccessibility ( accessor . Accessibility ) ;
if ( accessor . HasReadonlyModifier ( ) )
decl . Modifiers | = Modifiers . Readonly ;
TokenRole keywordRole = kind switch
{
MethodSemanticsAttributes . Getter = > PropertyDeclaration . GetKeywordRole ,
MethodSemanticsAttributes . Setter = > PropertyDeclaration . SetKeywordRole ,
MethodSemanticsAttributes . Adder = > CustomEventDeclaration . AddKeywordRole ,
MethodSemanticsAttributes . Remover = > CustomEventDeclaration . RemoveKeywordRole ,
_ = > null
} ;
if ( kind = = MethodSemanticsAttributes . Setter & & SupportInitAccessors & & accessor . IsInitOnly ) {
keywordRole = PropertyDeclaration . InitKeywordRole ;
}
if ( keywordRole ! = null ) {
decl . AddChild ( new CSharpTokenNode ( TextLocation . Empty , keywordRole ) , keywordRole ) ;
}
if ( accessor . IsInitOnly & & keywordRole ! = PropertyDeclaration . InitKeywordRole ) {
decl . AddChild ( new Comment ( "init" , CommentType . MultiLine ) , Roles . Comment ) ;
}
if ( AddResolveResultAnnotations ) {
decl . AddAnnotation ( new MemberResolveResult ( null , accessor ) ) ;
}
decl . Body = GenerateBodyBlock ( ) ;
if ( GenerateBody ) {
decl . Body = GenerateBodyBlock ( ) ;
} else {
decl . AddChild ( new CSharpTokenNode ( TextLocation . Empty , Roles . Semicolon ) , Roles . Semicolon ) ;
}
return decl ;
}
@ -1592,8 +1621,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1592,8 +1621,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
ct . HasReadOnlySpecifier = true ;
}
decl . Name = property . Name ;
decl . Getter = ConvertAccessor ( property . Getter , property . Accessibility , false ) ;
decl . Setter = ConvertAccessor ( property . Setter , property . Accessibility , true ) ;
decl . Getter = ConvertAccessor ( property . Getter , MethodSemanticsAttributes . Getter , property . Accessibility , false ) ;
decl . Setter = ConvertAccessor ( property . Setter , MethodSemanticsAttributes . Setter , property . Accessibility , true ) ;
decl . PrivateImplementationType = GetExplicitInterfaceType ( property ) ;
MergeReadOnlyModifiers ( decl , decl . Getter , decl . Setter ) ;
return decl ;
@ -1624,8 +1653,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1624,8 +1653,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
foreach ( IParameter p in indexer . Parameters ) {
decl . Parameters . Add ( ConvertParameter ( p ) ) ;
}
decl . Getter = ConvertAccessor ( indexer . Getter , indexer . Accessibility , false ) ;
decl . Setter = ConvertAccessor ( indexer . Setter , indexer . Accessibility , true ) ;
decl . Getter = ConvertAccessor ( indexer . Getter , MethodSemanticsAttributes . Getter , indexer . Accessibility , false ) ;
decl . Setter = ConvertAccessor ( indexer . Setter , MethodSemanticsAttributes . Setter , indexer . Accessibility , true ) ;
decl . PrivateImplementationType = GetExplicitInterfaceType ( indexer ) ;
MergeReadOnlyModifiers ( decl , decl . Getter , decl . Setter ) ;
return decl ;
@ -1644,8 +1673,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1644,8 +1673,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
decl . ReturnType = ConvertType ( ev . ReturnType ) ;
decl . Name = ev . Name ;
decl . AddAccessor = ConvertAccessor ( ev . AddAccessor , ev . Accessibility , true ) ;
decl . RemoveAccessor = ConvertAccessor ( ev . RemoveAccessor , ev . Accessibility , true ) ;
decl . AddAccessor = ConvertAccessor ( ev . AddAccessor , MethodSemanticsAttributes . Adder , ev . Accessibility , true ) ;
decl . RemoveAccessor = ConvertAccessor ( ev . RemoveAccessor , MethodSemanticsAttributes . Remover , ev . Accessibility , true ) ;
decl . PrivateImplementationType = GetExplicitInterfaceType ( ev ) ;
MergeReadOnlyModifiers ( decl , decl . AddAccessor , decl . RemoveAccessor ) ;
return decl ;
@ -1799,6 +1828,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1799,6 +1828,8 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
return ! member . IsStatic ;
case SymbolKind . Destructor :
return false ;
case SymbolKind . Method :
return ! ( ( IMethod ) member ) . IsLocalFunction ;
default :
return true ;
}
@ -1811,7 +1842,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
@@ -1811,7 +1842,11 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
m | = ModifierFromAccessibility ( member . Accessibility ) ;
}
if ( this . ShowModifiers ) {
if ( member . IsStatic ) {
if ( member is LocalFunctionMethod localFunction ) {
if ( localFunction . IsStaticLocalFunction ) {
m | = Modifiers . Static ;
}
} else if ( member . IsStatic ) {
m | = Modifiers . Static ;
} else {
var declaringType = member . DeclaringType ;