From fdf1dac3735217b292ff8b6ecaa8a45a2039f386 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Zgodzi=F1ski?= Date: Mon, 7 Mar 2011 10:18:38 +0100 Subject: [PATCH 1/5] Indexer decompilation support. Conflicts: ICSharpCode.Decompiler/Ast/AstBuilder.cs --- .../CSharp/Ast/TypeMembers/Accessor.cs | 8 ++++++-- .../CSharp/OutputVisitor/OutputVisitor.cs | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs index c487032ebc..cc5651d871 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/Accessor.cs @@ -56,8 +56,12 @@ namespace ICSharpCode.NRefactory.CSharp get { return GetChildByRole (Roles.Body); } set { SetChildByRole (Roles.Body, value); } } - - public override S AcceptVisitor (IAstVisitor visitor, T data) + + public AstNodeCollection Parameters { + get { return GetChildrenByRole(Roles.Parameter); } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) { return visitor.VisitAccessor (this, data); } diff --git a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs index da02c47d5f..5a5d01d098 100644 --- a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs @@ -202,8 +202,21 @@ namespace ICSharpCode.NRefactory.CSharp { WriteCommaSeparatedListInParenthesis(list.SafeCast(), spaceWithin); } + #endif - + + void WriteCommaSeparatedListInBrackets(IEnumerable list, bool spaceWithin) + { + WriteToken("[", AstNode.Roles.LBracket); + if (list.Any()) + { + Space(spaceWithin); + WriteCommaSeparatedList(list.SafeCast()); + Space(spaceWithin); + } + WriteToken("]", AstNode.Roles.RBracket); + } + void WriteCommaSeparatedListInBrackets(IEnumerable list) { WriteToken("[", AstNode.Roles.LBracket); @@ -1815,7 +1828,7 @@ namespace ICSharpCode.NRefactory.CSharp WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType); WriteKeyword("this"); Space(policy.BeforeMethodDeclarationParentheses); - WriteCommaSeparatedListInParenthesis(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses); + WriteCommaSeparatedListInBrackets(indexerDeclaration.Parameters, policy.WithinMethodDeclarationParentheses); OpenBrace(policy.PropertyBraceStyle); // output get/set in their original order foreach (AstNode node in indexerDeclaration.Children) { From 73350e7158c5ab72a215f452384173595692f100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Zgodzi=F1ski?= Date: Mon, 7 Mar 2011 11:00:39 +0100 Subject: [PATCH 2/5] small code reformatting --- ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs index 5a5d01d098..bcab463d7a 100644 --- a/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/OutputVisitor/OutputVisitor.cs @@ -208,8 +208,7 @@ namespace ICSharpCode.NRefactory.CSharp void WriteCommaSeparatedListInBrackets(IEnumerable list, bool spaceWithin) { WriteToken("[", AstNode.Roles.LBracket); - if (list.Any()) - { + if (list.Any()) { Space(spaceWithin); WriteCommaSeparatedList(list.SafeCast()); Space(spaceWithin); From c6a8a1f9d8075d9acac5385bedb2d46ed6cec42e Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 8 Mar 2011 09:06:19 +0100 Subject: [PATCH 3/5] Add support for Modifiers.Any (for pattern-matching) and for AttributeSection patterns. --- .../CSharp/Ast/CSharpModifierToken.cs | 5 +++- .../CSharp/Ast/Modifiers.cs | 5 ++++ .../CSharp/Ast/PatternMatching/Pattern.cs | 5 ++++ .../CSharp/Ast/PatternMatching/Placeholder.cs | 29 +++++++++++++++++++ .../CSharp/Ast/TypeMembers/AttributedNode.cs | 2 +- 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs b/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs index ec0a85705c..3fc7fa2912 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/CSharpModifierToken.cs @@ -72,7 +72,10 @@ namespace ICSharpCode.NRefactory.CSharp new KeyValuePair(Modifiers.Volatile, "volatile".Length), new KeyValuePair(Modifiers.Extern, "extern".Length), new KeyValuePair(Modifiers.Partial, "partial".Length), - new KeyValuePair(Modifiers.Const, "const".Length) + new KeyValuePair(Modifiers.Const, "const".Length), + + // even though it's used for patterns only, it needs to be in this table to be usable in the AST + new KeyValuePair(Modifiers.Any, "any".Length) }; public static IEnumerable AllModifiers { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs b/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs index a05a817aaf..700a3c04d1 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/Modifiers.cs @@ -66,4 +66,9 @@ namespace ICSharpCode.NRefactory.CSharp //Final = 0x400000, //Literal = 0x800000, VisibilityMask = Private | Internal | Protected | Public, + + /// + /// Special value used to match any modifiers during pattern matching. + /// + Any = unchecked((int)0x80000000) }} diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs index 23f5c2ea58..85fd861bb0 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs @@ -64,6 +64,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching return p != null ? new VariablePlaceholder(p) : null; } + public static implicit operator AttributeSection(Pattern p) + { + return p != null ? new AttributeSectionPlaceholder(p) : null; + } + // Make debugging easier by giving Patterns a ToString() implementation public override string ToString() { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs index f68feb443d..67987595f9 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Placeholder.cs @@ -152,4 +152,33 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching return child.DoMatchCollection(role, pos, match, backtrackingStack); } } + + sealed class AttributeSectionPlaceholder : AttributeSection + { + readonly AstNode child; + + public AttributeSectionPlaceholder(AstNode child) + { + this.child = child; + } + + public override NodeType NodeType { + get { return NodeType.Placeholder; } + } + + public override S AcceptVisitor(IAstVisitor visitor, T data) + { + return ((IPatternAstVisitor)visitor).VisitPlaceholder(this, child, data); + } + + protected internal override bool DoMatch(AstNode other, Match match) + { + return child.DoMatch(other, match); + } + + internal override bool DoMatchCollection(Role role, AstNode pos, Match match, Stack backtrackingStack) + { + return child.DoMatchCollection(role, pos, match, backtrackingStack); + } + } } diff --git a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs index 41eec380d1..af5e584dc4 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/TypeMembers/AttributedNode.cs @@ -60,7 +60,7 @@ namespace ICSharpCode.NRefactory.CSharp protected bool MatchAttributesAndModifiers(AttributedNode o, PatternMatching.Match match) { - return this.Modifiers == o.Modifiers && this.Attributes.DoMatch(o.Attributes, match); + return (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers) && this.Attributes.DoMatch(o.Attributes, match); } } } From 60b3164b65f29fd0ab86bd8200159ece274538cd Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 9 Mar 2011 10:03:17 +0100 Subject: [PATCH 4/5] NRefactory AstNode: add DescendantsAndSelf property. --- ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs index 2dab5a5ad9..dafcdc2533 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstNode.cs @@ -157,6 +157,15 @@ namespace ICSharpCode.NRefactory.CSharp } } + /// + /// Gets all descendants of this node (including this node itself). + /// + public IEnumerable DescendantsAndSelf { + get { + return Utils.TreeTraversal.PreOrder(this, n => n.Children); + } + } + /// /// Gets the first child with the specified role. /// Returns the role's null object if the child is not found. From cfccfcaaa16eea7c569ed4cf12603e27b9937067 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 9 Mar 2011 10:58:48 +0100 Subject: [PATCH 5/5] AstNode: add Invoke() methods to AstType (builds InvocationExpression for static methods) --- ICSharpCode.NRefactory/CSharp/Ast/AstType.cs | 24 +++++++++++++++++++ .../CSharp/Ast/PatternMatching/Pattern.cs | 5 ++++ 2 files changed, 29 insertions(+) diff --git a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs index a35204e3cd..5582b9012e 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/AstType.cs @@ -53,6 +53,30 @@ namespace ICSharpCode.NRefactory.CSharp return new TypeReferenceExpression { Type = this }.Member(memberName); } + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); + } + + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, params Expression[] arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments); + } + + /// + /// Builds an invocation expression using this type as target. + /// + public InvocationExpression Invoke(string methodName, IEnumerable typeArguments, IEnumerable arguments) + { + return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments); + } + public static AstType Create(Type type) { switch (Type.GetTypeCode(type)) { diff --git a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs index 85fd861bb0..ed2122d19a 100644 --- a/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs +++ b/ICSharpCode.NRefactory/CSharp/Ast/PatternMatching/Pattern.cs @@ -34,6 +34,11 @@ namespace ICSharpCode.NRefactory.CSharp.PatternMatching return p != null ? new TypePlaceholder(p) : null; } + public AstType ToType() + { + return new TypePlaceholder(this); + } + public static implicit operator Expression(Pattern p) { return p != null ? new ExpressionPlaceholder(p) : null;