Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CodeEditor/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/OutputVisitor/InsertSpecialsDecorator.cs @ 11700

Last change on this file since 11700 was 11700, checked in by jkarder, 9 years ago

#2077: created branch and added first version

File size: 4.8 KB
Line 
1// Copyright (c) 2010-2013 AlphaSierraPapa for the SharpDevelop Team
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4// software and associated documentation files (the "Software"), to deal in the Software
5// without restriction, including without limitation the rights to use, copy, modify, merge,
6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7// to whom the Software is furnished to do so, subject to the following conditions:
8//
9// The above copyright notice and this permission notice shall be included in all copies or
10// substantial portions of the Software.
11//
12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17// DEALINGS IN THE SOFTWARE.
18
19using System;
20using System.Collections.Generic;
21using System.Diagnostics;
22using System.Linq;
23using ICSharpCode.NRefactory.CSharp;
24
25namespace ICSharpCode.NRefactory.CSharp
26{
27  class InsertSpecialsDecorator : DecoratingTokenWriter
28  {
29    readonly Stack<AstNode> positionStack = new Stack<AstNode>();
30    int visitorWroteNewLine = 0;
31   
32    public InsertSpecialsDecorator(TokenWriter writer) : base(writer)
33    {
34    }
35   
36    public override void StartNode(AstNode node)
37    {
38      if (positionStack.Count > 0) {
39        WriteSpecialsUpToNode(node);
40      }
41      positionStack.Push(node.FirstChild);
42      base.StartNode(node);
43    }
44   
45    public override void EndNode(AstNode node)
46    {
47      base.EndNode(node);
48      AstNode pos = positionStack.Pop();
49      Debug.Assert(pos == null || pos.Parent == node);
50      WriteSpecials(pos, null);
51    }
52   
53    public override void WriteKeyword(Role role, string keyword)
54    {
55      if (role != null) {
56        WriteSpecialsUpToRole(role);
57      }
58      base.WriteKeyword(role, keyword);
59    }
60   
61    public override void WriteIdentifier(Identifier identifier)
62    {
63      WriteSpecialsUpToRole(identifier.Role ?? Roles.Identifier);
64      base.WriteIdentifier(identifier);
65    }
66   
67    public override void WriteToken(Role role, string token)
68    {
69      WriteSpecialsUpToRole(role);
70      base.WriteToken(role, token);
71    }
72   
73    public override void NewLine()
74    {
75      if (visitorWroteNewLine >= 0)
76        base.NewLine();
77      visitorWroteNewLine++;
78    }
79   
80    #region WriteSpecials
81    /// <summary>
82    /// Writes all specials from start to end (exclusive). Does not touch the positionStack.
83    /// </summary>
84    void WriteSpecials(AstNode start, AstNode end)
85    {
86      for (AstNode pos = start; pos != end; pos = pos.NextSibling) {
87        if (pos.Role == Roles.Comment) {
88          var node = (Comment)pos;
89          base.WriteComment(node.CommentType, node.Content);
90        }
91        // see CSharpOutputVisitor.VisitNewLine()
92        //        if (pos.Role == Roles.NewLine) {
93        //          if (visitorWroteNewLine <= 0)
94        //            base.NewLine();
95        //          visitorWroteNewLine--;
96        //        }
97        if (pos.Role == Roles.PreProcessorDirective) {
98          var node = (PreProcessorDirective)pos;
99          base.WritePreProcessorDirective(node.Type, node.Argument);
100        }
101      }
102    }
103   
104    /// <summary>
105    /// Writes all specials between the current position (in the positionStack) and the next
106    /// node with the specified role. Advances the current position.
107    /// </summary>
108    void WriteSpecialsUpToRole(Role role)
109    {
110      WriteSpecialsUpToRole(role, null);
111    }
112   
113    void WriteSpecialsUpToRole(Role role, AstNode nextNode)
114    {
115      if (positionStack.Count == 0) {
116        return;
117      }
118      // Look for the role between the current position and the nextNode.
119      for (AstNode pos = positionStack.Peek(); pos != null && pos != nextNode; pos = pos.NextSibling) {
120        if (pos.Role == role) {
121          WriteSpecials(positionStack.Pop(), pos);
122          // Push the next sibling because the node matching the role is not a special,
123          // and should be considered to be already handled.
124          positionStack.Push(pos.NextSibling);
125          // This is necessary for OptionalComma() to work correctly.
126          break;
127        }
128      }
129    }
130   
131    /// <summary>
132    /// Writes all specials between the current position (in the positionStack) and the specified node.
133    /// Advances the current position.
134    /// </summary>
135    void WriteSpecialsUpToNode(AstNode node)
136    {
137      if (positionStack.Count == 0) {
138        return;
139      }
140      for (AstNode pos = positionStack.Peek(); pos != null; pos = pos.NextSibling) {
141        if (pos == node) {
142          WriteSpecials(positionStack.Pop(), pos);
143          // Push the next sibling because the node itself is not a special,
144          // and should be considered to be already handled.
145          positionStack.Push(pos.NextSibling);
146          // This is necessary for OptionalComma() to work correctly.
147          break;
148        }
149      }
150    }
151    #endregion
152  }
153}
154
155
156
157
Note: See TracBrowser for help on using the repository browser.