diff --git a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs index 6cb24d828..8c5b92e00 100644 --- a/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs +++ b/ICSharpCode.Decompiler/CSharp/OutputVisitor/CSharpOutputVisitor.cs @@ -489,12 +489,15 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor } } - protected virtual void WriteModifiers(IEnumerable modifierTokens) + protected virtual void WriteModifiers(Modifiers modifiers) { - foreach (CSharpModifierToken modifier in modifierTokens) + foreach (Modifiers modifier in CSharpModifierToken.AllModifiers) { - modifier.AcceptVisitor(this); - Space(); + if ((modifiers & modifier) == modifier) + { + WriteKeyword(CSharpModifierToken.GetModifierName(modifier), EntityDeclaration.ModifierRole); + Space(); + } } } @@ -1556,7 +1559,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(delegateDeclaration); WriteAttributes(delegateDeclaration.Attributes); - WriteModifiers(delegateDeclaration.ModifierTokens); + WriteModifiers(delegateDeclaration.Modifiers); WriteKeyword(Roles.DelegateKeyword); delegateDeclaration.ReturnType.AcceptVisitor(this); Space(); @@ -1604,7 +1607,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(typeDeclaration); WriteAttributes(typeDeclaration.Attributes); - WriteModifiers(typeDeclaration.ModifierTokens); + WriteModifiers(typeDeclaration.Modifiers); BraceStyle braceStyle; switch (typeDeclaration.ClassType) { @@ -2250,7 +2253,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor public virtual void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement) { StartNode(variableDeclarationStatement); - WriteModifiers(variableDeclarationStatement.GetChildrenByRole(VariableDeclarationStatement.ModifierRole)); + WriteModifiers(variableDeclarationStatement.Modifiers); variableDeclarationStatement.Type.AcceptVisitor(this); Space(); WriteCommaSeparatedList(variableDeclarationStatement.Variables); @@ -2306,7 +2309,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(accessor); WriteAttributes(accessor.Attributes); - WriteModifiers(accessor.ModifierTokens); + WriteModifiers(accessor.Modifiers); BraceStyle style = policy.StatementBraceStyle; if (accessor.Role == PropertyDeclaration.GetterRole) { @@ -2343,7 +2346,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(constructorDeclaration); WriteAttributes(constructorDeclaration.Attributes); - WriteModifiers(constructorDeclaration.ModifierTokens); + WriteModifiers(constructorDeclaration.Modifiers); TypeDeclaration type = constructorDeclaration.Parent as TypeDeclaration; if (type != null && type.Name != constructorDeclaration.Name) WriteIdentifier((Identifier)type.NameToken.Clone()); @@ -2384,8 +2387,8 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(destructorDeclaration); WriteAttributes(destructorDeclaration.Attributes); - WriteModifiers(destructorDeclaration.ModifierTokens); - if (destructorDeclaration.ModifierTokens.Any()) + WriteModifiers(destructorDeclaration.Modifiers); + if (destructorDeclaration.Modifiers != Modifiers.None) { Space(); } @@ -2406,7 +2409,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(enumMemberDeclaration); WriteAttributes(enumMemberDeclaration.Attributes); - WriteModifiers(enumMemberDeclaration.ModifierTokens); + WriteModifiers(enumMemberDeclaration.Modifiers); WriteIdentifier(enumMemberDeclaration.NameToken); if (!enumMemberDeclaration.Initializer.IsNull) { @@ -2422,7 +2425,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(extensionDeclaration); WriteAttributes(extensionDeclaration.Attributes); - WriteModifiers(extensionDeclaration.ModifierTokens); + WriteModifiers(extensionDeclaration.Modifiers); WriteKeyword(ExtensionDeclaration.ExtensionKeywordRole); WriteTypeParameters(extensionDeclaration.TypeParameters); Space(policy.SpaceBeforeMethodDeclarationParentheses); @@ -2452,7 +2455,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(eventDeclaration); WriteAttributes(eventDeclaration.Attributes); - WriteModifiers(eventDeclaration.ModifierTokens); + WriteModifiers(eventDeclaration.Modifiers); WriteKeyword(EventDeclaration.EventKeywordRole); eventDeclaration.ReturnType.AcceptVisitor(this); Space(); @@ -2465,7 +2468,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(customEventDeclaration); WriteAttributes(customEventDeclaration.Attributes); - WriteModifiers(customEventDeclaration.ModifierTokens); + WriteModifiers(customEventDeclaration.Modifiers); WriteKeyword(CustomEventDeclaration.EventKeywordRole); customEventDeclaration.ReturnType.AcceptVisitor(this); Space(); @@ -2489,7 +2492,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(fieldDeclaration); WriteAttributes(fieldDeclaration.Attributes); - WriteModifiers(fieldDeclaration.ModifierTokens); + WriteModifiers(fieldDeclaration.Modifiers); fieldDeclaration.ReturnType.AcceptVisitor(this); Space(); WriteCommaSeparatedList(fieldDeclaration.Variables); @@ -2501,7 +2504,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(fixedFieldDeclaration); WriteAttributes(fixedFieldDeclaration.Attributes); - WriteModifiers(fixedFieldDeclaration.ModifierTokens); + WriteModifiers(fixedFieldDeclaration.Modifiers); WriteKeyword(FixedFieldDeclaration.FixedKeywordRole); Space(); fixedFieldDeclaration.ReturnType.AcceptVisitor(this); @@ -2530,7 +2533,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(indexerDeclaration); WriteAttributes(indexerDeclaration.Attributes); - WriteModifiers(indexerDeclaration.ModifierTokens); + WriteModifiers(indexerDeclaration.Modifiers); indexerDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType); @@ -2575,7 +2578,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(methodDeclaration); WriteAttributes(methodDeclaration.Attributes); - WriteModifiers(methodDeclaration.ModifierTokens); + WriteModifiers(methodDeclaration.Modifiers); methodDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(methodDeclaration.PrivateImplementationType); @@ -2595,7 +2598,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(operatorDeclaration); WriteAttributes(operatorDeclaration.Attributes); - WriteModifiers(operatorDeclaration.ModifierTokens); + WriteModifiers(operatorDeclaration.Modifiers); if (operatorDeclaration.OperatorType == OperatorType.Explicit || operatorDeclaration.OperatorType == OperatorType.CheckedExplicit) { WriteKeyword(OperatorDeclaration.ExplicitRole); @@ -2695,7 +2698,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(propertyDeclaration); WriteAttributes(propertyDeclaration.Attributes); - WriteModifiers(propertyDeclaration.ModifierTokens); + WriteModifiers(propertyDeclaration.Modifiers); propertyDeclaration.ReturnType.AcceptVisitor(this); Space(); WritePrivateImplementationType(propertyDeclaration.PrivateImplementationType); @@ -2901,7 +2904,7 @@ namespace ICSharpCode.Decompiler.CSharp.OutputVisitor { StartNode(arraySpecifier); WriteToken(Roles.LBracket); - foreach (var comma in arraySpecifier.GetChildrenByRole(Roles.Comma)) + for (int i = 0; i < arraySpecifier.Dimensions - 1; i++) { writer.WriteToken(Roles.Comma, ","); } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs index 823063143..c12c431be 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/ComposedType.cs @@ -50,40 +50,19 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax /// This is used for C# 7 ref locals/ref return. /// Parameters use ParameterDeclaration.ParameterModifier instead. /// - public bool HasRefSpecifier { - get { - return !GetChildByRole(RefRole).IsNull; - } - set { - SetChildByRole(RefRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); - } - } + public bool HasRefSpecifier { get; set; } /// /// Gets/sets whether this type has a 'readonly' specifier. /// This is used for C# 7.2 'ref readonly' locals/ref return. /// Parameters use ParameterDeclaration.ParameterModifier instead. /// - public bool HasReadOnlySpecifier { - get { - return !GetChildByRole(ReadonlyRole).IsNull; - } - set { - SetChildByRole(ReadonlyRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); - } - } + public bool HasReadOnlySpecifier { get; set; } [Slot("Roles.Type")] public partial AstType BaseType { get; set; } - public bool HasNullableSpecifier { - get { - return !GetChildByRole(NullableRole).IsNull; - } - set { - SetChildByRole(NullableRole, value ? new CSharpTokenNode(TextLocation.Empty, null) : null); - } - } + public bool HasNullableSpecifier { get; set; } public bool HasOnlyNullableSpecifier { get { @@ -91,39 +70,22 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax } } - public CSharpTokenNode NullableSpecifierToken { - get { - return GetChildByRole(NullableRole); - } - } + int pointerRank; public int PointerRank { get { - return GetChildrenByRole(PointerRole).Count; + return pointerRank; } set { if (value < 0) - throw new ArgumentOutOfRangeException(); - int d = this.PointerRank; - while (d > value) - { - GetChildByRole(PointerRole).Remove(); - d--; - } - while (d < value) - { - InsertChildBefore(GetChildByRole(PointerRole), new CSharpTokenNode(TextLocation.Empty, PointerRole), PointerRole); - d++; - } + throw new ArgumentOutOfRangeException(nameof(value)); + pointerRank = value; } } [Slot("ArraySpecifierRole")] public partial AstNodeCollection ArraySpecifiers { get; } - [Slot("PointerRole")] - public partial AstNodeCollection PointerTokens { get; } - protected internal override bool DoMatch(AstNode other, PatternMatching.Match match) { ComposedType o = other as ComposedType; @@ -207,22 +169,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax get { return GetChildByRole(Roles.LBracket); } } - public int Dimensions { - get { return 1 + GetChildrenByRole(Roles.Comma).Count; } - set { - int d = this.Dimensions; - while (d > value) - { - GetChildByRole(Roles.Comma).Remove(); - d--; - } - while (d < value) - { - InsertChildBefore(GetChildByRole(Roles.Comma), new CSharpTokenNode(TextLocation.Empty, Roles.Comma), Roles.Comma); - d++; - } - } - } + public int Dimensions { get; set; } = 1; public CSharpTokenNode RBracketToken { get { return GetChildByRole(Roles.RBracket); } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/VariableDeclarationStatement.cs b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/VariableDeclarationStatement.cs index f620661ff..a82fb3e01 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/Statements/VariableDeclarationStatement.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/Statements/VariableDeclarationStatement.cs @@ -41,10 +41,7 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax this.Variables.Add(new VariableInitializer(name, initializer)); } - public Modifiers Modifiers { - get { return EntityDeclaration.GetModifiers(this); } - set { EntityDeclaration.SetModifiers(this, value); } - } + public Modifiers Modifiers { get; set; } [Slot("Roles.Type")] public partial AstType Type { get; set; } diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs index 19ab4cc7b..451dae646 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/TypeMembers/EntityDeclaration.cs @@ -39,20 +39,13 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax get { return base.GetChildrenByRole(AttributeRole); } } - public Modifiers Modifiers { - get { return GetModifiers(this); } - set { SetModifiers(this, value); } - } + public Modifiers Modifiers { get; set; } public bool HasModifier(Modifiers mod) { return (Modifiers & mod) == mod; } - public IEnumerable ModifierTokens { - get { return GetChildrenByRole(ModifierRole); } - } - public virtual string Name { get { return GetChildByRole(Roles.Identifier).Name; @@ -76,48 +69,6 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax get { return GetChildByRole(Roles.Semicolon); } } - internal static Modifiers GetModifiers(AstNode node) - { - Modifiers m = 0; - foreach (CSharpModifierToken t in node.GetChildrenByRole(ModifierRole)) - { - m |= t.Modifier; - } - return m; - } - - internal static void SetModifiers(AstNode node, Modifiers newValue) - { - Modifiers oldValue = GetModifiers(node); - AstNode insertionPos = node.GetChildrenByRole(AttributeRole).LastOrDefault(); - foreach (Modifiers m in CSharpModifierToken.AllModifiers) - { - if ((m & newValue) != 0) - { - if ((m & oldValue) == 0) - { - // Modifier was added - var newToken = new CSharpModifierToken(TextLocation.Empty, m); - node.InsertChildAfter(insertionPos, newToken, ModifierRole); - insertionPos = newToken; - } - else - { - // Modifier already exists - insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m); - } - } - else - { - if ((m & oldValue) != 0) - { - // Modifier was removed - node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m).Remove(); - } - } - } - } - protected bool MatchAttributesAndModifiers(EntityDeclaration o, PatternMatching.Match match) { return (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers) && this.Attributes.DoMatch(o.Attributes, match);