PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/monodevelop-2.8.8.4/src/core/Mono.Texteditor/Mono.TextEditor.Highlighting/JaySyntaxMode.cs

#
C# | 237 lines | 195 code | 17 blank | 25 comment | 55 complexity | 972b55c021706616197088c39fe59ca1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. //
  2. // JaySyntaxMode.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.Linq;
  28. using System.Collections.Generic;
  29. using Mono.TextEditor.Highlighting;
  30. using Mono.TextEditor;
  31. using System.Xml;
  32. namespace Mono.TextEditor.Highlighting
  33. {
  34. public class JaySyntaxMode : Mono.TextEditor.Highlighting.SyntaxMode
  35. {
  36. public JaySyntaxMode ()
  37. {
  38. ResourceXmlProvider provider = new ResourceXmlProvider (typeof(IXmlProvider).Assembly, typeof(IXmlProvider).Assembly.GetManifestResourceNames ().First (s => s.Contains ("JaySyntaxMode")));
  39. using (XmlReader reader = provider.Open ()) {
  40. SyntaxMode baseMode = SyntaxMode.Read (reader);
  41. this.rules = new List<Rule> (baseMode.Rules);
  42. this.keywords = new List<Keywords> (baseMode.Keywords);
  43. this.spans = new List<Span> (baseMode.Spans).ToArray ();
  44. this.matches = baseMode.Matches;
  45. this.prevMarker = baseMode.PrevMarker;
  46. this.SemanticRules = new List<SemanticRule> (baseMode.SemanticRules);
  47. this.keywordTable = baseMode.keywordTable;
  48. this.keywordTableIgnoreCase = baseMode.keywordTableIgnoreCase;
  49. this.properties = baseMode.Properties;
  50. }
  51. }
  52. public override SpanParser CreateSpanParser (Document doc, SyntaxMode mode, LineSegment line, CloneableStack<Span> spanStack)
  53. {
  54. return new JaySpanParser (doc, mode, spanStack ?? line.StartSpan.Clone ());
  55. }
  56. class JayBlockSpan : Span
  57. {
  58. public int Offset {
  59. get;
  60. set;
  61. }
  62. public JayBlockSpan (int offset)
  63. {
  64. this.Offset = offset;
  65. this.Rule = "mode:text/x-csharp";
  66. this.Begin = new Regex ("}");
  67. this.End = new Regex ("}");
  68. this.TagColor = "keyword.access";
  69. }
  70. public override string ToString ()
  71. {
  72. return string.Format ("[JayBlockSpan: Offset={0}]", Offset);
  73. }
  74. }
  75. class ForcedJayBlockSpan : Span
  76. {
  77. public ForcedJayBlockSpan ()
  78. {
  79. this.Rule = "mode:text/x-csharp";
  80. this.Begin = new Regex ("%{");
  81. this.End = new Regex ("%}");
  82. this.TagColor = "keyword.access";
  83. }
  84. }
  85. class JayDefinitionSpan : Span
  86. {
  87. public JayDefinitionSpan ()
  88. {
  89. this.Rule = "token";
  90. this.Begin = this.End = new Regex ("%%");
  91. this.TagColor = "keyword.access";
  92. }
  93. }
  94. protected class JaySpanParser : SpanParser
  95. {
  96. public JaySpanParser (Document doc, SyntaxMode mode, CloneableStack<Span> spanStack) : base (doc, mode, spanStack)
  97. {
  98. }
  99. protected override void ScanSpan (ref int i)
  100. {
  101. bool hasJayDefinitonSpan = spanStack.Any (s => s is JayDefinitionSpan);
  102. int textOffset = i - StartOffset;
  103. if (textOffset + 1 < CurText.Length && CurText[textOffset] == '%') {
  104. char next = CurText[textOffset + 1];
  105. if (next == '{') {
  106. FoundSpanBegin (new ForcedJayBlockSpan (), i, 2);
  107. i++;
  108. return;
  109. }
  110. if (!hasJayDefinitonSpan && next == '%') {
  111. FoundSpanBegin (new JayDefinitionSpan (), i, 2);
  112. return;
  113. }
  114. if (next == '}' && spanStack.Any (s => s is ForcedJayBlockSpan)) {
  115. foreach (Span span in spanStack.Clone ()) {
  116. FoundSpanEnd (span, i, span.End.Pattern.Length);
  117. if (span is ForcedJayBlockSpan)
  118. break;
  119. }
  120. return;
  121. }
  122. }
  123. if (CurSpan is JayDefinitionSpan && CurText[textOffset] == '{' && hasJayDefinitonSpan && !spanStack.Any (s => s is JayBlockSpan)) {
  124. FoundSpanBegin (new JayBlockSpan (i), i, 1);
  125. return;
  126. }
  127. base.ScanSpan (ref i);
  128. }
  129. protected override bool ScanSpanEnd (Mono.TextEditor.Highlighting.Span cur, ref int i)
  130. {
  131. JayBlockSpan jbs = cur as JayBlockSpan;
  132. int textOffset = i - StartOffset;
  133. if (jbs != null) {
  134. if (CurText[textOffset] == '}') {
  135. int brackets = 0;
  136. bool isInString = false, isInChar = false, isVerbatimString = false;
  137. bool isInLineComment = false, isInBlockComment = false;
  138. for (int j = jbs.Offset; j <= i; j++) {
  139. char ch = doc.GetCharAt (j);
  140. switch (ch) {
  141. case '\n':
  142. case '\r':
  143. isInLineComment = false;
  144. if (!isVerbatimString)
  145. isInString = false;
  146. break;
  147. case '/':
  148. if (isInBlockComment) {
  149. if (j > 0 && doc.GetCharAt (j - 1) == '*')
  150. isInBlockComment = false;
  151. } else if (!isInString && !isInChar && j + 1 < doc.Length) {
  152. char nextChar = doc.GetCharAt (j + 1);
  153. if (nextChar == '/')
  154. isInLineComment = true;
  155. if (!isInLineComment && nextChar == '*')
  156. isInBlockComment = true;
  157. }
  158. break;
  159. case '\\':
  160. if (isInChar || (isInString && !isVerbatimString))
  161. j++;
  162. break;
  163. case '@':
  164. if (!(isInString || isInChar || isInLineComment || isInBlockComment) && j + 1 < doc.Length && doc.GetCharAt (j + 1) == '"') {
  165. isInString = true;
  166. isVerbatimString = true;
  167. j++;
  168. }
  169. break;
  170. case '"':
  171. if (!(isInChar || isInLineComment || isInBlockComment)) {
  172. if (isInString && isVerbatimString && j + 1 < doc.Length && doc.GetCharAt (j + 1) == '"') {
  173. j++;
  174. } else {
  175. isInString = !isInString;
  176. isVerbatimString = false;
  177. }
  178. }
  179. break;
  180. case '\'':
  181. if (!(isInString || isInLineComment || isInBlockComment))
  182. isInChar = !isInChar;
  183. break;
  184. case '{':
  185. if (!(isInString || isInChar || isInLineComment || isInBlockComment))
  186. brackets++;
  187. break;
  188. case '}':
  189. if (!(isInString || isInChar || isInLineComment || isInBlockComment))
  190. brackets--;
  191. break;
  192. }
  193. }
  194. if (brackets == 0) {
  195. FoundSpanEnd (cur, i, 1);
  196. return true;
  197. }
  198. return false;
  199. }
  200. }
  201. if (cur is ForcedJayBlockSpan) {
  202. if (textOffset + 1 < CurText.Length && CurText[textOffset] == '%' && CurText[textOffset + 1] == '}') {
  203. FoundSpanEnd (cur, i, 2);
  204. return true;
  205. }
  206. }
  207. if (cur is JayDefinitionSpan) {
  208. if (textOffset + 1 < CurText.Length && CurText[textOffset] == '%' && CurText[textOffset + 1] == '%') {
  209. FoundSpanEnd (cur, i, 2);
  210. return true;
  211. }
  212. }
  213. return base.ScanSpanEnd (cur, ref i);
  214. }
  215. }
  216. }
  217. }