diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs index 8a2a77c076..d84f49c224 100644 --- a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs +++ b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_Global.cs @@ -161,6 +161,9 @@ namespace ICSharpCode.NRefactory.CSharp default: throw new InvalidOperationException("unsupported class type : " + typeDeclaration.ClassType); } + + foreach (var constraint in typeDeclaration.Constraints) + constraint.AcceptVisitor (this); FixOpenBrace(braceStyle, typeDeclaration.LBraceToken); @@ -248,5 +251,20 @@ namespace ICSharpCode.NRefactory.CSharp if (comment.StartsLine && !HadErrors && (!policy.KeepCommentsAtFirstColumn || comment.StartLocation.Column > 1)) FixIndentation(comment); } + + public override void VisitConstraint(Constraint constraint) + { + VisitChildrenToFormat (constraint, node => { + if (node is AstType) { + node.AcceptVisitor (this); + } else if (node.Role == Roles.LPar) { + ForceSpacesBefore (node, false); + ForceSpacesAfter (node, false); + } else if (node.Role ==Roles.Comma) { + ForceSpacesBefore (node, false); + ForceSpacesAfter (node, true); + } + }); + } } } \ No newline at end of file diff --git a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs index d3abd82f9e..415450457e 100644 --- a/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs +++ b/ICSharpCode.NRefactory.CSharp/Formatter/FormattingVisitor_TypeMembers.cs @@ -347,6 +347,9 @@ namespace ICSharpCode.NRefactory.CSharp ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses); } + + foreach (var constraint in methodDeclaration.Constraints) + constraint.AcceptVisitor (this); if (!methodDeclaration.Body.IsNull) { FixOpenBrace(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken); diff --git a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs index 5eff5f6c4f..59b829a154 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs @@ -261,9 +261,9 @@ namespace ICSharpCode.NRefactory.CSharp switch (sce.Constraint) { case SpecialConstraint.Class: return new PrimitiveType ("class", Convert (sce.Location)); - case SpecialConstraint.Struct: + case SpecialConstraint.Struct: return new PrimitiveType ("struct", Convert (sce.Location)); - case SpecialConstraint.Constructor: + case SpecialConstraint.Constructor: return new PrimitiveType ("new", Convert (sce.Location)); } } @@ -2651,6 +2651,23 @@ namespace ICSharpCode.NRefactory.CSharp if (c.ConstraintExpressions != null) { foreach (var expr in c.ConstraintExpressions) { constraint.AddChild (ConvertToType (expr), Roles.BaseType); + if (expr is SpecialContraintExpr) { + var sce = (SpecialContraintExpr)expr; + switch (sce.Constraint) { + case SpecialConstraint.Class: + break; + case SpecialConstraint.Struct: + break; + case SpecialConstraint.Constructor: + var bl = LocationsBag.GetLocations (expr); + if (bl != null) { + constraint.AddChild (new CSharpTokenNode (Convert (bl[0]), Roles.LPar), Roles.LPar); + constraint.AddChild (new CSharpTokenNode (Convert (bl[1]), Roles.RPar), Roles.RPar); + } + break; + } + } + if (commaLocs != null && curComma < commaLocs.Count) constraint.AddChild (new CSharpTokenNode (Convert (commaLocs [curComma++]), Roles.Comma), Roles.Comma); } diff --git a/ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs b/ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs index 5ff03ee8ba..1689f20a46 100644 --- a/ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs +++ b/ICSharpCode.NRefactory.Tests/FormattingTests/TestFormattingBugs.cs @@ -350,6 +350,32 @@ foo (); } }"); } + + + /// + /// Bug 12270 - Code formatter breaks new() constraints + /// + [Test] + public void TestBug12270() + { + CSharpFormattingOptions policy = FormattingOptionsFactory.CreateMono(); + + Test(policy, +@"class C +{ + public void Test () where T : new () + { + } +}", +@"class C +{ + public void Test () where T : new() + { + } +}"); + } + + } }