1 | // |
---|
2 | // AstFormattingVisitor_Expressions.cs |
---|
3 | // |
---|
4 | // Author: |
---|
5 | // Mike KrÃŒger <mkrueger@xamarin.com> |
---|
6 | // |
---|
7 | // Copyright (c) 2013 Xamarin Inc. (http://xamarin.com) |
---|
8 | // |
---|
9 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
---|
10 | // of this software and associated documentation files (the "Software"), to deal |
---|
11 | // in the Software without restriction, including without limitation the rights |
---|
12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
---|
13 | // copies of the Software, and to permit persons to whom the Software is |
---|
14 | // furnished to do so, subject to the following conditions: |
---|
15 | // |
---|
16 | // The above copyright notice and this permission notice shall be included in |
---|
17 | // all copies or substantial portions of the Software. |
---|
18 | // |
---|
19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
---|
22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
---|
23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
---|
24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
---|
25 | // THE SOFTWARE. |
---|
26 | using System; |
---|
27 | using System.Linq; |
---|
28 | using System.Collections.Generic; |
---|
29 | |
---|
30 | namespace ICSharpCode.NRefactory.CSharp |
---|
31 | { |
---|
32 | partial class FormattingVisitor : DepthFirstAstVisitor |
---|
33 | { |
---|
34 | public override void VisitComposedType(ComposedType composedType) |
---|
35 | { |
---|
36 | var spec = composedType.ArraySpecifiers.FirstOrDefault(); |
---|
37 | if (spec != null) |
---|
38 | ForceSpacesBefore(spec.LBracketToken, policy.SpaceBeforeArrayDeclarationBrackets); |
---|
39 | |
---|
40 | if (composedType.HasNullableSpecifier) |
---|
41 | ForceSpacesBefore(composedType.NullableSpecifierToken, false); |
---|
42 | |
---|
43 | if (composedType.PointerRank > 0) |
---|
44 | foreach (var token in composedType.PointerTokens) |
---|
45 | ForceSpacesBefore(token, false); |
---|
46 | |
---|
47 | base.VisitComposedType(composedType); |
---|
48 | } |
---|
49 | |
---|
50 | public override void VisitAnonymousMethodExpression(AnonymousMethodExpression lambdaExpression) |
---|
51 | { |
---|
52 | FormatArguments(lambdaExpression); |
---|
53 | |
---|
54 | if (!lambdaExpression.Body.IsNull) { |
---|
55 | var old = curIndent; |
---|
56 | this.curIndent = curIndent.GetIndentWithoutSpace (); |
---|
57 | FixOpenBrace(policy.AnonymousMethodBraceStyle, lambdaExpression.Body.LBraceToken); |
---|
58 | VisitBlockWithoutFixingBraces(lambdaExpression.Body, policy.IndentBlocks); |
---|
59 | FixClosingBrace(policy.AnonymousMethodBraceStyle, lambdaExpression.Body.RBraceToken); |
---|
60 | curIndent = old; |
---|
61 | } |
---|
62 | |
---|
63 | } |
---|
64 | |
---|
65 | public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression) |
---|
66 | { |
---|
67 | ForceSpacesAround(assignmentExpression.OperatorToken, policy.SpaceAroundAssignment); |
---|
68 | base.VisitAssignmentExpression(assignmentExpression); |
---|
69 | } |
---|
70 | |
---|
71 | public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression) |
---|
72 | { |
---|
73 | bool forceSpaces = false; |
---|
74 | switch (binaryOperatorExpression.Operator) { |
---|
75 | case BinaryOperatorType.Equality: |
---|
76 | case BinaryOperatorType.InEquality: |
---|
77 | forceSpaces = policy.SpaceAroundEqualityOperator; |
---|
78 | break; |
---|
79 | case BinaryOperatorType.GreaterThan: |
---|
80 | case BinaryOperatorType.GreaterThanOrEqual: |
---|
81 | case BinaryOperatorType.LessThan: |
---|
82 | case BinaryOperatorType.LessThanOrEqual: |
---|
83 | forceSpaces = policy.SpaceAroundRelationalOperator; |
---|
84 | break; |
---|
85 | case BinaryOperatorType.ConditionalAnd: |
---|
86 | case BinaryOperatorType.ConditionalOr: |
---|
87 | forceSpaces = policy.SpaceAroundLogicalOperator; |
---|
88 | break; |
---|
89 | case BinaryOperatorType.BitwiseAnd: |
---|
90 | case BinaryOperatorType.BitwiseOr: |
---|
91 | case BinaryOperatorType.ExclusiveOr: |
---|
92 | forceSpaces = policy.SpaceAroundBitwiseOperator; |
---|
93 | break; |
---|
94 | case BinaryOperatorType.Add: |
---|
95 | case BinaryOperatorType.Subtract: |
---|
96 | forceSpaces = policy.SpaceAroundAdditiveOperator; |
---|
97 | break; |
---|
98 | case BinaryOperatorType.Multiply: |
---|
99 | case BinaryOperatorType.Divide: |
---|
100 | case BinaryOperatorType.Modulus: |
---|
101 | forceSpaces = policy.SpaceAroundMultiplicativeOperator; |
---|
102 | break; |
---|
103 | case BinaryOperatorType.ShiftLeft: |
---|
104 | case BinaryOperatorType.ShiftRight: |
---|
105 | forceSpaces = policy.SpaceAroundShiftOperator; |
---|
106 | break; |
---|
107 | case BinaryOperatorType.NullCoalescing: |
---|
108 | forceSpaces = policy.SpaceAroundNullCoalescingOperator; |
---|
109 | break; |
---|
110 | } |
---|
111 | var opToken = binaryOperatorExpression.OperatorToken; |
---|
112 | if (opToken.PrevSibling != null && opToken.PrevSibling.Role != Roles.NewLine) { |
---|
113 | ForceSpacesBefore(opToken, forceSpaces); |
---|
114 | } else { |
---|
115 | ForceSpacesAfter(binaryOperatorExpression.Left, false); |
---|
116 | FixIndentation(opToken); |
---|
117 | } |
---|
118 | ForceSpacesAfter(opToken, opToken.NextSibling != null && opToken.NextSibling.Role != Roles.NewLine && forceSpaces); |
---|
119 | |
---|
120 | binaryOperatorExpression.Left.AcceptVisitor(this); |
---|
121 | // Handle line breaks in binary opeartor expression. |
---|
122 | if (binaryOperatorExpression.Left.EndLocation.Line != binaryOperatorExpression.Right.StartLocation.Line) { |
---|
123 | if (opToken.StartLocation.Line == binaryOperatorExpression.Right.StartLocation.Line) { |
---|
124 | FixStatementIndentation(opToken.StartLocation); |
---|
125 | } else { |
---|
126 | FixStatementIndentation(binaryOperatorExpression.Right.StartLocation); |
---|
127 | } |
---|
128 | } |
---|
129 | binaryOperatorExpression.Right.AcceptVisitor(this); |
---|
130 | } |
---|
131 | |
---|
132 | public override void VisitConditionalExpression(ConditionalExpression conditionalExpression) |
---|
133 | { |
---|
134 | ForceSpacesBefore(conditionalExpression.QuestionMarkToken, policy.SpaceBeforeConditionalOperatorCondition); |
---|
135 | ForceSpacesAfter(conditionalExpression.QuestionMarkToken, policy.SpaceAfterConditionalOperatorCondition); |
---|
136 | ForceSpacesBefore(conditionalExpression.ColonToken, policy.SpaceBeforeConditionalOperatorSeparator); |
---|
137 | ForceSpacesAfter(conditionalExpression.ColonToken, policy.SpaceAfterConditionalOperatorSeparator); |
---|
138 | base.VisitConditionalExpression(conditionalExpression); |
---|
139 | } |
---|
140 | |
---|
141 | public override void VisitCastExpression(CastExpression castExpression) |
---|
142 | { |
---|
143 | if (castExpression.RParToken != null) { |
---|
144 | ForceSpacesAfter(castExpression.LParToken, policy.SpacesWithinCastParentheses); |
---|
145 | ForceSpacesBefore(castExpression.RParToken, policy.SpacesWithinCastParentheses); |
---|
146 | |
---|
147 | ForceSpacesAfter(castExpression.RParToken, policy.SpaceAfterTypecast); |
---|
148 | } |
---|
149 | base.VisitCastExpression(castExpression); |
---|
150 | } |
---|
151 | |
---|
152 | void ForceSpacesAround(AstNode node, bool forceSpaces) |
---|
153 | { |
---|
154 | if (node.IsNull) |
---|
155 | return; |
---|
156 | ForceSpacesBefore(node, forceSpaces); |
---|
157 | ForceSpacesAfter(node, forceSpaces); |
---|
158 | } |
---|
159 | |
---|
160 | void FormatCommas(AstNode parent, bool before, bool after) |
---|
161 | { |
---|
162 | if (parent.IsNull) { |
---|
163 | return; |
---|
164 | } |
---|
165 | foreach (CSharpTokenNode comma in parent.Children.Where (node => node.Role == Roles.Comma)) { |
---|
166 | ForceSpacesAfter(comma, after); |
---|
167 | ForceSpacesBefore(comma, before); |
---|
168 | } |
---|
169 | } |
---|
170 | |
---|
171 | bool DoWrap(Wrapping wrapping, AstNode wrapNode, int argumentCount) |
---|
172 | { |
---|
173 | return wrapping == Wrapping.WrapAlways || |
---|
174 | options.WrapLineLength > 0 && argumentCount > 1 && wrapping == Wrapping.WrapIfTooLong && wrapNode.StartLocation.Column >= options.WrapLineLength; |
---|
175 | } |
---|
176 | |
---|
177 | void FormatArguments(AstNode node) |
---|
178 | { |
---|
179 | Wrapping methodCallArgumentWrapping; |
---|
180 | NewLinePlacement newLineAferMethodCallOpenParentheses; |
---|
181 | bool doAlignToFirstArgument; |
---|
182 | NewLinePlacement methodClosingParenthesesOnNewLine; |
---|
183 | bool spaceWithinMethodCallParentheses; |
---|
184 | bool spaceWithinEmptyParentheses; |
---|
185 | bool spaceAfterMethodCallParameterComma; |
---|
186 | bool spaceBeforeMethodCallParameterComma; |
---|
187 | |
---|
188 | CSharpTokenNode rParToken, lParToken; |
---|
189 | List<AstNode> arguments; |
---|
190 | |
---|
191 | var constructorDeclaration = node as ConstructorDeclaration; |
---|
192 | if (constructorDeclaration != null) { |
---|
193 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
194 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
195 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
196 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
197 | spaceWithinMethodCallParentheses = policy.SpaceWithinConstructorDeclarationParentheses; |
---|
198 | spaceAfterMethodCallParameterComma = policy.SpaceAfterConstructorDeclarationParameterComma; |
---|
199 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeConstructorDeclarationParameterComma; |
---|
200 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
201 | lParToken = constructorDeclaration.LParToken; |
---|
202 | rParToken = constructorDeclaration.RParToken; |
---|
203 | arguments = constructorDeclaration.Parameters.Cast<AstNode>().ToList(); |
---|
204 | } else if (node is IndexerDeclaration) { |
---|
205 | var indexer = (IndexerDeclaration)node; |
---|
206 | methodCallArgumentWrapping = policy.IndexerDeclarationParameterWrapping; |
---|
207 | newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerDeclarationOpenBracket; |
---|
208 | methodClosingParenthesesOnNewLine = policy.IndexerDeclarationClosingBracketOnNewLine; |
---|
209 | doAlignToFirstArgument = policy.AlignToFirstIndexerDeclarationParameter; |
---|
210 | spaceWithinMethodCallParentheses = policy.SpaceWithinIndexerDeclarationBracket; |
---|
211 | spaceAfterMethodCallParameterComma = policy.SpaceAfterIndexerDeclarationParameterComma; |
---|
212 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeIndexerDeclarationParameterComma; |
---|
213 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
214 | lParToken = indexer.LBracketToken; |
---|
215 | rParToken = indexer.RBracketToken; |
---|
216 | arguments = indexer.Parameters.Cast<AstNode>().ToList(); |
---|
217 | } else if (node is OperatorDeclaration) { |
---|
218 | var op = (OperatorDeclaration)node; |
---|
219 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
220 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
221 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
222 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
223 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; |
---|
224 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; |
---|
225 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; |
---|
226 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
227 | lParToken = op.LParToken; |
---|
228 | rParToken = op.RParToken; |
---|
229 | arguments = op.Parameters.Cast<AstNode>().ToList(); |
---|
230 | } else if (node is MethodDeclaration) { |
---|
231 | var methodDeclaration = node as MethodDeclaration; |
---|
232 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
233 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
234 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
235 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
236 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; |
---|
237 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; |
---|
238 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; |
---|
239 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
240 | lParToken = methodDeclaration.LParToken; |
---|
241 | rParToken = methodDeclaration.RParToken; |
---|
242 | arguments = methodDeclaration.Parameters.Cast<AstNode>().ToList(); |
---|
243 | } else if (node is IndexerExpression) { |
---|
244 | var indexer = (IndexerExpression)node; |
---|
245 | methodCallArgumentWrapping = policy.IndexerArgumentWrapping; |
---|
246 | newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerOpenBracket; |
---|
247 | doAlignToFirstArgument = policy.AlignToFirstIndexerArgument; |
---|
248 | methodClosingParenthesesOnNewLine = policy.IndexerClosingBracketOnNewLine; |
---|
249 | spaceWithinMethodCallParentheses = policy.SpacesWithinBrackets; |
---|
250 | spaceAfterMethodCallParameterComma = policy.SpaceAfterBracketComma; |
---|
251 | spaceWithinEmptyParentheses = spaceWithinMethodCallParentheses; |
---|
252 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeBracketComma; |
---|
253 | rParToken = indexer.RBracketToken; |
---|
254 | lParToken = indexer.LBracketToken; |
---|
255 | arguments = indexer.Arguments.Cast<AstNode>().ToList(); |
---|
256 | } else if (node is ObjectCreateExpression) { |
---|
257 | var oce = node as ObjectCreateExpression; |
---|
258 | methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; |
---|
259 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; |
---|
260 | doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; |
---|
261 | methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; |
---|
262 | spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses; |
---|
263 | spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma; |
---|
264 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma; |
---|
265 | spaceWithinEmptyParentheses = policy.SpacesBetweenEmptyNewParentheses; |
---|
266 | |
---|
267 | rParToken = oce.RParToken; |
---|
268 | lParToken = oce.LParToken; |
---|
269 | arguments = oce.Arguments.Cast<AstNode>().ToList(); |
---|
270 | } else if (node is Attribute) { |
---|
271 | var oce = node as Attribute; |
---|
272 | methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; |
---|
273 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; |
---|
274 | doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; |
---|
275 | methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; |
---|
276 | spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses; |
---|
277 | spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma; |
---|
278 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma; |
---|
279 | spaceWithinEmptyParentheses = policy.SpacesBetweenEmptyNewParentheses; |
---|
280 | |
---|
281 | rParToken = oce.RParToken; |
---|
282 | lParToken = oce.LParToken; |
---|
283 | arguments = oce.Arguments.Cast<AstNode>().ToList(); |
---|
284 | } else if (node is LambdaExpression) { |
---|
285 | var methodDeclaration = node as LambdaExpression; |
---|
286 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
287 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
288 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
289 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
290 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; |
---|
291 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; |
---|
292 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; |
---|
293 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
294 | lParToken = methodDeclaration.LParToken; |
---|
295 | rParToken = methodDeclaration.RParToken; |
---|
296 | arguments = methodDeclaration.Parameters.Cast<AstNode>().ToList(); |
---|
297 | } else if (node is AnonymousMethodExpression) { |
---|
298 | var methodDeclaration = node as AnonymousMethodExpression; |
---|
299 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
300 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
301 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
302 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
303 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; |
---|
304 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; |
---|
305 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; |
---|
306 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
307 | lParToken = methodDeclaration.LParToken; |
---|
308 | rParToken = methodDeclaration.RParToken; |
---|
309 | arguments = methodDeclaration.Parameters.Cast<AstNode>().ToList(); |
---|
310 | } else if (node is ConstructorInitializer) { |
---|
311 | var constructorInitializer = node as ConstructorInitializer; |
---|
312 | methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping; |
---|
313 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses; |
---|
314 | methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine; |
---|
315 | doAlignToFirstArgument = policy.AlignToFirstMethodDeclarationParameter; |
---|
316 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses; |
---|
317 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma; |
---|
318 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma; |
---|
319 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodDeclarationParentheses; |
---|
320 | lParToken = constructorInitializer.LParToken; |
---|
321 | rParToken = constructorInitializer.RParToken; |
---|
322 | arguments = constructorInitializer.Arguments.Cast<AstNode>().ToList(); |
---|
323 | } else { |
---|
324 | InvocationExpression invocationExpression = node as InvocationExpression; |
---|
325 | methodCallArgumentWrapping = policy.MethodCallArgumentWrapping; |
---|
326 | newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses; |
---|
327 | methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine; |
---|
328 | doAlignToFirstArgument = policy.AlignToFirstMethodCallArgument; |
---|
329 | spaceWithinMethodCallParentheses = policy.SpaceWithinMethodCallParentheses; |
---|
330 | spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodCallParameterComma; |
---|
331 | spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodCallParameterComma; |
---|
332 | spaceWithinEmptyParentheses = policy.SpaceBetweenEmptyMethodCallParentheses; |
---|
333 | |
---|
334 | rParToken = invocationExpression.RParToken; |
---|
335 | lParToken = invocationExpression.LParToken; |
---|
336 | arguments = invocationExpression.Arguments.Cast<AstNode>().ToList(); |
---|
337 | } |
---|
338 | |
---|
339 | if (formatter.FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly) |
---|
340 | methodCallArgumentWrapping = Wrapping.DoNotChange; |
---|
341 | int argumentStart = 1; |
---|
342 | var firstarg = arguments.FirstOrDefault(); |
---|
343 | if (firstarg != null && firstarg.GetPrevNode().Role == Roles.NewLine) { |
---|
344 | doAlignToFirstArgument = false; |
---|
345 | argumentStart = 0; |
---|
346 | } |
---|
347 | bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, arguments.Count); |
---|
348 | if (wrapMethodCall && arguments.Any()) { |
---|
349 | if (ShouldBreakLine(newLineAferMethodCallOpenParentheses, lParToken)) { |
---|
350 | curIndent.Push(IndentType.Continuation); |
---|
351 | foreach (var arg in arguments) { |
---|
352 | FixStatementIndentation(arg.StartLocation); |
---|
353 | arg.AcceptVisitor(this); |
---|
354 | } |
---|
355 | curIndent.Pop(); |
---|
356 | } else { |
---|
357 | if (!doAlignToFirstArgument) { |
---|
358 | curIndent.Push(IndentType.Continuation); |
---|
359 | foreach (var arg in arguments.Take (argumentStart)) { |
---|
360 | FixStatementIndentation(arg.StartLocation); |
---|
361 | arg.AcceptVisitor(this); |
---|
362 | } |
---|
363 | foreach (var arg in arguments.Skip (argumentStart)) { |
---|
364 | FixStatementIndentation(arg.StartLocation); |
---|
365 | arg.AcceptVisitor(this); |
---|
366 | } |
---|
367 | curIndent.Pop(); |
---|
368 | } else { |
---|
369 | int extraSpaces = Math.Max(0, arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length); |
---|
370 | curIndent.ExtraSpaces += extraSpaces; |
---|
371 | foreach (var arg in arguments.Take (argumentStart)) { |
---|
372 | arg.AcceptVisitor(this); |
---|
373 | } |
---|
374 | foreach (var arg in arguments.Skip(argumentStart)) { |
---|
375 | FixStatementIndentation(arg.StartLocation); |
---|
376 | arg.AcceptVisitor(this); |
---|
377 | } |
---|
378 | curIndent.ExtraSpaces -= extraSpaces; |
---|
379 | } |
---|
380 | } |
---|
381 | |
---|
382 | if (!rParToken.IsNull) { |
---|
383 | if (ShouldBreakLine(methodClosingParenthesesOnNewLine, rParToken)) { |
---|
384 | FixStatementIndentation(rParToken.StartLocation); |
---|
385 | } else if (methodClosingParenthesesOnNewLine == NewLinePlacement.SameLine) { |
---|
386 | ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses); |
---|
387 | } |
---|
388 | } |
---|
389 | } else { |
---|
390 | |
---|
391 | foreach (var arg in arguments.Take (argumentStart)) { |
---|
392 | if (policy.IndentBlocksInsideExpressions) |
---|
393 | curIndent.Push(IndentType.Continuation); |
---|
394 | arg.AcceptVisitor(this); |
---|
395 | if (policy.IndentBlocksInsideExpressions) |
---|
396 | curIndent.Pop(); |
---|
397 | } |
---|
398 | foreach (var arg in arguments.Skip(argumentStart)) { |
---|
399 | if (arg.GetPrevSibling(NoWhitespacePredicate) != null) { |
---|
400 | if (methodCallArgumentWrapping == Wrapping.DoNotWrap) { |
---|
401 | ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.GetPrevSibling(NoWhitespacePredicate).Role == Roles.Comma); |
---|
402 | if (policy.IndentBlocksInsideExpressions) |
---|
403 | curIndent.Push(IndentType.Continuation); |
---|
404 | arg.AcceptVisitor(this); |
---|
405 | if (policy.IndentBlocksInsideExpressions) |
---|
406 | curIndent.Pop(); |
---|
407 | } else { |
---|
408 | if (!doAlignToFirstArgument && arg.PrevSibling.Role == Roles.NewLine) { |
---|
409 | curIndent.Push(IndentType.Continuation); |
---|
410 | FixStatementIndentation(arg.StartLocation); |
---|
411 | arg.AcceptVisitor(this); |
---|
412 | curIndent.Pop(); |
---|
413 | } else { |
---|
414 | if (arg.PrevSibling.StartLocation.Line == arg.StartLocation.Line) { |
---|
415 | ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.GetPrevSibling(NoWhitespacePredicate).Role == Roles.Comma); |
---|
416 | if (policy.IndentBlocksInsideExpressions) |
---|
417 | curIndent.Push(IndentType.Continuation); |
---|
418 | arg.AcceptVisitor(this); |
---|
419 | if (policy.IndentBlocksInsideExpressions) |
---|
420 | curIndent.Pop(); |
---|
421 | } else { |
---|
422 | int extraSpaces = Math.Max(0, arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length); |
---|
423 | curIndent.ExtraSpaces += extraSpaces; |
---|
424 | FixStatementIndentation(arg.StartLocation); |
---|
425 | arg.AcceptVisitor(this); |
---|
426 | curIndent.ExtraSpaces -= extraSpaces; |
---|
427 | } |
---|
428 | } |
---|
429 | } |
---|
430 | } else { |
---|
431 | arg.AcceptVisitor(this); |
---|
432 | } |
---|
433 | } |
---|
434 | if (!rParToken.IsNull) { |
---|
435 | if (methodCallArgumentWrapping == Wrapping.DoNotWrap) { |
---|
436 | ForceSpacesBeforeRemoveNewLines(rParToken, arguments.Any() ? spaceWithinMethodCallParentheses : spaceWithinEmptyParentheses); |
---|
437 | } else { |
---|
438 | bool sameLine = rParToken.GetPrevNode(n => n.Role == Roles.Argument || n.Role == Roles.Parameter || n.Role == Roles.LPar || n.Role == Roles.Comma).EndLocation.Line == rParToken.StartLocation.Line; |
---|
439 | if (sameLine) { |
---|
440 | ForceSpacesBeforeRemoveNewLines(rParToken, arguments.Any() ? spaceWithinMethodCallParentheses : spaceWithinEmptyParentheses); |
---|
441 | } else { |
---|
442 | FixStatementIndentation(rParToken.StartLocation); |
---|
443 | } |
---|
444 | } |
---|
445 | } |
---|
446 | } |
---|
447 | if (!rParToken.IsNull) { |
---|
448 | foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) { |
---|
449 | ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma); |
---|
450 | } |
---|
451 | } |
---|
452 | } |
---|
453 | |
---|
454 | public override void VisitInvocationExpression(InvocationExpression invocationExpression) |
---|
455 | { |
---|
456 | if (!invocationExpression.Target.IsNull) |
---|
457 | invocationExpression.Target.AcceptVisitor(this); |
---|
458 | |
---|
459 | ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses); |
---|
460 | if (invocationExpression.Arguments.Any()) { |
---|
461 | ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses); |
---|
462 | } else { |
---|
463 | ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses); |
---|
464 | ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses); |
---|
465 | } |
---|
466 | bool popIndent = false; |
---|
467 | if (invocationExpression.Target is MemberReferenceExpression) { |
---|
468 | var mt = (MemberReferenceExpression)invocationExpression.Target; |
---|
469 | if (mt.Target is InvocationExpression) { |
---|
470 | if (DoWrap(policy.ChainedMethodCallWrapping, mt.DotToken, 2)) { |
---|
471 | curIndent.Push(IndentType.Block); |
---|
472 | popIndent = true; |
---|
473 | FixStatementIndentation(mt.DotToken.StartLocation); |
---|
474 | } else { |
---|
475 | if (policy.ChainedMethodCallWrapping == Wrapping.DoNotWrap) |
---|
476 | ForceSpacesBeforeRemoveNewLines(mt.DotToken, false); |
---|
477 | } |
---|
478 | } |
---|
479 | } |
---|
480 | FormatArguments(invocationExpression); |
---|
481 | if (popIndent) |
---|
482 | curIndent.Pop(); |
---|
483 | } |
---|
484 | |
---|
485 | public override void VisitIndexerExpression(IndexerExpression indexerExpression) |
---|
486 | { |
---|
487 | ForceSpacesBeforeRemoveNewLines(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets); |
---|
488 | ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets); |
---|
489 | |
---|
490 | if (!indexerExpression.Target.IsNull) |
---|
491 | indexerExpression.Target.AcceptVisitor(this); |
---|
492 | |
---|
493 | FormatArguments(indexerExpression); |
---|
494 | |
---|
495 | |
---|
496 | |
---|
497 | } |
---|
498 | |
---|
499 | public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression) |
---|
500 | { |
---|
501 | var lp = parenthesizedExpression.LParToken; |
---|
502 | var expr = parenthesizedExpression.Expression; |
---|
503 | int extraSpaces = 0; |
---|
504 | if (lp.StartLocation.Line == expr.StartLocation.Line) { |
---|
505 | ForceSpacesAfter(lp, policy.SpacesWithinParentheses); |
---|
506 | } else { |
---|
507 | extraSpaces += options.IndentSize; |
---|
508 | curIndent.ExtraSpaces += extraSpaces; |
---|
509 | FixIndentation(expr); |
---|
510 | } |
---|
511 | |
---|
512 | base.VisitParenthesizedExpression(parenthesizedExpression); |
---|
513 | |
---|
514 | var rp = parenthesizedExpression.RParToken; |
---|
515 | |
---|
516 | curIndent.ExtraSpaces -= extraSpaces; |
---|
517 | if (rp.StartLocation.Line == expr.EndLocation.Line) { |
---|
518 | ForceSpacesBefore(rp, policy.SpacesWithinParentheses); |
---|
519 | } else { |
---|
520 | FixIndentation(rp); |
---|
521 | } |
---|
522 | } |
---|
523 | |
---|
524 | public override void VisitSizeOfExpression(SizeOfExpression sizeOfExpression) |
---|
525 | { |
---|
526 | ForceSpacesBeforeRemoveNewLines(sizeOfExpression.LParToken, policy.SpaceBeforeSizeOfParentheses); |
---|
527 | ForceSpacesAfter(sizeOfExpression.LParToken, policy.SpacesWithinSizeOfParentheses); |
---|
528 | ForceSpacesBeforeRemoveNewLines(sizeOfExpression.RParToken, policy.SpacesWithinSizeOfParentheses); |
---|
529 | base.VisitSizeOfExpression(sizeOfExpression); |
---|
530 | } |
---|
531 | |
---|
532 | public override void VisitTypeOfExpression(TypeOfExpression typeOfExpression) |
---|
533 | { |
---|
534 | ForceSpacesBeforeRemoveNewLines(typeOfExpression.LParToken, policy.SpaceBeforeTypeOfParentheses); |
---|
535 | ForceSpacesAfter(typeOfExpression.LParToken, policy.SpacesWithinTypeOfParentheses); |
---|
536 | ForceSpacesBeforeRemoveNewLines(typeOfExpression.RParToken, policy.SpacesWithinTypeOfParentheses); |
---|
537 | base.VisitTypeOfExpression(typeOfExpression); |
---|
538 | } |
---|
539 | |
---|
540 | public override void VisitCheckedExpression(CheckedExpression checkedExpression) |
---|
541 | { |
---|
542 | ForceSpacesAfter(checkedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); |
---|
543 | ForceSpacesBeforeRemoveNewLines(checkedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); |
---|
544 | base.VisitCheckedExpression(checkedExpression); |
---|
545 | } |
---|
546 | |
---|
547 | public override void VisitUncheckedExpression(UncheckedExpression uncheckedExpression) |
---|
548 | { |
---|
549 | ForceSpacesAfter(uncheckedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses); |
---|
550 | ForceSpacesBeforeRemoveNewLines(uncheckedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses); |
---|
551 | base.VisitUncheckedExpression(uncheckedExpression); |
---|
552 | } |
---|
553 | |
---|
554 | public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression) |
---|
555 | { |
---|
556 | ForceSpacesBeforeRemoveNewLines(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses); |
---|
557 | |
---|
558 | if (objectCreateExpression.Arguments.Any()) { |
---|
559 | if (!objectCreateExpression.LParToken.IsNull) |
---|
560 | ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses); |
---|
561 | } else { |
---|
562 | if (!objectCreateExpression.LParToken.IsNull) |
---|
563 | ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses); |
---|
564 | } |
---|
565 | |
---|
566 | if (!objectCreateExpression.Type.IsNull) |
---|
567 | objectCreateExpression.Type.AcceptVisitor(this); |
---|
568 | objectCreateExpression.Initializer.AcceptVisitor(this); |
---|
569 | FormatArguments(objectCreateExpression); |
---|
570 | } |
---|
571 | |
---|
572 | public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression) |
---|
573 | { |
---|
574 | FormatCommas(arrayObjectCreateExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma); |
---|
575 | base.VisitArrayCreateExpression(arrayObjectCreateExpression); |
---|
576 | } |
---|
577 | |
---|
578 | public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression) |
---|
579 | { |
---|
580 | var old = curIndent; |
---|
581 | curIndent = curIndent.Clone(); |
---|
582 | curIndent.ExtraSpaces = 0; |
---|
583 | |
---|
584 | if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) { |
---|
585 | FixOpenBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken); |
---|
586 | curIndent.Push(IndentType.Block); |
---|
587 | foreach (var init in arrayInitializerExpression.Elements) { |
---|
588 | FixStatementIndentation(init.StartLocation); |
---|
589 | init.AcceptVisitor(this); |
---|
590 | } |
---|
591 | curIndent.Pop(); |
---|
592 | FixClosingBrace(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.RBraceToken); |
---|
593 | } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) { |
---|
594 | ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken); |
---|
595 | foreach (var init in arrayInitializerExpression.Elements) { |
---|
596 | ForceSpacesBeforeRemoveNewLines(init); |
---|
597 | init.AcceptVisitor(this); |
---|
598 | } |
---|
599 | ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken); |
---|
600 | } else { |
---|
601 | var lBrace = arrayInitializerExpression.LBraceToken; |
---|
602 | var rBrace = arrayInitializerExpression.RBraceToken; |
---|
603 | |
---|
604 | foreach (var child in arrayInitializerExpression.Children) { |
---|
605 | if (child.Role == Roles.LBrace) { |
---|
606 | if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) { |
---|
607 | ForceSpacesAfter(child, true); |
---|
608 | } else { |
---|
609 | FixOpenBrace(policy.ArrayInitializerBraceStyle, child); |
---|
610 | } |
---|
611 | curIndent.Push(IndentType.Block); |
---|
612 | continue; |
---|
613 | } |
---|
614 | if (child.Role == Roles.RBrace) { |
---|
615 | curIndent.Pop(); |
---|
616 | if (lBrace.StartLocation.Line == rBrace.StartLocation.Line && policy.AllowOneLinedArrayInitialziers) { |
---|
617 | ForceSpaceBefore(child, true); |
---|
618 | |
---|
619 | } else { |
---|
620 | FixClosingBrace(policy.ArrayInitializerBraceStyle, child); |
---|
621 | } |
---|
622 | continue; |
---|
623 | } |
---|
624 | if (child.Role == Roles.Expression) { |
---|
625 | if (child.PrevSibling != null) { |
---|
626 | if (child.PrevSibling.Role == Roles.NewLine) { |
---|
627 | FixIndentation(child); |
---|
628 | } |
---|
629 | if (child.PrevSibling.Role == Roles.Comma) { |
---|
630 | ForceSpaceBefore(child, true); |
---|
631 | } |
---|
632 | } |
---|
633 | child.AcceptVisitor(this); |
---|
634 | if (child.NextSibling != null && child.NextSibling.Role == Roles.Comma) |
---|
635 | ForceSpacesAfter(child, false); |
---|
636 | continue; |
---|
637 | } |
---|
638 | |
---|
639 | child.AcceptVisitor(this); |
---|
640 | } |
---|
641 | } |
---|
642 | curIndent = old; |
---|
643 | } |
---|
644 | |
---|
645 | public override void VisitParameterDeclaration(ParameterDeclaration parameterDeclaration) |
---|
646 | { |
---|
647 | var assignToken = parameterDeclaration.AssignToken; |
---|
648 | if (!assignToken.IsNull) |
---|
649 | ForceSpacesAround(assignToken, policy.SpaceAroundAssignment); |
---|
650 | base.VisitParameterDeclaration(parameterDeclaration); |
---|
651 | } |
---|
652 | |
---|
653 | public override void VisitLambdaExpression(LambdaExpression lambdaExpression) |
---|
654 | { |
---|
655 | FormatArguments(lambdaExpression); |
---|
656 | ForceSpacesBeforeRemoveNewLines(lambdaExpression.ArrowToken, true); |
---|
657 | |
---|
658 | if (!lambdaExpression.Body.IsNull) { |
---|
659 | var body = lambdaExpression.Body as BlockStatement; |
---|
660 | if (body != null) { |
---|
661 | var old = curIndent; |
---|
662 | this.curIndent = curIndent.GetIndentWithoutSpace (); |
---|
663 | FixOpenBrace(policy.AnonymousMethodBraceStyle, body.LBraceToken); |
---|
664 | VisitBlockWithoutFixingBraces(body, policy.IndentMethodBody); |
---|
665 | FixClosingBrace(policy.AnonymousMethodBraceStyle, body.RBraceToken); |
---|
666 | curIndent = old; |
---|
667 | } else { |
---|
668 | ForceSpacesAfter(lambdaExpression.ArrowToken, true); |
---|
669 | lambdaExpression.Body.AcceptVisitor(this); |
---|
670 | } |
---|
671 | } |
---|
672 | } |
---|
673 | |
---|
674 | public override void VisitNamedExpression(NamedExpression namedExpression) |
---|
675 | { |
---|
676 | ForceSpacesAround(namedExpression.AssignToken, policy.SpaceAroundAssignment); |
---|
677 | base.VisitNamedExpression(namedExpression); |
---|
678 | } |
---|
679 | |
---|
680 | public override void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression) |
---|
681 | { |
---|
682 | ForceSpacesAfter(namedArgumentExpression.ColonToken, policy.SpaceInNamedArgumentAfterDoubleColon); |
---|
683 | |
---|
684 | base.VisitNamedArgumentExpression(namedArgumentExpression); |
---|
685 | } |
---|
686 | |
---|
687 | public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression) |
---|
688 | { |
---|
689 | var dot = memberReferenceExpression.DotToken; |
---|
690 | if (dot.PrevSibling.EndLocation.Line == dot.StartLocation.Line) |
---|
691 | ForceSpacesBefore(dot, false); |
---|
692 | ForceSpacesAfter(dot, false); |
---|
693 | base.VisitMemberReferenceExpression(memberReferenceExpression); |
---|
694 | } |
---|
695 | |
---|
696 | public override void VisitPointerReferenceExpression(PointerReferenceExpression pointerReferenceExpression) |
---|
697 | { |
---|
698 | ForceSpacesAround(pointerReferenceExpression.ArrowToken, policy.SpaceAroundUnsafeArrowOperator); |
---|
699 | base.VisitPointerReferenceExpression(pointerReferenceExpression); |
---|
700 | } |
---|
701 | |
---|
702 | public override void VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression) |
---|
703 | { |
---|
704 | base.VisitUnaryOperatorExpression(unaryOperatorExpression); |
---|
705 | switch (unaryOperatorExpression.Operator) { |
---|
706 | case UnaryOperatorType.Any: |
---|
707 | break; |
---|
708 | case UnaryOperatorType.Not: |
---|
709 | case UnaryOperatorType.BitNot: |
---|
710 | case UnaryOperatorType.Minus: |
---|
711 | case UnaryOperatorType.Plus: |
---|
712 | case UnaryOperatorType.Increment: |
---|
713 | case UnaryOperatorType.Decrement: |
---|
714 | ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.Expression, false); |
---|
715 | break; |
---|
716 | case UnaryOperatorType.PostIncrement: |
---|
717 | case UnaryOperatorType.PostDecrement: |
---|
718 | ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.OperatorToken, false); |
---|
719 | break; |
---|
720 | case UnaryOperatorType.Dereference: |
---|
721 | ForceSpacesAfter(unaryOperatorExpression.OperatorToken, policy.SpaceAfterUnsafeAsteriskOfOperator); |
---|
722 | break; |
---|
723 | case UnaryOperatorType.AddressOf: |
---|
724 | ForceSpacesAfter(unaryOperatorExpression.OperatorToken, policy.SpaceAfterUnsafeAddressOfOperator); |
---|
725 | break; |
---|
726 | case UnaryOperatorType.Await: |
---|
727 | ForceSpacesBeforeRemoveNewLines(unaryOperatorExpression.Expression, true); |
---|
728 | break; |
---|
729 | default: |
---|
730 | throw new ArgumentOutOfRangeException(); |
---|
731 | } |
---|
732 | } |
---|
733 | } |
---|
734 | } |
---|
735 | |
---|