~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Formatter/AstFormattingVisitor.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// 
2
 
// AstFormattingVisitor.cs
3
 
//
4
 
// Author:
5
 
//       Mike KrĆ¼ger <mkrueger@novell.com>
6
 
// 
7
 
// Copyright (c) 2010 Novell, Inc (http://www.novell.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.Diagnostics;
28
 
using System.Text;
29
 
using System.Collections.Generic;
30
 
using System.Linq;
31
 
using ICSharpCode.NRefactory.Editor;
32
 
using ICSharpCode.NRefactory.TypeSystem;
33
 
using ICSharpCode.NRefactory.CSharp.Refactoring;
34
 
 
35
 
namespace ICSharpCode.NRefactory.CSharp
36
 
{
37
 
        public enum FormattingMode {
38
 
                OnTheFly,
39
 
                Intrusive
40
 
        }
41
 
 
42
 
        public class AstFormattingVisitor : DepthFirstAstVisitor
43
 
        {
44
 
                sealed class TextReplaceAction
45
 
                {
46
 
                        internal readonly int Offset;
47
 
                        internal readonly int RemovalLength;
48
 
                        internal readonly string NewText;
49
 
                        internal TextReplaceAction DependsOn;
50
 
 
51
 
#if DEBUG
52
 
                        internal readonly string StackTrace;
53
 
#endif
54
 
 
55
 
                        public TextReplaceAction (int offset, int removalLength, string newText)
56
 
                        {
57
 
                                this.Offset = offset;
58
 
                                this.RemovalLength = removalLength;
59
 
                                this.NewText = newText ?? string.Empty;
60
 
                                #if DEBUG
61
 
                                this.StackTrace = Environment.StackTrace;
62
 
                                #endif
63
 
                        }
64
 
                        
65
 
                        public override bool Equals(object obj)
66
 
                        {
67
 
                                TextReplaceAction other = obj as TextReplaceAction;
68
 
                                if (other == null) {
69
 
                                        return false;
70
 
                                }
71
 
                                return this.Offset == other.Offset && this.RemovalLength == other.RemovalLength && this.NewText == other.NewText;
72
 
                        }
73
 
                        
74
 
                        public override int GetHashCode()
75
 
                        {
76
 
                                return 0;
77
 
                        }
78
 
 
79
 
                        public override string ToString()
80
 
                        {
81
 
                                return string.Format("[TextReplaceAction: Offset={0}, RemovalLength={1}, NewText={2}]", Offset, RemovalLength, NewText);
82
 
                        }
83
 
                }
84
 
                
85
 
                CSharpFormattingOptions policy;
86
 
                IDocument document;
87
 
                List<TextReplaceAction> changes = new List<TextReplaceAction> ();
88
 
                Indent curIndent;
89
 
                readonly TextEditorOptions options;
90
 
                
91
 
                public FormattingMode FormattingMode {
92
 
                        get;
93
 
                        set;
94
 
                }
95
 
 
96
 
                public bool HadErrors {
97
 
                        get;
98
 
                        set;
99
 
                }
100
 
 
101
 
                public DomRegion FormattingRegion {
102
 
                        get;
103
 
                        set;
104
 
                }
105
 
                
106
 
                public AstFormattingVisitor(CSharpFormattingOptions policy, IDocument document, TextEditorOptions options = null)
107
 
                {
108
 
                        if (policy == null) {
109
 
                                throw new ArgumentNullException("policy");
110
 
                        }
111
 
                        if (document == null) {
112
 
                                throw new ArgumentNullException("document");
113
 
                        }
114
 
                        this.policy = policy;
115
 
                        this.document = document;
116
 
                        this.options = options ?? TextEditorOptions.Default;
117
 
                        curIndent = new Indent(this.options);
118
 
                }
119
 
 
120
 
                protected virtual void VisitChildren (AstNode node)
121
 
                {
122
 
                        if (!FormattingRegion.IsEmpty) {
123
 
                                if (node.EndLocation < FormattingRegion.Begin || node.StartLocation > FormattingRegion.End)
124
 
                                        return;
125
 
                        }
126
 
 
127
 
                        AstNode next;
128
 
                        for (var child = node.FirstChild; child != null; child = next) {
129
 
                                // Store next to allow the loop to continue
130
 
                                // if the visitor removes/replaces child.
131
 
                                next = child.NextSibling;
132
 
                                child.AcceptVisitor (this);
133
 
                        }
134
 
                }
135
 
                
136
 
                /// <summary>
137
 
                /// Applies the changes to the input document.
138
 
                /// </summary>
139
 
                public void ApplyChanges()
140
 
                {
141
 
                        ApplyChanges(0, document.TextLength, document.Replace, (o, l, v) => document.GetText(o, l) == v);
142
 
                }
143
 
                
144
 
                public void ApplyChanges(int startOffset, int length)
145
 
                {
146
 
                        ApplyChanges(startOffset, length, document.Replace, (o, l, v) => document.GetText(o, l) == v);
147
 
                }
148
 
                
149
 
                /// <summary>
150
 
                /// Applies the changes to the given Script instance.
151
 
                /// </summary>
152
 
                public void ApplyChanges(Script script)
153
 
                {
154
 
                        ApplyChanges(0, document.TextLength, script.Replace);
155
 
                }
156
 
                
157
 
                public void ApplyChanges(int startOffset, int length, Script script)
158
 
                {
159
 
                        ApplyChanges(startOffset, length, script.Replace);
160
 
                }
161
 
                
162
 
                public void ApplyChanges(int startOffset, int length, Action<int, int, string> documentReplace, Func<int, int, string, bool> filter = null)
163
 
                {
164
 
                        int endOffset = startOffset + length;
165
 
                        TextReplaceAction previousChange = null;
166
 
                        int delta = 0;
167
 
                        var depChanges = new List<TextReplaceAction> ();
168
 
                        foreach (var change in changes.OrderBy(c => c.Offset)) {
169
 
                                if (previousChange != null) {
170
 
                                        if (change.Equals(previousChange)) {
171
 
                                                // ignore duplicate changes
172
 
                                                continue;
173
 
                                        }
174
 
                                        if (change.Offset < previousChange.Offset + previousChange.RemovalLength) {
175
 
                                                #if DEBUG
176
 
                                                Console.WriteLine ("change 1:" + change);
177
 
                                                Console.WriteLine (change.StackTrace);
178
 
 
179
 
                                                Console.WriteLine ("change 2:" + change);
180
 
                                                Console.WriteLine (previousChange.StackTrace);
181
 
                                                #endif
182
 
                                                throw new InvalidOperationException ("Detected overlapping changes " + change + "/" + previousChange);
183
 
                                        }
184
 
                                }
185
 
                                previousChange = change;
186
 
                                
187
 
                                bool skipChange = change.Offset < startOffset || change.Offset > endOffset;
188
 
                                skipChange |= filter != null && filter(change.Offset + delta, change.RemovalLength, change.NewText);
189
 
                                skipChange &= !depChanges.Contains(change);
190
 
 
191
 
                                if (!skipChange) {
192
 
                                        documentReplace(change.Offset + delta, change.RemovalLength, change.NewText);
193
 
                                        delta += change.NewText.Length - change.RemovalLength;
194
 
                                        if (change.DependsOn != null) {
195
 
                                                depChanges.Add(change.DependsOn);
196
 
                                        }
197
 
                                }
198
 
                        }
199
 
                        changes.Clear();
200
 
                }
201
 
 
202
 
                public override void VisitCompilationUnit(CompilationUnit unit)
203
 
                {
204
 
                        base.VisitCompilationUnit(unit);
205
 
                }
206
 
 
207
 
                public void EnsureBlankLinesAfter(AstNode node, int blankLines)
208
 
                {
209
 
                        if (FormattingMode != FormattingMode.Intrusive)
210
 
                                return;
211
 
                        var loc = node.EndLocation;
212
 
                        int line = loc.Line;
213
 
                        do {
214
 
                                line++;
215
 
                        } while (line < document.LineCount && IsSpacing(document.GetLineByNumber(line)));
216
 
                        var start = document.GetOffset(node.EndLocation);
217
 
                        
218
 
                        int foundBlankLines = line - loc.Line - 1;
219
 
                        
220
 
                        StringBuilder sb = new StringBuilder();
221
 
                        for (int i = 0; i < blankLines - foundBlankLines; i++) {
222
 
                                sb.Append(this.options.EolMarker);
223
 
                        }
224
 
                        
225
 
                        int ws = start;
226
 
                        while (ws < document.TextLength && IsSpacing (document.GetCharAt (ws))) {
227
 
                                ws++;
228
 
                        }
229
 
                        int removedChars = ws - start;
230
 
                        if (foundBlankLines > blankLines) {
231
 
                                removedChars += document.GetLineByNumber(loc.Line + foundBlankLines - blankLines).EndOffset
232
 
                                        - document.GetLineByNumber(loc.Line).EndOffset;
233
 
                        }
234
 
                        AddChange(start, removedChars, sb.ToString());
235
 
                }
236
 
 
237
 
                public void EnsureBlankLinesBefore(AstNode node, int blankLines)
238
 
                {
239
 
                        if (FormattingMode != FormattingMode.Intrusive)
240
 
                                return;
241
 
                        var loc = node.StartLocation;
242
 
                        int line = loc.Line;
243
 
                        do {
244
 
                                line--;
245
 
                        } while (line > 0 && IsSpacing(document.GetLineByNumber(line)));
246
 
                        int end = document.GetOffset(loc.Line, 1);
247
 
                        int start = document.GetOffset(line + 1, 1);
248
 
                        StringBuilder sb = new StringBuilder ();
249
 
                        for (int i = 0; i < blankLines; i++) {
250
 
                                sb.Append(this.options.EolMarker);
251
 
                        }
252
 
                        if (end - start == 0 && sb.Length == 0)
253
 
                                return;
254
 
                        AddChange(start, end - start, sb.ToString());
255
 
                }
256
 
 
257
 
                public override void VisitUsingDeclaration(UsingDeclaration usingDeclaration)
258
 
                {
259
 
                        if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling is UsingAliasDeclaration)) {
260
 
                                EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
261
 
                        } else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling  is UsingAliasDeclaration)) {
262
 
                                FixIndentationForceNewLine(usingDeclaration.StartLocation);
263
 
                                EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
264
 
                        } else {
265
 
                                FixIndentationForceNewLine(usingDeclaration.StartLocation);
266
 
                        }
267
 
                }
268
 
 
269
 
                public override void VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
270
 
                {
271
 
                        if (usingDeclaration.PrevSibling != null && !(usingDeclaration.PrevSibling is UsingDeclaration || usingDeclaration.PrevSibling  is UsingAliasDeclaration)) {
272
 
                                EnsureBlankLinesBefore(usingDeclaration, policy.BlankLinesBeforeUsings);
273
 
                        } else if (!(usingDeclaration.NextSibling is UsingDeclaration || usingDeclaration.NextSibling  is UsingAliasDeclaration)) {
274
 
                                FixIndentationForceNewLine(usingDeclaration.StartLocation);
275
 
                                EnsureBlankLinesAfter(usingDeclaration, policy.BlankLinesAfterUsings);
276
 
                        } else {
277
 
                                FixIndentationForceNewLine(usingDeclaration.StartLocation);
278
 
                        }
279
 
                }
280
 
 
281
 
                public override void VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
282
 
                {
283
 
                        var firstNsMember = namespaceDeclaration.Members.FirstOrDefault();
284
 
                        if (firstNsMember != null) {
285
 
                                EnsureBlankLinesBefore(firstNsMember, policy.BlankLinesBeforeFirstDeclaration);
286
 
                        }
287
 
                        FixIndentationForceNewLine(namespaceDeclaration.StartLocation);
288
 
                        EnforceBraceStyle(policy.NamespaceBraceStyle, namespaceDeclaration.LBraceToken, namespaceDeclaration.RBraceToken);
289
 
                        if (policy.IndentNamespaceBody) {
290
 
                                curIndent.Push(IndentType.Block);
291
 
                        }
292
 
                        base.VisitNamespaceDeclaration(namespaceDeclaration);
293
 
                        if (policy.IndentNamespaceBody) {
294
 
                                curIndent.Pop ();
295
 
                        }
296
 
                        FixIndentation(namespaceDeclaration.RBraceToken.StartLocation);
297
 
                }
298
 
 
299
 
                public override void VisitTypeDeclaration(TypeDeclaration typeDeclaration)
300
 
                {
301
 
                        FormatAttributedNode(typeDeclaration);
302
 
                        BraceStyle braceStyle;
303
 
                        bool indentBody = false;
304
 
                        switch (typeDeclaration.ClassType) {
305
 
                                case ClassType.Class:
306
 
                                        braceStyle = policy.ClassBraceStyle;
307
 
                                        indentBody = policy.IndentClassBody;
308
 
                                        break;
309
 
                                case ClassType.Struct:
310
 
                                        braceStyle = policy.StructBraceStyle;
311
 
                                        indentBody = policy.IndentStructBody;
312
 
                                        break;
313
 
                                case ClassType.Interface:
314
 
                                        braceStyle = policy.InterfaceBraceStyle;
315
 
                                        indentBody = policy.IndentInterfaceBody;
316
 
                                        break;
317
 
                                case ClassType.Enum:
318
 
                                        braceStyle = policy.EnumBraceStyle;
319
 
                                        indentBody = policy.IndentEnumBody;
320
 
                                        break;
321
 
                                default:
322
 
                                        throw new InvalidOperationException("unsupported class type : " + typeDeclaration.ClassType);
323
 
                        }
324
 
 
325
 
                        EnforceBraceStyle(braceStyle, typeDeclaration.LBraceToken, typeDeclaration.RBraceToken);
326
 
                        
327
 
                        if (indentBody) {
328
 
                                curIndent.Push(IndentType.Block);
329
 
                        }
330
 
                        base.VisitTypeDeclaration(typeDeclaration);
331
 
                        if (indentBody) {
332
 
                                curIndent.Pop ();
333
 
                        }
334
 
                        
335
 
                        if (typeDeclaration.NextSibling is TypeDeclaration || typeDeclaration.NextSibling is DelegateDeclaration) {
336
 
                                EnsureBlankLinesAfter(typeDeclaration, policy.BlankLinesBetweenTypes);
337
 
                        }
338
 
 
339
 
                }
340
 
 
341
 
                bool IsSimpleAccessor(Accessor accessor)
342
 
                {
343
 
                        if (accessor.IsNull || accessor.Body.IsNull || accessor.Body.FirstChild == null) {
344
 
                                return true;
345
 
                        }
346
 
                        if (accessor.Body.Statements.Count() != 1) {
347
 
                                return false;
348
 
                        }
349
 
                        return !(accessor.Body.Statements.FirstOrDefault() is BlockStatement);
350
 
                        
351
 
                }
352
 
 
353
 
                bool IsSpacing(char ch)
354
 
                {
355
 
                        return ch == ' ' || ch == '\t';
356
 
                }
357
 
                
358
 
                bool IsSpacing(ISegment segment)
359
 
                {
360
 
                        int endOffset = segment.EndOffset;
361
 
                        for (int i = segment.Offset; i < endOffset; i++) {
362
 
                                if (!IsSpacing(document.GetCharAt(i))) {
363
 
                                        return false;
364
 
                                }
365
 
                        }
366
 
                        return true;
367
 
                }
368
 
 
369
 
                int SearchLastNonWsChar(int startOffset, int endOffset)
370
 
                {
371
 
                        startOffset = System.Math.Max(0, startOffset);
372
 
                        endOffset = System.Math.Max(startOffset, endOffset);
373
 
                        if (startOffset >= endOffset) {
374
 
                                return startOffset;
375
 
                        }
376
 
                        int result = -1;
377
 
                        bool inComment = false;
378
 
                        
379
 
                        for (int i = startOffset; i < endOffset && i < document.TextLength; i++) {
380
 
                                char ch = document.GetCharAt(i);
381
 
                                if (IsSpacing(ch)) {
382
 
                                        continue;
383
 
                                }
384
 
                                if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') {
385
 
                                        return result;
386
 
                                }
387
 
                                if (ch == '/' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '*') {
388
 
                                        inComment = true;
389
 
                                        i++;
390
 
                                        continue;
391
 
                                }
392
 
                                if (inComment && ch == '*' && i + 1 < document.TextLength && document.GetCharAt(i + 1) == '/') {
393
 
                                        inComment = false;
394
 
                                        i++;
395
 
                                        continue;
396
 
                                }
397
 
                                if (!inComment) {
398
 
                                        result = i;
399
 
                                }
400
 
                        }
401
 
                        return result;
402
 
                }
403
 
 
404
 
                void ForceSpace(int startOffset, int endOffset, bool forceSpace)
405
 
                {
406
 
                        int lastNonWs = SearchLastNonWsChar(startOffset, endOffset);
407
 
                        AddChange(lastNonWs + 1, System.Math.Max(0, endOffset - lastNonWs - 1), forceSpace ? " " : "");
408
 
                }
409
 
//              void ForceSpacesAfter (AstNode n, bool forceSpaces)
410
 
//              {
411
 
//                      if (n == null)
412
 
//                              return;
413
 
//                      AstLocation location = n.EndLocation;
414
 
//                      int offset = data.LocationToOffset (location.Line, location.Column);
415
 
//                      int i = offset;
416
 
//                      while (i < data.Length && IsSpacing (data.GetCharAt (i))) {
417
 
//                              i++;
418
 
//                      }
419
 
//                      ForceSpace (offset - 1, i, forceSpaces);
420
 
//              }
421
 
                
422
 
                void ForceSpacesAfter(AstNode n, bool forceSpaces)
423
 
                {
424
 
                        if (n == null) {
425
 
                                return;
426
 
                        }
427
 
                        TextLocation location = n.EndLocation;
428
 
                        int offset = document.GetOffset(location);
429
 
                        if (location.Column > document.GetLineByNumber(location.Line).Length) {
430
 
                                return;
431
 
                        }
432
 
                        int i = offset;
433
 
                        while (i < document.TextLength && IsSpacing (document.GetCharAt (i))) {
434
 
                                i++;
435
 
                        }
436
 
                        ForceSpace(offset - 1, i, forceSpaces);
437
 
                }
438
 
                
439
 
//              int ForceSpacesBefore (AstNode n, bool forceSpaces)
440
 
//              {
441
 
//                      if (n == null || n.IsNull)
442
 
//                              return 0;
443
 
//                      AstLocation location = n.StartLocation;
444
 
//
445
 
//                      int offset = data.LocationToOffset (location.Line, location.Column);
446
 
//                      int i = offset - 1;
447
 
//
448
 
//                      while (i >= 0 && IsSpacing (data.GetCharAt (i))) {
449
 
//                              i--;
450
 
//                      }
451
 
//                      ForceSpace (i, offset, forceSpaces);
452
 
//                      return i;
453
 
//              }
454
 
                
455
 
                int ForceSpacesBefore(AstNode n, bool forceSpaces)
456
 
                {
457
 
                        if (n == null || n.IsNull) {
458
 
                                return 0;
459
 
                        }
460
 
                        TextLocation location = n.StartLocation;
461
 
                        // respect manual line breaks.
462
 
                        if (location.Column <= 1 || GetIndentation(location.Line).Length == location.Column - 1) {
463
 
                                return 0;
464
 
                        }
465
 
                        
466
 
                        int offset = document.GetOffset(location);
467
 
                        int i = offset - 1;
468
 
                        while (i >= 0 && IsSpacing (document.GetCharAt (i))) {
469
 
                                i--;
470
 
                        }
471
 
                        ForceSpace(i, offset, forceSpaces);
472
 
                        return i;
473
 
                }
474
 
 
475
 
                int ForceSpacesBeforeRemoveNewLines(AstNode n, bool forceSpace = true)
476
 
                {
477
 
                        if (n == null || n.IsNull) {
478
 
                                return 0;
479
 
                        }
480
 
                        int offset = document.GetOffset(n.StartLocation);
481
 
                        int i = offset - 1;
482
 
                        while (i >= 0) {
483
 
                                char ch = document.GetCharAt(i);
484
 
                                if (!IsSpacing(ch) && ch != '\r' && ch != '\n')
485
 
                                        break;
486
 
                                i--;
487
 
                        }
488
 
                        var length = System.Math.Max(0, (offset - 1) - i);
489
 
                        AddChange(i + 1, length, forceSpace ? " " : "");
490
 
                        return i;
491
 
                }
492
 
 
493
 
                public override void VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
494
 
                {
495
 
                        FormatAttributedNode(propertyDeclaration);
496
 
                        bool oneLine = false;
497
 
                        switch (policy.PropertyFormatting) {
498
 
                                case PropertyFormatting.AllowOneLine:
499
 
                                        bool isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter);
500
 
                                        int accessorLine = propertyDeclaration.RBraceToken.StartLocation.Line;
501
 
                                        if (!propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull) {
502
 
                                                accessorLine = propertyDeclaration.Getter.StartLocation.Line;
503
 
                                        } else if (propertyDeclaration.Getter.IsNull && !propertyDeclaration.Setter.IsNull) {
504
 
                                                accessorLine = propertyDeclaration.Setter.StartLocation.Line;
505
 
                                        } else {
506
 
                                                var acc = propertyDeclaration.Getter.StartLocation < propertyDeclaration.Setter.StartLocation ?
507
 
                                                        propertyDeclaration.Getter : propertyDeclaration.Setter;
508
 
                                                accessorLine = acc.StartLocation.Line;
509
 
                                        }
510
 
                                        if (!isSimple || propertyDeclaration.LBraceToken.StartLocation.Line != accessorLine) {
511
 
                                                EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
512
 
                                        } else {
513
 
                                                ForceSpacesBefore(propertyDeclaration.Getter, true);
514
 
                                                ForceSpacesBefore(propertyDeclaration.Setter, true);
515
 
                                                ForceSpacesBeforeRemoveNewLines(propertyDeclaration.RBraceToken, true);
516
 
                                                oneLine = true;
517
 
                                        }
518
 
                                        break;
519
 
                                case PropertyFormatting.ForceNewLine:
520
 
                                        EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
521
 
                                        break;
522
 
                                case PropertyFormatting.ForceOneLine:
523
 
                                        isSimple = IsSimpleAccessor(propertyDeclaration.Getter) && IsSimpleAccessor(propertyDeclaration.Setter);
524
 
                                        if (isSimple) {
525
 
                                                int offset = this.document.GetOffset(propertyDeclaration.LBraceToken.StartLocation);
526
 
                                        
527
 
                                                int start = SearchWhitespaceStart(offset);
528
 
                                                int end = SearchWhitespaceEnd(offset);
529
 
                                                AddChange(start, offset - start, " ");
530
 
                                                AddChange(offset + 1, end - offset - 2, " ");
531
 
                                        
532
 
                                                offset = this.document.GetOffset(propertyDeclaration.RBraceToken.StartLocation);
533
 
                                                start = SearchWhitespaceStart(offset);
534
 
                                                AddChange(start, offset - start, " ");
535
 
                                                oneLine = true;
536
 
                                
537
 
                                        } else {
538
 
                                                EnforceBraceStyle(policy.PropertyBraceStyle, propertyDeclaration.LBraceToken, propertyDeclaration.RBraceToken);
539
 
                                        }
540
 
                                        break;
541
 
                        }
542
 
                        if (policy.IndentPropertyBody) {
543
 
                                curIndent.Push(IndentType.Block);
544
 
                        }
545
 
                        ///System.Console.WriteLine ("one line: " + oneLine);
546
 
                        if (!propertyDeclaration.Getter.IsNull) {
547
 
                                if (!oneLine) {
548
 
                                        if (!IsLineIsEmptyUpToEol(propertyDeclaration.Getter.StartLocation)) {
549
 
                                                int offset = this.document.GetOffset(propertyDeclaration.Getter.StartLocation);
550
 
                                                int start = SearchWhitespaceStart(offset);
551
 
                                                string indentString = this.curIndent.IndentString;
552
 
                                                AddChange(start, offset - start, this.options.EolMarker + indentString);
553
 
                                        } else {
554
 
                                                FixIndentation(propertyDeclaration.Getter.StartLocation);
555
 
                                        }
556
 
                                } else {
557
 
                                        int offset = this.document.GetOffset(propertyDeclaration.Getter.StartLocation);
558
 
                                        int start = SearchWhitespaceStart(offset);
559
 
                                        AddChange(start, offset - start, " ");
560
 
                                        
561
 
                                        ForceSpacesBefore(propertyDeclaration.Getter.Body.LBraceToken, true);
562
 
                                        ForceSpacesBefore(propertyDeclaration.Getter.Body.RBraceToken, true);
563
 
                                }
564
 
                                if (!propertyDeclaration.Getter.Body.IsNull) {
565
 
                                        if (!policy.AllowPropertyGetBlockInline || propertyDeclaration.Getter.Body.LBraceToken.StartLocation.Line != propertyDeclaration.Getter.Body.RBraceToken.StartLocation.Line) {
566
 
                                                EnforceBraceStyle(policy.PropertyGetBraceStyle, propertyDeclaration.Getter.Body.LBraceToken, propertyDeclaration.Getter.Body.RBraceToken);
567
 
                                        } else {
568
 
                                                nextStatementIndent = " ";
569
 
                                        }
570
 
                                        VisitBlockWithoutFixingBraces(propertyDeclaration.Getter.Body, policy.IndentBlocks);
571
 
                                }
572
 
                        }
573
 
                        
574
 
                        if (!propertyDeclaration.Setter.IsNull) {
575
 
                                if (!oneLine) {
576
 
                                        if (!IsLineIsEmptyUpToEol(propertyDeclaration.Setter.StartLocation)) {
577
 
                                                int offset = this.document.GetOffset(propertyDeclaration.Setter.StartLocation);
578
 
                                                int start = SearchWhitespaceStart(offset);
579
 
                                                string indentString = this.curIndent.IndentString;
580
 
                                                AddChange(start, offset - start, this.options.EolMarker + indentString);
581
 
                                        } else {
582
 
                                                FixIndentation(propertyDeclaration.Setter.StartLocation);
583
 
                                        }
584
 
                                } else {
585
 
                                        int offset = this.document.GetOffset(propertyDeclaration.Setter.StartLocation);
586
 
                                        int start = SearchWhitespaceStart(offset);
587
 
                                        AddChange(start, offset - start, " ");
588
 
                                        
589
 
                                        ForceSpacesBefore(propertyDeclaration.Setter.Body.LBraceToken, true);
590
 
                                        ForceSpacesBefore(propertyDeclaration.Setter.Body.RBraceToken, true);
591
 
                                }
592
 
                                if (!propertyDeclaration.Setter.Body.IsNull) {
593
 
                                        if (!policy.AllowPropertySetBlockInline || propertyDeclaration.Setter.Body.LBraceToken.StartLocation.Line != propertyDeclaration.Setter.Body.RBraceToken.StartLocation.Line) {
594
 
                                                EnforceBraceStyle(policy.PropertySetBraceStyle, propertyDeclaration.Setter.Body.LBraceToken, propertyDeclaration.Setter.Body.RBraceToken);
595
 
                                        } else {
596
 
                                                nextStatementIndent = " ";
597
 
                                        }
598
 
                                        VisitBlockWithoutFixingBraces(propertyDeclaration.Setter.Body, policy.IndentBlocks);
599
 
                                }
600
 
                        }
601
 
                        
602
 
                        if (policy.IndentPropertyBody) {
603
 
                                curIndent.Pop ();
604
 
                        }
605
 
                        if (IsMember(propertyDeclaration.NextSibling)) {
606
 
                                EnsureBlankLinesAfter(propertyDeclaration, policy.BlankLinesBetweenMembers);
607
 
                        }
608
 
                }
609
 
 
610
 
                public override void VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
611
 
                {
612
 
                        ForceSpacesBefore(indexerDeclaration.LBracketToken, policy.SpaceBeforeIndexerDeclarationBracket);
613
 
                        ForceSpacesAfter(indexerDeclaration.LBracketToken, policy.SpaceWithinIndexerDeclarationBracket);
614
 
 
615
 
                        FormatParameters(indexerDeclaration);
616
 
 
617
 
                        FormatAttributedNode(indexerDeclaration);
618
 
                        EnforceBraceStyle(policy.PropertyBraceStyle, indexerDeclaration.LBraceToken, indexerDeclaration.RBraceToken);
619
 
                        if (policy.IndentPropertyBody) {
620
 
                                curIndent.Push(IndentType.Block);
621
 
                        }
622
 
                        
623
 
                        if (!indexerDeclaration.Getter.IsNull) {
624
 
                                FixIndentation(indexerDeclaration.Getter.StartLocation);
625
 
                                if (!indexerDeclaration.Getter.Body.IsNull) {
626
 
                                        if (!policy.AllowPropertyGetBlockInline || indexerDeclaration.Getter.Body.LBraceToken.StartLocation.Line != indexerDeclaration.Getter.Body.RBraceToken.StartLocation.Line) {
627
 
                                                EnforceBraceStyle(policy.PropertyGetBraceStyle, indexerDeclaration.Getter.Body.LBraceToken, indexerDeclaration.Getter.Body.RBraceToken);
628
 
                                        } else {
629
 
                                                nextStatementIndent = " ";
630
 
                                        }
631
 
                                        VisitBlockWithoutFixingBraces(indexerDeclaration.Getter.Body, policy.IndentBlocks);
632
 
                                }
633
 
                        }
634
 
                        
635
 
                        if (!indexerDeclaration.Setter.IsNull) {
636
 
                                FixIndentation(indexerDeclaration.Setter.StartLocation);
637
 
                                if (!indexerDeclaration.Setter.Body.IsNull) {
638
 
                                        if (!policy.AllowPropertySetBlockInline || indexerDeclaration.Setter.Body.LBraceToken.StartLocation.Line != indexerDeclaration.Setter.Body.RBraceToken.StartLocation.Line) {
639
 
                                                EnforceBraceStyle(policy.PropertySetBraceStyle, indexerDeclaration.Setter.Body.LBraceToken, indexerDeclaration.Setter.Body.RBraceToken);
640
 
                                        } else {
641
 
                                                nextStatementIndent = " ";
642
 
                                        }
643
 
                                        VisitBlockWithoutFixingBraces(indexerDeclaration.Setter.Body, policy.IndentBlocks);
644
 
                                }
645
 
                        }
646
 
                        if (policy.IndentPropertyBody) {
647
 
                                curIndent.Pop ();
648
 
                        }
649
 
                        if (IsMember(indexerDeclaration.NextSibling)) {
650
 
                                EnsureBlankLinesAfter(indexerDeclaration, policy.BlankLinesBetweenMembers);
651
 
                        }
652
 
                }
653
 
 
654
 
                static bool IsSimpleEvent(AstNode node)
655
 
                {
656
 
                        return node is EventDeclaration;
657
 
                }
658
 
 
659
 
                public override void VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)
660
 
                {
661
 
                        FormatAttributedNode(eventDeclaration);
662
 
                        EnforceBraceStyle(policy.EventBraceStyle, eventDeclaration.LBraceToken, eventDeclaration.RBraceToken);
663
 
                        if (policy.IndentEventBody) {
664
 
                                curIndent.Push(IndentType.Block);
665
 
                        }
666
 
                        
667
 
                        if (!eventDeclaration.AddAccessor.IsNull) {
668
 
                                FixIndentation(eventDeclaration.AddAccessor.StartLocation);
669
 
                                if (!eventDeclaration.AddAccessor.Body.IsNull) {
670
 
                                        if (!policy.AllowEventAddBlockInline || eventDeclaration.AddAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.AddAccessor.Body.RBraceToken.StartLocation.Line) {
671
 
                                                EnforceBraceStyle(policy.EventAddBraceStyle, eventDeclaration.AddAccessor.Body.LBraceToken, eventDeclaration.AddAccessor.Body.RBraceToken);
672
 
                                        } else {
673
 
                                                nextStatementIndent = " ";
674
 
                                        }
675
 
                                        
676
 
                                        VisitBlockWithoutFixingBraces(eventDeclaration.AddAccessor.Body, policy.IndentBlocks);
677
 
                                }
678
 
                        }
679
 
                        
680
 
                        if (!eventDeclaration.RemoveAccessor.IsNull) {
681
 
                                FixIndentation(eventDeclaration.RemoveAccessor.StartLocation);
682
 
                                if (!eventDeclaration.RemoveAccessor.Body.IsNull) {
683
 
                                        if (!policy.AllowEventRemoveBlockInline || eventDeclaration.RemoveAccessor.Body.LBraceToken.StartLocation.Line != eventDeclaration.RemoveAccessor.Body.RBraceToken.StartLocation.Line) {
684
 
                                                EnforceBraceStyle(policy.EventRemoveBraceStyle, eventDeclaration.RemoveAccessor.Body.LBraceToken, eventDeclaration.RemoveAccessor.Body.RBraceToken);
685
 
                                        } else {
686
 
                                                nextStatementIndent = " ";
687
 
                                        }
688
 
                                        VisitBlockWithoutFixingBraces(eventDeclaration.RemoveAccessor.Body, policy.IndentBlocks);
689
 
                                }
690
 
                        }
691
 
                        
692
 
                        if (policy.IndentEventBody) {
693
 
                                curIndent.Pop ();
694
 
                        }
695
 
                        
696
 
                        if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) {
697
 
                                EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields);
698
 
                        } else if (IsMember(eventDeclaration.NextSibling)) {
699
 
                                EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers);
700
 
                        }
701
 
                }
702
 
 
703
 
                public override void VisitEventDeclaration(EventDeclaration eventDeclaration)
704
 
                {
705
 
                        FormatAttributedNode(eventDeclaration);
706
 
                        if (eventDeclaration.NextSibling is EventDeclaration && IsSimpleEvent(eventDeclaration) && IsSimpleEvent(eventDeclaration.NextSibling)) {
707
 
                                EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenEventFields);
708
 
                        } else if (IsMember(eventDeclaration.NextSibling)) {
709
 
                                EnsureBlankLinesAfter(eventDeclaration, policy.BlankLinesBetweenMembers);
710
 
                        }
711
 
                        
712
 
                        var lastLoc = eventDeclaration.StartLocation;
713
 
                        curIndent.Push(IndentType.Block);
714
 
                        foreach (var initializer in eventDeclaration.Variables) {
715
 
                                if (lastLoc.Line != initializer.StartLocation.Line) {
716
 
                                        FixStatementIndentation(initializer.StartLocation);
717
 
                                        lastLoc = initializer.StartLocation;
718
 
                                }
719
 
                                initializer.AcceptVisitor(this);
720
 
                        }
721
 
                        curIndent.Pop ();
722
 
                }
723
 
 
724
 
                public override void VisitAccessor(Accessor accessor)
725
 
                {
726
 
                        FixIndentationForceNewLine(accessor.StartLocation);
727
 
                        base.VisitAccessor(accessor);
728
 
                }
729
 
 
730
 
                public override void VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
731
 
                {
732
 
                        FormatAttributedNode(fieldDeclaration);
733
 
                        fieldDeclaration.ReturnType.AcceptVisitor(this);
734
 
                        FormatCommas(fieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma);
735
 
                        if (fieldDeclaration.NextSibling is FieldDeclaration || fieldDeclaration.NextSibling is FixedFieldDeclaration) {
736
 
                                EnsureBlankLinesAfter(fieldDeclaration, policy.BlankLinesBetweenFields);
737
 
                        } else if (IsMember(fieldDeclaration.NextSibling)) {
738
 
                                EnsureBlankLinesAfter(fieldDeclaration, policy.BlankLinesBetweenMembers);
739
 
                        }
740
 
                        
741
 
                        var lastLoc = fieldDeclaration.StartLocation;
742
 
                        curIndent.Push(IndentType.Block);
743
 
                        foreach (var initializer in fieldDeclaration.Variables) {
744
 
                                if (lastLoc.Line != initializer.StartLocation.Line) {
745
 
                                        FixStatementIndentation(initializer.StartLocation);
746
 
                                        lastLoc = initializer.StartLocation;
747
 
                                }
748
 
                                initializer.AcceptVisitor(this);
749
 
                        }
750
 
                        curIndent.Pop ();
751
 
                }
752
 
 
753
 
                public override void VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
754
 
                {
755
 
                        FormatAttributedNode(fixedFieldDeclaration);
756
 
                        FormatCommas(fixedFieldDeclaration, policy.SpaceBeforeFieldDeclarationComma, policy.SpaceAfterFieldDeclarationComma);
757
 
                        if (fixedFieldDeclaration.NextSibling is FieldDeclaration || fixedFieldDeclaration.NextSibling is FixedFieldDeclaration) {
758
 
                                EnsureBlankLinesAfter(fixedFieldDeclaration, policy.BlankLinesBetweenFields);
759
 
                        } else if (IsMember(fixedFieldDeclaration.NextSibling)) {
760
 
                                EnsureBlankLinesAfter(fixedFieldDeclaration, policy.BlankLinesBetweenMembers);
761
 
                        }
762
 
                        
763
 
                        var lastLoc = fixedFieldDeclaration.StartLocation;
764
 
                        curIndent.Push(IndentType.Block);
765
 
                        foreach (var initializer in fixedFieldDeclaration.Variables) {
766
 
                                if (lastLoc.Line != initializer.StartLocation.Line) {
767
 
                                        FixStatementIndentation(initializer.StartLocation);
768
 
                                        lastLoc = initializer.StartLocation;
769
 
                                }
770
 
                                initializer.AcceptVisitor(this);
771
 
                        }
772
 
                        curIndent.Pop ();
773
 
                }
774
 
 
775
 
                public override void VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
776
 
                {
777
 
                        FormatAttributedNode(enumMemberDeclaration);
778
 
                        base.VisitEnumMemberDeclaration(enumMemberDeclaration);
779
 
                }
780
 
 
781
 
                public override void VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
782
 
                {
783
 
                        FormatAttributedNode(delegateDeclaration);
784
 
                        
785
 
                        ForceSpacesBefore(delegateDeclaration.LParToken, policy.SpaceBeforeDelegateDeclarationParentheses);
786
 
                        if (delegateDeclaration.Parameters.Any()) {
787
 
                                ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceWithinDelegateDeclarationParentheses);
788
 
                                ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceWithinDelegateDeclarationParentheses);
789
 
                        } else {
790
 
                                ForceSpacesAfter(delegateDeclaration.LParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses);
791
 
                                ForceSpacesBefore(delegateDeclaration.RParToken, policy.SpaceBetweenEmptyDelegateDeclarationParentheses);
792
 
                        }
793
 
                        FormatCommas(delegateDeclaration, policy.SpaceBeforeDelegateDeclarationParameterComma, policy.SpaceAfterDelegateDeclarationParameterComma);
794
 
 
795
 
                        if (delegateDeclaration.NextSibling is TypeDeclaration || delegateDeclaration.NextSibling is DelegateDeclaration) {
796
 
                                EnsureBlankLinesAfter(delegateDeclaration, policy.BlankLinesBetweenTypes);
797
 
                        } else if (IsMember(delegateDeclaration.NextSibling)) {
798
 
                                EnsureBlankLinesAfter(delegateDeclaration, policy.BlankLinesBetweenMembers);
799
 
                        }
800
 
 
801
 
                        base.VisitDelegateDeclaration(delegateDeclaration);
802
 
                }
803
 
 
804
 
                static bool IsMember(AstNode nextSibling)
805
 
                {
806
 
                        return nextSibling != null && nextSibling.NodeType == NodeType.Member;
807
 
                }
808
 
                
809
 
                void FormatAttributedNode(AstNode node)
810
 
                {
811
 
                        if (node == null) {
812
 
                                return;
813
 
                        }
814
 
                        AstNode child = node.FirstChild;
815
 
                        while (child != null && child is AttributeSection) {
816
 
                                FixIndentationForceNewLine(child.StartLocation);
817
 
                                child = child.NextSibling;
818
 
                        }
819
 
                        if (child != null) {
820
 
                                FixIndentationForceNewLine(child.StartLocation);
821
 
                        }
822
 
                }
823
 
 
824
 
 
825
 
                void FormatParameters(AstNode node)
826
 
                {
827
 
                        Wrapping methodCallArgumentWrapping;
828
 
                        bool newLineAferMethodCallOpenParentheses;
829
 
                        bool methodClosingParenthesesOnNewLine;
830
 
                        bool spaceWithinMethodCallParentheses;
831
 
                        bool spaceAfterMethodCallParameterComma;
832
 
                        bool spaceBeforeMethodCallParameterComma;
833
 
                                
834
 
                        CSharpTokenNode rParToken;
835
 
                        AstNodeCollection<ParameterDeclaration> parameters;
836
 
 
837
 
                        var constructorDeclaration = node as ConstructorDeclaration;
838
 
                        if (constructorDeclaration != null) {
839
 
                                methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
840
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
841
 
                                methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
842
 
 
843
 
                                spaceWithinMethodCallParentheses = policy.SpaceWithinConstructorDeclarationParentheses;
844
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterConstructorDeclarationParameterComma;
845
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeConstructorDeclarationParameterComma;
846
 
                                rParToken = constructorDeclaration.RParToken;
847
 
                                parameters = constructorDeclaration.Parameters;
848
 
                        } else if (node is IndexerDeclaration) {
849
 
                                var indexer = (IndexerDeclaration)node;
850
 
                                methodCallArgumentWrapping = policy.IndexerDeclarationParameterWrapping;
851
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerDeclarationOpenBracket;
852
 
                                methodClosingParenthesesOnNewLine = policy.IndexerDeclarationClosingBracketOnNewLine;
853
 
 
854
 
                                spaceWithinMethodCallParentheses = policy.SpaceWithinIndexerDeclarationBracket;
855
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterIndexerDeclarationParameterComma;
856
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeIndexerDeclarationParameterComma;
857
 
                                rParToken = indexer.RBracketToken;
858
 
                                parameters = indexer.Parameters;
859
 
                        } else if (node is OperatorDeclaration) {
860
 
                                var op = (OperatorDeclaration)node;
861
 
                                methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
862
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
863
 
                                methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
864
 
                                spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
865
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
866
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
867
 
                                rParToken = op.RParToken;
868
 
                                parameters = op.Parameters;
869
 
                        } else {
870
 
                                var methodDeclaration = node as MethodDeclaration;
871
 
                                methodCallArgumentWrapping = policy.MethodDeclarationParameterWrapping;
872
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodDeclarationOpenParentheses;
873
 
                                methodClosingParenthesesOnNewLine = policy.MethodDeclarationClosingParenthesesOnNewLine;
874
 
                                spaceWithinMethodCallParentheses = policy.SpaceWithinMethodDeclarationParentheses;
875
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodDeclarationParameterComma;
876
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodDeclarationParameterComma;
877
 
                                rParToken = methodDeclaration.RParToken;
878
 
                                parameters = methodDeclaration.Parameters;
879
 
                        }
880
 
                        if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
881
 
                                methodCallArgumentWrapping = Wrapping.DoNotChange;
882
 
 
883
 
                        bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, parameters.Count);
884
 
                        if (wrapMethodCall && parameters.Any()) {
885
 
                                if (newLineAferMethodCallOpenParentheses) {
886
 
                                        curIndent.Push(IndentType.Continuation);
887
 
                                        foreach (var arg in parameters) {
888
 
                                                FixStatementIndentation(arg.StartLocation);
889
 
                                        }
890
 
                                        curIndent.Pop();
891
 
                                } else {
892
 
                                        int extraSpaces = parameters.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
893
 
                                        curIndent.ExtraSpaces += extraSpaces;
894
 
                                        foreach (var arg in parameters.Skip(1)) {
895
 
                                                FixStatementIndentation(arg.StartLocation);
896
 
                                        }
897
 
                                        curIndent.ExtraSpaces -= extraSpaces;
898
 
                                }
899
 
                                if (!rParToken.IsNull) {
900
 
                                        if (methodClosingParenthesesOnNewLine) {
901
 
                                                FixStatementIndentation(rParToken.StartLocation);
902
 
                                        } else {
903
 
                                                ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
904
 
                                        }
905
 
                                }
906
 
                        } else {
907
 
                                foreach (var arg in parameters) {
908
 
                                        if (arg.PrevSibling != null) {
909
 
                                                if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
910
 
                                                        ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
911
 
                                                } else {
912
 
                                                        ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
913
 
                                                }
914
 
                                        }
915
 
                                        arg.AcceptVisitor(this);
916
 
                                }
917
 
                                if (!rParToken.IsNull) {
918
 
                                        if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
919
 
                                                ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
920
 
                                        } else {
921
 
                                                bool sameLine = rParToken.GetPrevNode().StartLocation.Line == rParToken.StartLocation.Line;
922
 
                                                if (sameLine) {
923
 
                                                        ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
924
 
                                                } else {
925
 
                                                        FixStatementIndentation(rParToken.StartLocation);
926
 
                                                }
927
 
                                        }
928
 
                                }
929
 
                        }
930
 
                        if (!rParToken.IsNull) {
931
 
                                foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
932
 
                                        ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
933
 
                                }
934
 
                        }
935
 
                }
936
 
 
937
 
                public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration)
938
 
                {
939
 
                        FormatAttributedNode(methodDeclaration);
940
 
                        
941
 
                        ForceSpacesBefore(methodDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
942
 
                        if (methodDeclaration.Parameters.Any()) {
943
 
                                ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
944
 
                                FormatParameters(methodDeclaration);
945
 
                        } else {
946
 
                                ForceSpacesAfter(methodDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
947
 
                                ForceSpacesBefore(methodDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
948
 
                        }
949
 
 
950
 
                        if (!methodDeclaration.Body.IsNull) {
951
 
                                EnforceBraceStyle(policy.MethodBraceStyle, methodDeclaration.Body.LBraceToken, methodDeclaration.Body.RBraceToken);
952
 
                                VisitBlockWithoutFixingBraces(methodDeclaration.Body, policy.IndentMethodBody);
953
 
                        }
954
 
                        if (IsMember(methodDeclaration.NextSibling)) {
955
 
                                EnsureBlankLinesAfter(methodDeclaration, policy.BlankLinesBetweenMembers);
956
 
                        }
957
 
                }
958
 
 
959
 
                public override void VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
960
 
                {
961
 
                        FormatAttributedNode(operatorDeclaration);
962
 
                        
963
 
                        ForceSpacesBefore(operatorDeclaration.LParToken, policy.SpaceBeforeMethodDeclarationParentheses);
964
 
                        if (operatorDeclaration.Parameters.Any()) {
965
 
                                ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceWithinMethodDeclarationParentheses);
966
 
                                FormatParameters(operatorDeclaration);
967
 
                        } else {
968
 
                                ForceSpacesAfter(operatorDeclaration.LParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
969
 
                                ForceSpacesBefore(operatorDeclaration.RParToken, policy.SpaceBetweenEmptyMethodDeclarationParentheses);
970
 
                        }
971
 
 
972
 
                        if (!operatorDeclaration.Body.IsNull) {
973
 
                                EnforceBraceStyle(policy.MethodBraceStyle, operatorDeclaration.Body.LBraceToken, operatorDeclaration.Body.RBraceToken);
974
 
                                VisitBlockWithoutFixingBraces(operatorDeclaration.Body, policy.IndentMethodBody);
975
 
                        }
976
 
                        if (IsMember(operatorDeclaration.NextSibling)) {
977
 
                                EnsureBlankLinesAfter(operatorDeclaration, policy.BlankLinesBetweenMembers);
978
 
                        }
979
 
                }
980
 
 
981
 
                public override void VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
982
 
                {
983
 
                        FormatAttributedNode(constructorDeclaration);
984
 
                        
985
 
                        ForceSpacesBefore(constructorDeclaration.LParToken, policy.SpaceBeforeConstructorDeclarationParentheses);
986
 
                        if (constructorDeclaration.Parameters.Any()) {
987
 
                                ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceWithinConstructorDeclarationParentheses);
988
 
                                FormatParameters(constructorDeclaration);
989
 
                        } else {
990
 
                                ForceSpacesAfter(constructorDeclaration.LParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
991
 
                                ForceSpacesBefore(constructorDeclaration.RParToken, policy.SpaceBetweenEmptyConstructorDeclarationParentheses);
992
 
                        }
993
 
 
994
 
                        if (!constructorDeclaration.Body.IsNull) {
995
 
                                EnforceBraceStyle(policy.ConstructorBraceStyle, constructorDeclaration.Body.LBraceToken, constructorDeclaration.Body.RBraceToken);
996
 
                                VisitBlockWithoutFixingBraces(constructorDeclaration.Body, policy.IndentMethodBody);
997
 
                        }
998
 
                        if (IsMember(constructorDeclaration.NextSibling)) {
999
 
                                EnsureBlankLinesAfter(constructorDeclaration, policy.BlankLinesBetweenMembers);
1000
 
                        }
1001
 
                }
1002
 
 
1003
 
                public override void VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
1004
 
                {
1005
 
                        FormatAttributedNode(destructorDeclaration);
1006
 
                        
1007
 
                        CSharpTokenNode lParen = destructorDeclaration.LParToken;
1008
 
                        int offset = this.document.GetOffset(lParen.StartLocation);
1009
 
                        ForceSpaceBefore(offset, policy.SpaceBeforeConstructorDeclarationParentheses);
1010
 
                        
1011
 
                        if (!destructorDeclaration.Body.IsNull) {
1012
 
                                EnforceBraceStyle(policy.DestructorBraceStyle, destructorDeclaration.Body.LBraceToken, destructorDeclaration.Body.RBraceToken);
1013
 
                                VisitBlockWithoutFixingBraces(destructorDeclaration.Body, policy.IndentMethodBody);
1014
 
                        }
1015
 
                        if (IsMember(destructorDeclaration.NextSibling)) {
1016
 
                                EnsureBlankLinesAfter(destructorDeclaration, policy.BlankLinesBetweenMembers);
1017
 
                        }
1018
 
                }
1019
 
 
1020
 
                #region Statements
1021
 
                public override void VisitExpressionStatement(ExpressionStatement expressionStatement)
1022
 
                {
1023
 
                        base.VisitExpressionStatement(expressionStatement);
1024
 
                        FixSemicolon(expressionStatement.SemicolonToken);
1025
 
                }
1026
 
 
1027
 
                void VisitBlockWithoutFixingBraces(BlockStatement blockStatement, bool indent)
1028
 
                {
1029
 
                        if (indent) {
1030
 
                                curIndent.Push(IndentType.Block);
1031
 
                        }
1032
 
                        foreach (var child in blockStatement.Children) {
1033
 
                                if (child.Role == Roles.LBrace || child.Role == Roles.RBrace) {
1034
 
                                        continue;
1035
 
                                }
1036
 
                                if (child is Statement) {
1037
 
                                        FixStatementIndentation(child.StartLocation);
1038
 
                                        child.AcceptVisitor(this);
1039
 
                                } else if (child is Comment) {
1040
 
                                        child.AcceptVisitor(this);
1041
 
                                } else {
1042
 
                                        // pre processor directives at line start, if they are there.
1043
 
                                        if (child.StartLocation.Column > 1)
1044
 
                                                FixStatementIndentation(child.StartLocation);
1045
 
                                }
1046
 
                        }
1047
 
                        if (indent) {
1048
 
                                curIndent.Pop ();
1049
 
                        }
1050
 
                }
1051
 
 
1052
 
                public override void VisitBlockStatement(BlockStatement blockStatement)
1053
 
                {
1054
 
                        FixIndentation(blockStatement.StartLocation);
1055
 
                        VisitBlockWithoutFixingBraces(blockStatement, policy.IndentBlocks);
1056
 
                        FixIndentation(blockStatement.EndLocation, -1);
1057
 
                }
1058
 
 
1059
 
                public override void VisitComment(Comment comment)
1060
 
                {
1061
 
                        if (comment.StartsLine && !HadErrors && (!policy.KeepCommentsAtFirstColumn || comment.StartLocation.Column > 1)) {
1062
 
                                FixIndentation(comment.StartLocation);
1063
 
                        }
1064
 
                }
1065
 
 
1066
 
                public override void VisitBreakStatement(BreakStatement breakStatement)
1067
 
                {
1068
 
                        FixSemicolon(breakStatement.SemicolonToken);
1069
 
                }
1070
 
 
1071
 
                public override void VisitCheckedStatement(CheckedStatement checkedStatement)
1072
 
                {
1073
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, checkedStatement.Body);
1074
 
                }
1075
 
 
1076
 
                public override void VisitContinueStatement(ContinueStatement continueStatement)
1077
 
                {
1078
 
                        FixSemicolon(continueStatement.SemicolonToken);
1079
 
                }
1080
 
 
1081
 
                public override void VisitEmptyStatement(EmptyStatement emptyStatement)
1082
 
                {
1083
 
                        // Empty
1084
 
                }
1085
 
 
1086
 
                public override void VisitFixedStatement(FixedStatement fixedStatement)
1087
 
                {
1088
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, fixedStatement.EmbeddedStatement);
1089
 
                }
1090
 
 
1091
 
                public override void VisitForeachStatement(ForeachStatement foreachStatement)
1092
 
                {
1093
 
                        ForceSpacesBefore(foreachStatement.LParToken, policy.SpaceBeforeForeachParentheses);
1094
 
 
1095
 
                        ForceSpacesAfter(foreachStatement.LParToken, policy.SpacesWithinForeachParentheses);
1096
 
                        ForceSpacesBefore(foreachStatement.RParToken, policy.SpacesWithinForeachParentheses);
1097
 
 
1098
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.ForEachBraceForcement, foreachStatement.EmbeddedStatement);
1099
 
                }
1100
 
 
1101
 
                void FixEmbeddedStatment(BraceStyle braceStyle, BraceForcement braceForcement, AstNode node)
1102
 
                {
1103
 
                        FixEmbeddedStatment(braceStyle, braceForcement, null, false, node);
1104
 
                }
1105
 
 
1106
 
                void FixEmbeddedStatment(BraceStyle braceStyle, BraceForcement braceForcement, CSharpTokenNode token, bool allowInLine, AstNode node, bool statementAlreadyIndented = false)
1107
 
                {
1108
 
                        if (node == null) {
1109
 
                                return;
1110
 
                        }
1111
 
                        bool isBlock = node is BlockStatement;
1112
 
                        TextReplaceAction beginBraceAction = null;
1113
 
                        TextReplaceAction endBraceAction = null;
1114
 
 
1115
 
                        switch (braceForcement) {
1116
 
                                case BraceForcement.DoNotChange:
1117
 
                                        //nothing
1118
 
                                        break;
1119
 
                                case BraceForcement.AddBraces:
1120
 
                                        if (!isBlock) {
1121
 
                                                AstNode n = node.Parent.GetCSharpNodeBefore(node);
1122
 
                                                int start = document.GetOffset(n.EndLocation);
1123
 
                                                string startBrace = "";
1124
 
                                                switch (braceStyle) {
1125
 
                                                        case BraceStyle.EndOfLineWithoutSpace:
1126
 
                                                                startBrace = "{";
1127
 
                                                                break;
1128
 
                                                        case BraceStyle.BannerStyle:
1129
 
                                                        case BraceStyle.EndOfLine:
1130
 
                                                                startBrace = " {";
1131
 
                                                                break;
1132
 
                                                        case BraceStyle.NextLine:
1133
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "{";
1134
 
                                                                break;
1135
 
                                                        case BraceStyle.NextLineShifted2:
1136
 
                                                        case BraceStyle.NextLineShifted:
1137
 
                                                                curIndent.Push(IndentType.Block);
1138
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "{";
1139
 
                                                                curIndent.Pop();
1140
 
                                                                break;
1141
 
                                                }
1142
 
                                                beginBraceAction = AddChange(start, 0, startBrace);
1143
 
                                        }
1144
 
                                        break;
1145
 
                                case BraceForcement.RemoveBraces:
1146
 
                                        if (isBlock) {
1147
 
                                                BlockStatement block = node as BlockStatement;
1148
 
                                                if (block.Statements.Count() == 1) {
1149
 
                                                        int offset1 = document.GetOffset(node.StartLocation);
1150
 
                                                        int start = SearchWhitespaceStart(offset1);
1151
 
                                                        
1152
 
                                                        int offset2 = document.GetOffset(node.EndLocation);
1153
 
                                                        int end = SearchWhitespaceStart(offset2 - 1);
1154
 
                                                        
1155
 
                                                        beginBraceAction = AddChange(start, offset1 - start + 1, null);
1156
 
                                                        endBraceAction = AddChange(end + 1, offset2 - end, null);
1157
 
                                                        node = block.FirstChild;
1158
 
                                                        isBlock = false;
1159
 
                                                }
1160
 
                                        }
1161
 
                                        break;
1162
 
                        }
1163
 
                        if (isBlock) {
1164
 
                                BlockStatement block = node as BlockStatement;
1165
 
                                if (allowInLine && block.StartLocation.Line == block.EndLocation.Line && block.Statements.Count() <= 1) {
1166
 
                                        if (block.Statements.Count() == 1) {
1167
 
                                                nextStatementIndent = " ";
1168
 
                                        }
1169
 
                                } else {
1170
 
                                        if (!statementAlreadyIndented) {
1171
 
                                                EnforceBraceStyle(braceStyle, block.LBraceToken, block.RBraceToken);
1172
 
                                        }
1173
 
                                }
1174
 
                                if (braceStyle == BraceStyle.NextLineShifted2) {
1175
 
                                        curIndent.Push(IndentType.Block);
1176
 
                                }
1177
 
                        } else {
1178
 
                                if (allowInLine && token.StartLocation.Line == node.EndLocation.Line) {
1179
 
                                        nextStatementIndent = " ";
1180
 
                                }
1181
 
                        }
1182
 
                        if (policy.IndentBlocks && !(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement || policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement)) { 
1183
 
                                curIndent.Push(IndentType.Block);
1184
 
                        }
1185
 
                        if (isBlock) {
1186
 
                                VisitBlockWithoutFixingBraces((BlockStatement)node, false);
1187
 
                        } else {
1188
 
                                if (!statementAlreadyIndented) {
1189
 
                                        FixStatementIndentation(node.StartLocation);
1190
 
                                }
1191
 
                                node.AcceptVisitor(this);
1192
 
                        }
1193
 
                        if (policy.IndentBlocks && !(policy.AlignEmbeddedIfStatements && node is IfElseStatement && node.Parent is IfElseStatement || policy.AlignEmbeddedUsingStatements && node is UsingStatement && node.Parent is UsingStatement)) { 
1194
 
                                curIndent.Pop();
1195
 
                        }
1196
 
                        switch (braceForcement) {
1197
 
                                case BraceForcement.DoNotChange:
1198
 
                                        break;
1199
 
                                case BraceForcement.AddBraces:
1200
 
                                        if (!isBlock) {
1201
 
                                                int offset = document.GetOffset(node.EndLocation);
1202
 
                                                if (!char.IsWhiteSpace(document.GetCharAt(offset))) {
1203
 
                                                        offset++;
1204
 
                                                }
1205
 
                                                string startBrace = "";
1206
 
                                                switch (braceStyle) {
1207
 
                                                        case BraceStyle.DoNotChange:
1208
 
                                                                startBrace = null;
1209
 
                                                                break;
1210
 
                                                        case BraceStyle.EndOfLineWithoutSpace:
1211
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "}";
1212
 
                                                                break;
1213
 
                                                        case BraceStyle.EndOfLine:
1214
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "}";
1215
 
                                                                break;
1216
 
                                                        case BraceStyle.NextLine:
1217
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "}";
1218
 
                                                                break;
1219
 
                                                        case BraceStyle.BannerStyle:
1220
 
                                                        case BraceStyle.NextLineShifted2:
1221
 
                                                        case BraceStyle.NextLineShifted:
1222
 
                                                                curIndent.Push(IndentType.Block);
1223
 
                                                                startBrace = this.options.EolMarker + curIndent.IndentString + "}";
1224
 
                                                                curIndent.Pop ();
1225
 
                                                                break;
1226
 
 
1227
 
                                                }
1228
 
                                                if (startBrace != null) {
1229
 
                                                        endBraceAction = AddChange(offset, 0, startBrace);
1230
 
                                                }
1231
 
                                        }
1232
 
                                        break;
1233
 
                        }
1234
 
                        if (beginBraceAction != null && endBraceAction != null) {
1235
 
                                beginBraceAction.DependsOn = endBraceAction;
1236
 
                                endBraceAction.DependsOn = beginBraceAction;
1237
 
                        }
1238
 
                }
1239
 
 
1240
 
                void EnforceBraceStyle(BraceStyle braceStyle, AstNode lbrace, AstNode rbrace)
1241
 
                {
1242
 
                        if (lbrace.IsNull || rbrace.IsNull) {
1243
 
                                return;
1244
 
                        }
1245
 
                        
1246
 
                        //                      LineSegment lbraceLineSegment = data.Document.GetLine (lbrace.StartLocation.Line);
1247
 
                        int lbraceOffset = document.GetOffset(lbrace.StartLocation);
1248
 
                        
1249
 
                        //                      LineSegment rbraceLineSegment = data.Document.GetLine (rbrace.StartLocation.Line);
1250
 
                        int rbraceOffset = document.GetOffset(rbrace.StartLocation);
1251
 
                        int whitespaceStart = SearchWhitespaceStart(lbraceOffset);
1252
 
                        int whitespaceEnd = SearchWhitespaceLineStart(rbraceOffset);
1253
 
                        string startIndent = "";
1254
 
                        string endIndent = "";
1255
 
                        switch (braceStyle) {
1256
 
                                case BraceStyle.DoNotChange:
1257
 
                                        startIndent = endIndent = null;
1258
 
                                        break;
1259
 
                                case BraceStyle.EndOfLineWithoutSpace:
1260
 
                                        startIndent = "";
1261
 
                                        endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString;
1262
 
                                        break;
1263
 
                                case BraceStyle.BannerStyle:
1264
 
                                        var prevNode = lbrace.GetPrevNode();
1265
 
                                        if (prevNode is Comment) {
1266
 
                                                // delete old bracket
1267
 
                                                AddChange(whitespaceStart, lbraceOffset - whitespaceStart + 1, "");
1268
 
                                        
1269
 
                                                while (prevNode is Comment) {
1270
 
                                                        prevNode = prevNode.GetPrevNode();
1271
 
                                                }
1272
 
                                                whitespaceStart = document.GetOffset(prevNode.EndLocation);
1273
 
                                                lbraceOffset = whitespaceStart;
1274
 
                                                startIndent = " {";
1275
 
                                        } else {
1276
 
                                                startIndent = " ";
1277
 
                                        }
1278
 
                                        curIndent.Push(IndentType.Block);
1279
 
                                        endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString;
1280
 
                                        curIndent.Pop();
1281
 
                                        break;
1282
 
                                case BraceStyle.EndOfLine:
1283
 
                                        prevNode = lbrace.GetPrevNode();
1284
 
                                        if (prevNode is Comment) {
1285
 
                                                // delete old bracket
1286
 
                                                AddChange(whitespaceStart, lbraceOffset - whitespaceStart + 1, "");
1287
 
                                        
1288
 
                                                while (prevNode is Comment) {
1289
 
                                                        prevNode = prevNode.GetPrevNode();
1290
 
                                                }
1291
 
                                                whitespaceStart = document.GetOffset(prevNode.EndLocation);
1292
 
                                                lbraceOffset = whitespaceStart;
1293
 
                                                startIndent = " {";
1294
 
                                        } else {
1295
 
                                                startIndent = " ";
1296
 
                                        }
1297
 
                                        endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString;
1298
 
                                        break;
1299
 
                                case BraceStyle.NextLine:
1300
 
                                        startIndent = this.options.EolMarker + curIndent.IndentString;
1301
 
                                        endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString;
1302
 
                                        break;
1303
 
                                case BraceStyle.NextLineShifted2:
1304
 
                                case BraceStyle.NextLineShifted:
1305
 
                                        curIndent.Push(IndentType.Block);
1306
 
                                        startIndent = this.options.EolMarker + curIndent.IndentString;
1307
 
                                        endIndent = IsLineIsEmptyUpToEol(rbraceOffset) ? curIndent.IndentString : this.options.EolMarker + curIndent.IndentString;
1308
 
                                        curIndent.Pop ();
1309
 
                                        break;
1310
 
                        }
1311
 
                        
1312
 
                        if (lbraceOffset > 0 && startIndent != null) {
1313
 
                                AddChange(whitespaceStart, lbraceOffset - whitespaceStart, startIndent);
1314
 
                        }
1315
 
                        if (rbraceOffset > 0 && endIndent != null) {
1316
 
                                AddChange(whitespaceEnd, rbraceOffset - whitespaceEnd, endIndent);
1317
 
                        }
1318
 
                }
1319
 
 
1320
 
                TextReplaceAction AddChange(int offset, int removedChars, string insertedText)
1321
 
                {
1322
 
                        if (removedChars == 0 && string.IsNullOrEmpty (insertedText))
1323
 
                                return null;
1324
 
                        var action = new TextReplaceAction (offset, removedChars, insertedText);
1325
 
                        changes.Add(action);
1326
 
                        return action;
1327
 
                }
1328
 
 
1329
 
                public bool IsLineIsEmptyUpToEol(TextLocation startLocation)
1330
 
                {
1331
 
                        return IsLineIsEmptyUpToEol(document.GetOffset(startLocation) - 1);
1332
 
                }
1333
 
 
1334
 
                bool IsLineIsEmptyUpToEol(int startOffset)
1335
 
                {
1336
 
                        for (int offset = startOffset - 1; offset >= 0; offset--) {
1337
 
                                char ch = document.GetCharAt(offset);
1338
 
                                if (ch != ' ' && ch != '\t') {
1339
 
                                        return ch == '\n' || ch == '\r';
1340
 
                                }
1341
 
                        }
1342
 
                        return true;
1343
 
                }
1344
 
 
1345
 
                int SearchWhitespaceStart(int startOffset)
1346
 
                {
1347
 
                        if (startOffset < 0) {
1348
 
                                throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset);
1349
 
                        }
1350
 
                        for (int offset = startOffset - 1; offset >= 0; offset--) {
1351
 
                                char ch = document.GetCharAt(offset);
1352
 
                                if (!Char.IsWhiteSpace(ch)) {
1353
 
                                        return offset + 1;
1354
 
                                }
1355
 
                        }
1356
 
                        return 0;
1357
 
                }
1358
 
 
1359
 
                int SearchWhitespaceEnd(int startOffset)
1360
 
                {
1361
 
                        if (startOffset > document.TextLength) {
1362
 
                                throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset);
1363
 
                        }
1364
 
                        for (int offset = startOffset + 1; offset < document.TextLength; offset++) {
1365
 
                                char ch = document.GetCharAt(offset);
1366
 
                                if (!Char.IsWhiteSpace(ch)) {
1367
 
                                        return offset + 1;
1368
 
                                }
1369
 
                        }
1370
 
                        return document.TextLength - 1;
1371
 
                }
1372
 
 
1373
 
                int SearchWhitespaceLineStart(int startOffset)
1374
 
                {
1375
 
                        if (startOffset < 0) {
1376
 
                                throw new ArgumentOutOfRangeException ("startoffset", "value : " + startOffset);
1377
 
                        }
1378
 
                        for (int offset = startOffset - 1; offset >= 0; offset--) {
1379
 
                                char ch = document.GetCharAt(offset);
1380
 
                                if (ch != ' ' && ch != '\t') {
1381
 
                                        return offset + 1;
1382
 
                                }
1383
 
                        }
1384
 
                        return 0;
1385
 
                }
1386
 
 
1387
 
                public override void VisitForStatement(ForStatement forStatement)
1388
 
                {
1389
 
                        foreach (AstNode node in forStatement.Children) {
1390
 
                                if (node.Role == Roles.Semicolon) {
1391
 
                                        if (node.NextSibling is CSharpTokenNode || node.NextSibling is EmptyStatement) {
1392
 
                                                continue;
1393
 
                                        }
1394
 
                                        ForceSpacesBefore(node, policy.SpaceBeforeForSemicolon);
1395
 
                                        ForceSpacesAfter(node, policy.SpaceAfterForSemicolon);
1396
 
                                }
1397
 
                        }
1398
 
 
1399
 
                        ForceSpacesBefore(forStatement.LParToken, policy.SpaceBeforeForParentheses);
1400
 
 
1401
 
                        ForceSpacesAfter(forStatement.LParToken, policy.SpacesWithinForParentheses);
1402
 
                        ForceSpacesBefore(forStatement.RParToken, policy.SpacesWithinForParentheses);
1403
 
 
1404
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.ForBraceForcement, forStatement.EmbeddedStatement);
1405
 
                }
1406
 
 
1407
 
                public override void VisitGotoStatement(GotoStatement gotoStatement)
1408
 
                {
1409
 
                        VisitChildren(gotoStatement);
1410
 
                        FixSemicolon(gotoStatement.SemicolonToken);
1411
 
                }
1412
 
 
1413
 
                public override void VisitIfElseStatement(IfElseStatement ifElseStatement)
1414
 
                {
1415
 
                        ForceSpacesBefore(ifElseStatement.LParToken, policy.SpaceBeforeIfParentheses);
1416
 
 
1417
 
                        ForceSpacesAfter(ifElseStatement.LParToken, policy.SpacesWithinIfParentheses);
1418
 
                        ForceSpacesBefore(ifElseStatement.RParToken, policy.SpacesWithinIfParentheses);
1419
 
 
1420
 
                        if (!(ifElseStatement.Parent is IfElseStatement && ((IfElseStatement)ifElseStatement.Parent).FalseStatement == ifElseStatement)) {
1421
 
                                FixStatementIndentation(ifElseStatement.StartLocation);
1422
 
                        }
1423
 
                        
1424
 
                        if (!ifElseStatement.Condition.IsNull) {
1425
 
                                ifElseStatement.Condition.AcceptVisitor(this);
1426
 
                        }
1427
 
                        
1428
 
                        if (!ifElseStatement.TrueStatement.IsNull) {
1429
 
                                FixEmbeddedStatment(policy.StatementBraceStyle, policy.IfElseBraceForcement, ifElseStatement.IfToken, policy.AllowIfBlockInline, ifElseStatement.TrueStatement);
1430
 
                        }
1431
 
                        
1432
 
                        if (!ifElseStatement.FalseStatement.IsNull) {
1433
 
                                var placeElseOnNewLine = policy.ElseNewLinePlacement;
1434
 
                                if (!(ifElseStatement.TrueStatement is BlockStatement) && policy.IfElseBraceForcement != BraceForcement.AddBraces)
1435
 
                                        placeElseOnNewLine = NewLinePlacement.NewLine;
1436
 
                                PlaceOnNewLine(placeElseOnNewLine, ifElseStatement.ElseToken);
1437
 
                                var forcement = policy.IfElseBraceForcement;
1438
 
                                if (ifElseStatement.FalseStatement is IfElseStatement) {
1439
 
                                        forcement = BraceForcement.DoNotChange;
1440
 
                                        PlaceOnNewLine(policy.ElseIfNewLinePlacement, ((IfElseStatement)ifElseStatement.FalseStatement).IfToken);
1441
 
                                }
1442
 
                                FixEmbeddedStatment(policy.StatementBraceStyle, forcement, ifElseStatement.ElseToken, policy.AllowIfBlockInline, ifElseStatement.FalseStatement, ifElseStatement.FalseStatement is IfElseStatement);
1443
 
                        }
1444
 
                }
1445
 
 
1446
 
                public override void VisitLabelStatement(LabelStatement labelStatement)
1447
 
                {
1448
 
                        // TODO
1449
 
                        VisitChildren(labelStatement);
1450
 
                }
1451
 
 
1452
 
                public override void VisitLockStatement(LockStatement lockStatement)
1453
 
                {
1454
 
                        ForceSpacesBefore(lockStatement.LParToken, policy.SpaceBeforeLockParentheses);
1455
 
 
1456
 
                        ForceSpacesAfter(lockStatement.LParToken, policy.SpacesWithinLockParentheses);
1457
 
                        ForceSpacesBefore(lockStatement.RParToken, policy.SpacesWithinLockParentheses);
1458
 
 
1459
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, lockStatement.EmbeddedStatement);
1460
 
                }
1461
 
 
1462
 
                public override void VisitReturnStatement(ReturnStatement returnStatement)
1463
 
                {
1464
 
                        VisitChildren(returnStatement);
1465
 
                        FixSemicolon(returnStatement.SemicolonToken);
1466
 
                }
1467
 
 
1468
 
                public override void VisitSwitchStatement(SwitchStatement switchStatement)
1469
 
                {
1470
 
                        ForceSpacesBefore(switchStatement.LParToken, policy.SpaceBeforeSwitchParentheses);
1471
 
 
1472
 
                        ForceSpacesAfter(switchStatement.LParToken, policy.SpacesWithinSwitchParentheses);
1473
 
                        ForceSpacesBefore(switchStatement.RParToken, policy.SpacesWithinSwitchParentheses);
1474
 
 
1475
 
                        EnforceBraceStyle(policy.StatementBraceStyle, switchStatement.LBraceToken, switchStatement.RBraceToken);
1476
 
                        VisitChildren(switchStatement);
1477
 
                }
1478
 
 
1479
 
                public override void VisitSwitchSection(SwitchSection switchSection)
1480
 
                {
1481
 
                        if (policy.IndentSwitchBody) {
1482
 
                                curIndent.Push(IndentType.Block);
1483
 
                        }
1484
 
                        
1485
 
                        foreach (CaseLabel label in switchSection.CaseLabels) {
1486
 
                                FixStatementIndentation(label.StartLocation);
1487
 
                                label.AcceptVisitor(this);
1488
 
                        }
1489
 
                        if (policy.IndentCaseBody) {
1490
 
                                curIndent.Push(IndentType.Block);
1491
 
                        }
1492
 
                        
1493
 
                        foreach (var stmt in switchSection.Statements) {
1494
 
                                if (stmt is BreakStatement && !policy.IndentBreakStatements && policy.IndentCaseBody) {
1495
 
                                        curIndent.Pop();
1496
 
                                        FixStatementIndentation(stmt.StartLocation);
1497
 
                                        stmt.AcceptVisitor(this);
1498
 
                                        curIndent.Push(IndentType.Block);
1499
 
                                        continue;
1500
 
                                }
1501
 
                                FixStatementIndentation(stmt.StartLocation);
1502
 
                                stmt.AcceptVisitor(this);
1503
 
                        }
1504
 
                        if (policy.IndentCaseBody) {
1505
 
                                curIndent.Pop ();
1506
 
                        }
1507
 
                        
1508
 
                        if (policy.IndentSwitchBody) {
1509
 
                                curIndent.Pop ();
1510
 
                        }
1511
 
                }
1512
 
 
1513
 
                public override void VisitCaseLabel(CaseLabel caseLabel)
1514
 
                {
1515
 
                        FixSemicolon(caseLabel.ColonToken);
1516
 
                }
1517
 
 
1518
 
                public override void VisitThrowStatement(ThrowStatement throwStatement)
1519
 
                {
1520
 
                        VisitChildren(throwStatement);
1521
 
                        FixSemicolon(throwStatement.SemicolonToken);
1522
 
                }
1523
 
 
1524
 
                public override void VisitTryCatchStatement(TryCatchStatement tryCatchStatement)
1525
 
                {
1526
 
                        if (!tryCatchStatement.TryBlock.IsNull) {
1527
 
                                FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.TryBlock);
1528
 
                        }
1529
 
                        
1530
 
                        foreach (CatchClause clause in tryCatchStatement.CatchClauses) {
1531
 
                                PlaceOnNewLine(policy.CatchNewLinePlacement, clause.CatchToken);
1532
 
                                if (!clause.LParToken.IsNull) {
1533
 
                                        ForceSpacesBefore(clause.LParToken, policy.SpaceBeforeCatchParentheses);
1534
 
 
1535
 
                                        ForceSpacesAfter(clause.LParToken, policy.SpacesWithinCatchParentheses);
1536
 
                                        ForceSpacesBefore(clause.RParToken, policy.SpacesWithinCatchParentheses);
1537
 
                                }
1538
 
                                FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, clause.Body);
1539
 
                        }
1540
 
                        
1541
 
                        if (!tryCatchStatement.FinallyBlock.IsNull) {
1542
 
                                PlaceOnNewLine(policy.FinallyNewLinePlacement, tryCatchStatement.FinallyToken);
1543
 
                                
1544
 
                                FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, tryCatchStatement.FinallyBlock);
1545
 
                        }
1546
 
                        
1547
 
                }
1548
 
 
1549
 
                public override void VisitCatchClause(CatchClause catchClause)
1550
 
                {
1551
 
                        // Handled in TryCatchStatement
1552
 
                }
1553
 
 
1554
 
                public override void VisitUncheckedStatement(UncheckedStatement uncheckedStatement)
1555
 
                {
1556
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.FixedBraceForcement, uncheckedStatement.Body);
1557
 
                }
1558
 
 
1559
 
                public override void VisitUnsafeStatement(UnsafeStatement unsafeStatement)
1560
 
                {
1561
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, BraceForcement.DoNotChange, unsafeStatement.Body);
1562
 
                }
1563
 
 
1564
 
                public override void VisitUsingStatement(UsingStatement usingStatement)
1565
 
                {
1566
 
                        ForceSpacesBefore(usingStatement.LParToken, policy.SpaceBeforeUsingParentheses);
1567
 
 
1568
 
                        ForceSpacesAfter(usingStatement.LParToken, policy.SpacesWithinUsingParentheses);
1569
 
                        ForceSpacesBefore(usingStatement.RParToken, policy.SpacesWithinUsingParentheses);
1570
 
 
1571
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.UsingBraceForcement, usingStatement.EmbeddedStatement);
1572
 
                }
1573
 
 
1574
 
                public override void VisitVariableDeclarationStatement(VariableDeclarationStatement variableDeclarationStatement)
1575
 
                {
1576
 
                        if ((variableDeclarationStatement.Modifiers & Modifiers.Const) == Modifiers.Const) {
1577
 
                                ForceSpacesAround(variableDeclarationStatement.Type, true);
1578
 
                        } else {
1579
 
                                ForceSpacesAfter(variableDeclarationStatement.Type, true);
1580
 
                        }
1581
 
                        var lastLoc = variableDeclarationStatement.StartLocation;
1582
 
                        foreach (var initializer in variableDeclarationStatement.Variables) {
1583
 
                                if (lastLoc.Line != initializer.StartLocation.Line) {
1584
 
                                        FixStatementIndentation(initializer.StartLocation);
1585
 
                                        lastLoc = initializer.StartLocation;
1586
 
                                }
1587
 
                                initializer.AcceptVisitor(this);
1588
 
                        }
1589
 
 
1590
 
                        FormatCommas(variableDeclarationStatement, policy.SpaceBeforeLocalVariableDeclarationComma, policy.SpaceAfterLocalVariableDeclarationComma);
1591
 
                        FixSemicolon(variableDeclarationStatement.SemicolonToken);
1592
 
                }
1593
 
 
1594
 
                public override void VisitDoWhileStatement(DoWhileStatement doWhileStatement)
1595
 
                {
1596
 
                        PlaceOnNewLine(policy.WhileNewLinePlacement, doWhileStatement.WhileToken);
1597
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, doWhileStatement.EmbeddedStatement);
1598
 
                }
1599
 
 
1600
 
                public override void VisitWhileStatement(WhileStatement whileStatement)
1601
 
                {
1602
 
                        ForceSpacesBefore(whileStatement.LParToken, policy.SpaceBeforeWhileParentheses);
1603
 
 
1604
 
                        ForceSpacesAfter(whileStatement.LParToken, policy.SpacesWithinWhileParentheses);
1605
 
                        ForceSpacesBefore(whileStatement.RParToken, policy.SpacesWithinWhileParentheses);
1606
 
 
1607
 
                        FixEmbeddedStatment(policy.StatementBraceStyle, policy.WhileBraceForcement, whileStatement.EmbeddedStatement);
1608
 
                }
1609
 
 
1610
 
                public override void VisitYieldBreakStatement(YieldBreakStatement yieldBreakStatement)
1611
 
                {
1612
 
                        FixSemicolon(yieldBreakStatement.SemicolonToken);
1613
 
                }
1614
 
 
1615
 
                public override void VisitYieldReturnStatement(YieldReturnStatement yieldStatement)
1616
 
                {
1617
 
                        yieldStatement.Expression.AcceptVisitor(this);
1618
 
                        FixSemicolon(yieldStatement.SemicolonToken);
1619
 
                }
1620
 
 
1621
 
                public override void VisitVariableInitializer(VariableInitializer variableInitializer)
1622
 
                {
1623
 
                        if (!variableInitializer.AssignToken.IsNull) {
1624
 
                                ForceSpacesAround(variableInitializer.AssignToken, policy.SpaceAroundAssignment);
1625
 
                        }
1626
 
                        if (!variableInitializer.Initializer.IsNull) {
1627
 
                                variableInitializer.Initializer.AcceptVisitor(this);
1628
 
                        }
1629
 
                }
1630
 
 
1631
 
                #endregion
1632
 
                
1633
 
                #region Expressions
1634
 
                public override void VisitComposedType(ComposedType composedType)
1635
 
                {
1636
 
                        var spec = composedType.ArraySpecifiers.FirstOrDefault();
1637
 
                        if (spec != null) {
1638
 
                                ForceSpacesBefore(spec.LBracketToken, policy.SpaceBeforeArrayDeclarationBrackets);
1639
 
                        }
1640
 
 
1641
 
                        base.VisitComposedType(composedType);
1642
 
                }
1643
 
 
1644
 
                public override void VisitAnonymousMethodExpression(AnonymousMethodExpression anonymousMethodExpression)
1645
 
                {
1646
 
                        if (!anonymousMethodExpression.Body.IsNull) {
1647
 
                                EnforceBraceStyle(policy.AnonymousMethodBraceStyle, anonymousMethodExpression.Body.LBraceToken, anonymousMethodExpression.Body.RBraceToken);
1648
 
                        }
1649
 
                        base.VisitAnonymousMethodExpression(anonymousMethodExpression);
1650
 
                }
1651
 
 
1652
 
                public override void VisitAssignmentExpression(AssignmentExpression assignmentExpression)
1653
 
                {
1654
 
                        ForceSpacesAround(assignmentExpression.OperatorToken, policy.SpaceAroundAssignment);
1655
 
                        base.VisitAssignmentExpression(assignmentExpression);
1656
 
                }
1657
 
 
1658
 
                public override void VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
1659
 
                {
1660
 
                        bool forceSpaces = false;
1661
 
                        switch (binaryOperatorExpression.Operator) {
1662
 
                                case BinaryOperatorType.Equality:
1663
 
                                case BinaryOperatorType.InEquality:
1664
 
                                        forceSpaces = policy.SpaceAroundEqualityOperator;
1665
 
                                        break;
1666
 
                                case BinaryOperatorType.GreaterThan:
1667
 
                                case BinaryOperatorType.GreaterThanOrEqual:
1668
 
                                case BinaryOperatorType.LessThan:
1669
 
                                case BinaryOperatorType.LessThanOrEqual:
1670
 
                                        forceSpaces = policy.SpaceAroundRelationalOperator;
1671
 
                                        break;
1672
 
                                case BinaryOperatorType.ConditionalAnd:
1673
 
                                case BinaryOperatorType.ConditionalOr:
1674
 
                                        forceSpaces = policy.SpaceAroundLogicalOperator;
1675
 
                                        break;
1676
 
                                case BinaryOperatorType.BitwiseAnd:
1677
 
                                case BinaryOperatorType.BitwiseOr:
1678
 
                                case BinaryOperatorType.ExclusiveOr:
1679
 
                                        forceSpaces = policy.SpaceAroundBitwiseOperator;
1680
 
                                        break;
1681
 
                                case BinaryOperatorType.Add:
1682
 
                                case BinaryOperatorType.Subtract:
1683
 
                                        forceSpaces = policy.SpaceAroundAdditiveOperator;
1684
 
                                        break;
1685
 
                                case BinaryOperatorType.Multiply:
1686
 
                                case BinaryOperatorType.Divide:
1687
 
                                case BinaryOperatorType.Modulus:
1688
 
                                        forceSpaces = policy.SpaceAroundMultiplicativeOperator;
1689
 
                                        break;
1690
 
                                case BinaryOperatorType.ShiftLeft:
1691
 
                                case BinaryOperatorType.ShiftRight:
1692
 
                                        forceSpaces = policy.SpaceAroundShiftOperator;
1693
 
                                        break;
1694
 
                                case BinaryOperatorType.NullCoalescing:
1695
 
                                        forceSpaces = policy.SpaceAroundNullCoalescingOperator;
1696
 
                                        break;
1697
 
                        }
1698
 
                        ForceSpacesAround(binaryOperatorExpression.OperatorToken, forceSpaces);
1699
 
                        
1700
 
                        base.VisitBinaryOperatorExpression(binaryOperatorExpression);
1701
 
                        // Handle line breaks in binary opeartor expression.
1702
 
                        if (binaryOperatorExpression.Left.EndLocation.Line != binaryOperatorExpression.Right.StartLocation.Line) {
1703
 
                                curIndent.Push(IndentType.Block);
1704
 
                                if (binaryOperatorExpression.OperatorToken.StartLocation.Line == binaryOperatorExpression.Right.StartLocation.Line) {
1705
 
                                        FixStatementIndentation(binaryOperatorExpression.OperatorToken.StartLocation);
1706
 
                                } else {
1707
 
                                        FixStatementIndentation(binaryOperatorExpression.Right.StartLocation);
1708
 
                                }
1709
 
                                curIndent.Pop ();
1710
 
                        }
1711
 
                }
1712
 
 
1713
 
                public override void VisitConditionalExpression(ConditionalExpression conditionalExpression)
1714
 
                {
1715
 
                        ForceSpacesBefore(conditionalExpression.QuestionMarkToken, policy.SpaceBeforeConditionalOperatorCondition);
1716
 
                        ForceSpacesAfter(conditionalExpression.QuestionMarkToken, policy.SpaceAfterConditionalOperatorCondition);
1717
 
                        ForceSpacesBefore(conditionalExpression.ColonToken, policy.SpaceBeforeConditionalOperatorSeparator);
1718
 
                        ForceSpacesAfter(conditionalExpression.ColonToken, policy.SpaceAfterConditionalOperatorSeparator);
1719
 
                        base.VisitConditionalExpression(conditionalExpression);
1720
 
                }
1721
 
 
1722
 
                public override void VisitCastExpression(CastExpression castExpression)
1723
 
                {
1724
 
                        if (castExpression.RParToken != null) {
1725
 
                                ForceSpacesAfter(castExpression.LParToken, policy.SpacesWithinCastParentheses);
1726
 
                                ForceSpacesBefore(castExpression.RParToken, policy.SpacesWithinCastParentheses);
1727
 
 
1728
 
                                ForceSpacesAfter(castExpression.RParToken, policy.SpaceAfterTypecast);
1729
 
                        }
1730
 
                        base.VisitCastExpression(castExpression);
1731
 
                }
1732
 
 
1733
 
                void ForceSpacesAround(AstNode node, bool forceSpaces)
1734
 
                {
1735
 
                        if (node.IsNull) {
1736
 
                                return;
1737
 
                        }
1738
 
                        ForceSpacesBefore(node, forceSpaces);
1739
 
                        ForceSpacesAfter(node, forceSpaces);
1740
 
                }
1741
 
 
1742
 
                void FormatCommas(AstNode parent, bool before, bool after)
1743
 
                {
1744
 
                        if (parent.IsNull) {
1745
 
                                return;
1746
 
                        }
1747
 
                        foreach (CSharpTokenNode comma in parent.Children.Where (node => node.Role == Roles.Comma)) {
1748
 
                                ForceSpacesAfter(comma, after);
1749
 
                                ForceSpacesBefore(comma, before);
1750
 
                        }
1751
 
                }
1752
 
 
1753
 
                bool DoWrap (Wrapping wrapping, AstNode wrapNode, int argumentCount)
1754
 
                {
1755
 
                        return wrapping == Wrapping.WrapAlways || 
1756
 
                                options.WrapLineLength > 0 && argumentCount > 1 && wrapping == Wrapping.WrapIfTooLong && wrapNode.StartLocation.Column >= options.WrapLineLength;
1757
 
                }
1758
 
 
1759
 
                void FormatArguments(AstNode node)
1760
 
                {
1761
 
                        Wrapping methodCallArgumentWrapping;
1762
 
                        bool newLineAferMethodCallOpenParentheses;
1763
 
                        bool methodClosingParenthesesOnNewLine;
1764
 
                        bool spaceWithinMethodCallParentheses;
1765
 
                        bool spaceAfterMethodCallParameterComma;
1766
 
                        bool spaceBeforeMethodCallParameterComma;
1767
 
                                
1768
 
                        CSharpTokenNode rParToken;
1769
 
                        AstNodeCollection<Expression> arguments;
1770
 
                        var indexer = node as IndexerExpression;
1771
 
                        if (indexer != null) {
1772
 
                                methodCallArgumentWrapping = policy.IndexerArgumentWrapping;
1773
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferIndexerOpenBracket;
1774
 
                                methodClosingParenthesesOnNewLine = policy.IndexerClosingBracketOnNewLine;
1775
 
                                spaceWithinMethodCallParentheses = policy.SpacesWithinBrackets;
1776
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterBracketComma;
1777
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeBracketComma;
1778
 
                        
1779
 
                                rParToken = indexer.RBracketToken;
1780
 
                                arguments = indexer.Arguments;
1781
 
                        } else if (node is ObjectCreateExpression) {
1782
 
                                var oce = node as ObjectCreateExpression;
1783
 
                                methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
1784
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
1785
 
                                methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
1786
 
                                spaceWithinMethodCallParentheses = policy.SpacesWithinNewParentheses;
1787
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterNewParameterComma;
1788
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeNewParameterComma;
1789
 
                        
1790
 
                                rParToken = oce.RParToken;
1791
 
                                arguments = oce.Arguments;
1792
 
                        } else {
1793
 
                                InvocationExpression invocationExpression = node as InvocationExpression;
1794
 
                                methodCallArgumentWrapping = policy.MethodCallArgumentWrapping;
1795
 
                                newLineAferMethodCallOpenParentheses = policy.NewLineAferMethodCallOpenParentheses;
1796
 
                                methodClosingParenthesesOnNewLine = policy.MethodCallClosingParenthesesOnNewLine;
1797
 
                                spaceWithinMethodCallParentheses = policy.SpaceWithinMethodCallParentheses;
1798
 
                                spaceAfterMethodCallParameterComma = policy.SpaceAfterMethodCallParameterComma;
1799
 
                                spaceBeforeMethodCallParameterComma = policy.SpaceBeforeMethodCallParameterComma;
1800
 
                        
1801
 
                                rParToken = invocationExpression.RParToken;
1802
 
                                arguments = invocationExpression.Arguments;
1803
 
                        }
1804
 
 
1805
 
                        if (FormattingMode == ICSharpCode.NRefactory.CSharp.FormattingMode.OnTheFly)
1806
 
                                methodCallArgumentWrapping = Wrapping.DoNotChange;
1807
 
 
1808
 
                        bool wrapMethodCall = DoWrap(methodCallArgumentWrapping, rParToken, arguments.Count);
1809
 
                        if (wrapMethodCall && arguments.Any()) {
1810
 
                                if (newLineAferMethodCallOpenParentheses) {
1811
 
                                        curIndent.Push(IndentType.Continuation);
1812
 
                                        foreach (var arg in arguments) {
1813
 
                                                FixStatementIndentation(arg.StartLocation);
1814
 
                                        }
1815
 
                                        curIndent.Pop();
1816
 
                                } else {
1817
 
                                        int extraSpaces = arguments.First().StartLocation.Column - 1 - curIndent.IndentString.Length;
1818
 
                                        curIndent.ExtraSpaces += extraSpaces;
1819
 
                                        foreach (var arg in arguments.Skip(1)) {
1820
 
                                                FixStatementIndentation(arg.StartLocation);
1821
 
                                        }
1822
 
                                        curIndent.ExtraSpaces -= extraSpaces;
1823
 
                                }
1824
 
                                if (!rParToken.IsNull) {
1825
 
                                        if (methodClosingParenthesesOnNewLine) {
1826
 
                                                FixStatementIndentation(rParToken.StartLocation);
1827
 
                                        } else {
1828
 
                                                ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
1829
 
                                        }
1830
 
                                }
1831
 
                        } else {
1832
 
                                foreach (var arg in arguments) {
1833
 
                                        if (arg.PrevSibling != null) {
1834
 
                                                if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
1835
 
                                                        ForceSpacesBeforeRemoveNewLines(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
1836
 
                                                } else {
1837
 
                                                        ForceSpacesBefore(arg, spaceAfterMethodCallParameterComma && arg.PrevSibling.Role == Roles.Comma);
1838
 
                                                }
1839
 
                                        }
1840
 
                                        arg.AcceptVisitor(this);
1841
 
                                }
1842
 
                                if (!rParToken.IsNull) {
1843
 
                                        if (methodCallArgumentWrapping == Wrapping.DoNotWrap) {
1844
 
                                                ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
1845
 
                                        } else {
1846
 
                                                bool sameLine = rParToken.GetPrevNode().StartLocation.Line == rParToken.StartLocation.Line;
1847
 
                                                if (sameLine) {
1848
 
                                                        ForceSpacesBeforeRemoveNewLines(rParToken, spaceWithinMethodCallParentheses);
1849
 
                                                } else {
1850
 
                                                        FixStatementIndentation(rParToken.StartLocation);
1851
 
                                                }
1852
 
                                        }
1853
 
                                }
1854
 
                        }
1855
 
                        if (!rParToken.IsNull) {
1856
 
                                foreach (CSharpTokenNode comma in rParToken.Parent.Children.Where(n => n.Role == Roles.Comma)) {
1857
 
                                        ForceSpacesBefore(comma, spaceBeforeMethodCallParameterComma);
1858
 
                                }
1859
 
                        }
1860
 
                }
1861
 
 
1862
 
                public override void VisitInvocationExpression(InvocationExpression invocationExpression)
1863
 
                {
1864
 
                        ForceSpacesBefore(invocationExpression.LParToken, policy.SpaceBeforeMethodCallParentheses);
1865
 
                        if (invocationExpression.Arguments.Any()) {
1866
 
                                ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceWithinMethodCallParentheses);
1867
 
                        } else {
1868
 
                                ForceSpacesAfter(invocationExpression.LParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
1869
 
                                ForceSpacesBefore(invocationExpression.RParToken, policy.SpaceBetweenEmptyMethodCallParentheses);
1870
 
                        }
1871
 
 
1872
 
                        if (!invocationExpression.Target.IsNull)
1873
 
                                invocationExpression.Target.AcceptVisitor(this);
1874
 
 
1875
 
                        if (invocationExpression.Target is MemberReferenceExpression) {
1876
 
                                var mt = (MemberReferenceExpression)invocationExpression.Target;
1877
 
                                if (mt.Target is InvocationExpression) {
1878
 
                                        if (DoWrap(policy.ChainedMethodCallWrapping, mt.DotToken, 2)) {
1879
 
                                                curIndent.Push(IndentType.Continuation);
1880
 
                                                FixStatementIndentation(mt.DotToken.StartLocation);
1881
 
                                                curIndent.Pop();
1882
 
                                        } else {
1883
 
                                                if (policy.ChainedMethodCallWrapping == Wrapping.DoNotWrap)
1884
 
                                                        ForceSpacesBeforeRemoveNewLines(mt.DotToken, false);
1885
 
                                        }
1886
 
                                }
1887
 
                        }
1888
 
                        FormatArguments(invocationExpression);
1889
 
                }
1890
 
 
1891
 
                public override void VisitIndexerExpression(IndexerExpression indexerExpression)
1892
 
                {
1893
 
                        ForceSpacesBefore(indexerExpression.LBracketToken, policy.SpacesBeforeBrackets);
1894
 
                        ForceSpacesAfter(indexerExpression.LBracketToken, policy.SpacesWithinBrackets);
1895
 
 
1896
 
                        if (!indexerExpression.Target.IsNull)
1897
 
                                indexerExpression.Target.AcceptVisitor(this);
1898
 
 
1899
 
                        FormatArguments(indexerExpression);
1900
 
 
1901
 
 
1902
 
 
1903
 
                }
1904
 
 
1905
 
                public override void VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
1906
 
                {
1907
 
                        ForceSpacesAfter(parenthesizedExpression.LParToken, policy.SpacesWithinParentheses);
1908
 
                        ForceSpacesBefore(parenthesizedExpression.RParToken, policy.SpacesWithinParentheses);
1909
 
                        base.VisitParenthesizedExpression(parenthesizedExpression);
1910
 
                }
1911
 
 
1912
 
                public override void VisitSizeOfExpression(SizeOfExpression sizeOfExpression)
1913
 
                {
1914
 
                        ForceSpacesBefore(sizeOfExpression.LParToken, policy.SpaceBeforeSizeOfParentheses);
1915
 
                        ForceSpacesAfter(sizeOfExpression.LParToken, policy.SpacesWithinSizeOfParentheses);
1916
 
                        ForceSpacesBefore(sizeOfExpression.RParToken, policy.SpacesWithinSizeOfParentheses);
1917
 
                        base.VisitSizeOfExpression(sizeOfExpression);
1918
 
                }
1919
 
 
1920
 
                public override void VisitTypeOfExpression(TypeOfExpression typeOfExpression)
1921
 
                {
1922
 
                        ForceSpacesBefore(typeOfExpression.LParToken, policy.SpaceBeforeTypeOfParentheses);
1923
 
                        ForceSpacesAfter(typeOfExpression.LParToken, policy.SpacesWithinTypeOfParentheses);
1924
 
                        ForceSpacesBefore(typeOfExpression.RParToken, policy.SpacesWithinTypeOfParentheses);
1925
 
                        base.VisitTypeOfExpression(typeOfExpression);
1926
 
                }
1927
 
 
1928
 
                public override void VisitCheckedExpression(CheckedExpression checkedExpression)
1929
 
                {
1930
 
                        ForceSpacesAfter(checkedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses);
1931
 
                        ForceSpacesBefore(checkedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses);
1932
 
                        base.VisitCheckedExpression(checkedExpression);
1933
 
                }
1934
 
 
1935
 
                public override void VisitUncheckedExpression(UncheckedExpression uncheckedExpression)
1936
 
                {
1937
 
                        ForceSpacesAfter(uncheckedExpression.LParToken, policy.SpacesWithinCheckedExpressionParantheses);
1938
 
                        ForceSpacesBefore(uncheckedExpression.RParToken, policy.SpacesWithinCheckedExpressionParantheses);
1939
 
                        base.VisitUncheckedExpression(uncheckedExpression);
1940
 
                }
1941
 
 
1942
 
                public override void VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression)
1943
 
                {
1944
 
                        ForceSpacesBefore(objectCreateExpression.LParToken, policy.SpaceBeforeNewParentheses);
1945
 
                        
1946
 
                        if (objectCreateExpression.Arguments.Any()) {
1947
 
                                if (!objectCreateExpression.LParToken.IsNull)
1948
 
                                        ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesWithinNewParentheses);
1949
 
                        } else {
1950
 
                                if (!objectCreateExpression.LParToken.IsNull)
1951
 
                                        ForceSpacesAfter(objectCreateExpression.LParToken, policy.SpacesBetweenEmptyNewParentheses);
1952
 
                        }
1953
 
 
1954
 
                        if (!objectCreateExpression.Type.IsNull)
1955
 
                                objectCreateExpression.Type.AcceptVisitor(this);
1956
 
 
1957
 
                        FormatArguments(objectCreateExpression);
1958
 
 
1959
 
                }
1960
 
 
1961
 
                public override void VisitArrayCreateExpression(ArrayCreateExpression arrayObjectCreateExpression)
1962
 
                {
1963
 
                        FormatCommas(arrayObjectCreateExpression, policy.SpaceBeforeMethodCallParameterComma, policy.SpaceAfterMethodCallParameterComma);
1964
 
                        base.VisitArrayCreateExpression(arrayObjectCreateExpression);
1965
 
                }
1966
 
 
1967
 
                public override void VisitArrayInitializerExpression(ArrayInitializerExpression arrayInitializerExpression)
1968
 
                {
1969
 
                        if (DoWrap(policy.ArrayInitializerWrapping, arrayInitializerExpression.RBraceToken, arrayInitializerExpression.Elements.Count)) {
1970
 
                                EnforceBraceStyle(policy.ArrayInitializerBraceStyle, arrayInitializerExpression.LBraceToken, arrayInitializerExpression.RBraceToken);
1971
 
                                curIndent.Push(IndentType.Block);
1972
 
                                foreach (var init in arrayInitializerExpression.Elements) {
1973
 
                                        FixStatementIndentation(init.StartLocation);
1974
 
                                        init.AcceptVisitor(this);
1975
 
                                }
1976
 
                                curIndent.Pop();
1977
 
                        } else if (policy.ArrayInitializerWrapping == Wrapping.DoNotWrap) {
1978
 
                                ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.LBraceToken);
1979
 
                                ForceSpacesBeforeRemoveNewLines(arrayInitializerExpression.RBraceToken);
1980
 
                                foreach (var init in arrayInitializerExpression.Elements) {
1981
 
                                        ForceSpacesBeforeRemoveNewLines(init);
1982
 
                                        init.AcceptVisitor(this);
1983
 
                                }
1984
 
                        } else {
1985
 
                                base.VisitArrayInitializerExpression(arrayInitializerExpression);
1986
 
                        }
1987
 
                }
1988
 
 
1989
 
                public override void VisitLambdaExpression(LambdaExpression lambdaExpression)
1990
 
                {
1991
 
                        ForceSpacesAfter(lambdaExpression.ArrowToken, true);
1992
 
                        ForceSpacesBefore(lambdaExpression.ArrowToken, true);
1993
 
 
1994
 
                        base.VisitLambdaExpression(lambdaExpression);
1995
 
                }
1996
 
 
1997
 
                public override void VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression)
1998
 
                {
1999
 
                        ForceSpacesAfter(namedArgumentExpression.ColonToken, policy.SpaceInNamedArgumentAfterDoubleColon);
2000
 
                        base.VisitNamedArgumentExpression(namedArgumentExpression);
2001
 
                }
2002
 
 
2003
 
                public override void VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
2004
 
                {
2005
 
                        ForceSpacesAfter(memberReferenceExpression.DotToken, false);
2006
 
                        base.VisitMemberReferenceExpression(memberReferenceExpression);
2007
 
                }
2008
 
 
2009
 
                #endregion
2010
 
                
2011
 
                void ForceSpaceBefore(int offset, bool forceSpace)
2012
 
                {
2013
 
                        bool insertedSpace = false;
2014
 
                        do {
2015
 
                                char ch = document.GetCharAt(offset);
2016
 
                                //Console.WriteLine (ch);
2017
 
                                if (!IsSpacing(ch) && (insertedSpace || !forceSpace)) {
2018
 
                                        break;
2019
 
                                }
2020
 
                                if (ch == ' ' && forceSpace) {
2021
 
                                        if (insertedSpace) {
2022
 
                                                AddChange(offset, 1, null);
2023
 
                                        } else {
2024
 
                                                insertedSpace = true;
2025
 
                                        }
2026
 
                                } else if (forceSpace) {
2027
 
                                        if (!insertedSpace) {
2028
 
                                                AddChange(offset, IsSpacing(ch) ? 1 : 0, " ");
2029
 
                                                insertedSpace = true;
2030
 
                                        } else if (IsSpacing(ch)) {
2031
 
                                                AddChange(offset, 1, null);
2032
 
                                        }
2033
 
                                }
2034
 
 
2035
 
                                offset--;
2036
 
                        } while (offset >= 0);
2037
 
                }
2038
 
 
2039
 
                
2040
 
 
2041
 
                /*
2042
 
                int GetLastNonWsChar (LineSegment line, int lastColumn)
2043
 
                {
2044
 
                        int result = -1;
2045
 
                        bool inComment = false;
2046
 
                        for (int i = 0; i < lastColumn; i++) {
2047
 
                                char ch = data.GetCharAt (line.Offset + i);
2048
 
                                if (Char.IsWhiteSpace (ch))
2049
 
                                        continue;
2050
 
                                if (ch == '/' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '/')
2051
 
                                        return result;
2052
 
                                if (ch == '/' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '*') {
2053
 
                                        inComment = true;
2054
 
                                        i++;
2055
 
                                        continue;
2056
 
                                }
2057
 
                                if (inComment && ch == '*' && i + 1 < line.EditableLength && data.GetCharAt (line.Offset + i + 1) == '/') {
2058
 
                                        inComment = false;
2059
 
                                        i++;
2060
 
                                        continue;
2061
 
                                }
2062
 
                                if (!inComment)
2063
 
                                        result = i;
2064
 
                        }
2065
 
                        return result;
2066
 
                }
2067
 
                 */
2068
 
                
2069
 
                
2070
 
                public void FixSemicolon(CSharpTokenNode semicolon)
2071
 
                {
2072
 
                        if (semicolon.IsNull) {
2073
 
                                return;
2074
 
                        }
2075
 
                        int endOffset = document.GetOffset(semicolon.StartLocation);
2076
 
                        int offset = endOffset;
2077
 
                        while (offset - 1 > 0 && char.IsWhiteSpace (document.GetCharAt (offset - 1))) {
2078
 
                                offset--;
2079
 
                        }
2080
 
                        if (offset < endOffset) {
2081
 
                                AddChange(offset, endOffset - offset, null);
2082
 
                        }
2083
 
                }
2084
 
 
2085
 
                void PlaceOnNewLine(NewLinePlacement newLine, AstNode keywordNode)
2086
 
                {
2087
 
                        if (keywordNode == null || newLine == NewLinePlacement.DoNotCare) {
2088
 
                                return;
2089
 
                        }
2090
 
 
2091
 
                        var prev = keywordNode.GetPrevNode ();
2092
 
                        if (prev is Comment || prev is PreProcessorDirective)
2093
 
                                return;
2094
 
 
2095
 
                        int offset = document.GetOffset(keywordNode.StartLocation);
2096
 
                        
2097
 
                        int whitespaceStart = SearchWhitespaceStart(offset);
2098
 
                        string indentString = newLine == NewLinePlacement.NewLine ? this.options.EolMarker + this.curIndent.IndentString : " ";
2099
 
                        AddChange(whitespaceStart, offset - whitespaceStart, indentString);
2100
 
                }
2101
 
 
2102
 
                string nextStatementIndent = null;
2103
 
 
2104
 
                void FixStatementIndentation(TextLocation location)
2105
 
                {
2106
 
                        int offset = document.GetOffset(location);
2107
 
                        if (offset <= 0) {
2108
 
                                Console.WriteLine("possible wrong offset");
2109
 
                                Console.WriteLine(Environment.StackTrace);
2110
 
                                return;
2111
 
                        }
2112
 
                        bool isEmpty = IsLineIsEmptyUpToEol(offset);
2113
 
                        int lineStart = SearchWhitespaceLineStart(offset);
2114
 
                        string indentString = nextStatementIndent == null ? (isEmpty ? "" : this.options.EolMarker) + this.curIndent.IndentString : nextStatementIndent;
2115
 
                        nextStatementIndent = null;
2116
 
                        AddChange(lineStart, offset - lineStart, indentString);
2117
 
                }
2118
 
 
2119
 
                void FixIndentation(TextLocation location)
2120
 
                {
2121
 
                        FixIndentation(location, 0);
2122
 
                }
2123
 
 
2124
 
                void FixIndentation(TextLocation location, int relOffset)
2125
 
                {
2126
 
                        if (location.Line < 1 || location.Line > document.LineCount) {
2127
 
                                Console.WriteLine("Invalid location " + location);
2128
 
                                Console.WriteLine(Environment.StackTrace);
2129
 
                                return;
2130
 
                        }
2131
 
                        
2132
 
                        string lineIndent = GetIndentation(location.Line);
2133
 
                        string indentString = this.curIndent.IndentString;
2134
 
                        if (indentString != lineIndent && location.Column - 1 + relOffset == lineIndent.Length) {
2135
 
                                AddChange(document.GetOffset(location.Line, 1), lineIndent.Length, indentString);
2136
 
                        }
2137
 
                }
2138
 
 
2139
 
                void FixIndentationForceNewLine(TextLocation location)
2140
 
                {
2141
 
                        string lineIndent = GetIndentation(location.Line);
2142
 
                        string indentString = this.curIndent.IndentString;
2143
 
                        if (location.Column - 1 == lineIndent.Length) {
2144
 
                                AddChange(document.GetOffset(location.Line, 1), lineIndent.Length, indentString);
2145
 
                        } else {
2146
 
                                int offset = document.GetOffset(location);
2147
 
                                int start = SearchWhitespaceLineStart(offset);
2148
 
                                if (start > 0) {
2149
 
                                        char ch = document.GetCharAt(start - 1);
2150
 
                                        if (ch == '\n') {
2151
 
                                                start--;
2152
 
                                                if (start > 1 && document.GetCharAt(start - 1) == '\r') {
2153
 
                                                        start--;
2154
 
                                                }
2155
 
                                        } else if (ch == '\r') {
2156
 
                                                start--;
2157
 
                                        }
2158
 
                                        AddChange(start, offset - start, this.options.EolMarker + indentString);
2159
 
                                }
2160
 
                        }
2161
 
                }
2162
 
                
2163
 
                string GetIndentation(int lineNumber)
2164
 
                {
2165
 
                        IDocumentLine line = document.GetLineByNumber(lineNumber);
2166
 
                        StringBuilder b = new StringBuilder ();
2167
 
                        int endOffset = line.EndOffset;
2168
 
                        for (int i = line.Offset; i < endOffset; i++) {
2169
 
                                char c = document.GetCharAt(i);
2170
 
                                if (!IsSpacing(c)) {
2171
 
                                        break;
2172
 
                                }
2173
 
                                b.Append(c);
2174
 
                        }
2175
 
                        return b.ToString();
2176
 
                }
2177
 
        }
2178
 
}
2179