d_highlight_rules.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Distributed under the BSD license:
  3. *
  4. * Copyright (c) 2012, Ajax.org B.V.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. * * Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * * Neither the name of Ajax.org B.V. nor the
  15. * names of its contributors may be used to endorse or promote products
  16. * derived from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. * ***** END LICENSE BLOCK ***** */
  30. define(function(require, exports, module) {
  31. "use strict";
  32. var oop = require("../lib/oop");
  33. var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
  34. var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;
  35. var DHighlightRules = function() {
  36. var keywords = (
  37. "this|super|import|module|body|mixin|__traits|invariant|alias|asm|delete|"+
  38. "typeof|typeid|sizeof|cast|new|in|is|typedef|__vector|__parameters"
  39. );
  40. var keywordControls = (
  41. "break|case|continue|default|do|else|for|foreach|foreach_reverse|goto|if|" +
  42. "return|switch|while|catch|try|throw|finally|version|assert|unittest|with"
  43. );
  44. var types = (
  45. "auto|bool|char|dchar|wchar|byte|ubyte|float|double|real|" +
  46. "cfloat|creal|cdouble|cent|ifloat|ireal|idouble|" +
  47. "int|long|short|void|uint|ulong|ushort|ucent|" +
  48. "function|delegate|string|wstring|dstring|size_t|ptrdiff_t|hash_t|Object"
  49. );
  50. var modifiers = (
  51. "abstract|align|debug|deprecated|export|extern|const|final|in|inout|out|" +
  52. "ref|immutable|lazy|nothrow|override|package|pragma|private|protected|" +
  53. "public|pure|scope|shared|__gshared|synchronized|static|volatile"
  54. );
  55. var storages = (
  56. "class|struct|union|template|interface|enum|macro"
  57. );
  58. var stringEscapesSeq = {
  59. token: "constant.language.escape",
  60. regex: "\\\\(?:(?:x[0-9A-F]{2})|(?:[0-7]{1,3})|(?:['\"\\?0abfnrtv\\\\])|" +
  61. "(?:u[0-9a-fA-F]{4})|(?:U[0-9a-fA-F]{8}))"
  62. };
  63. var builtinConstants = (
  64. "null|true|false|"+
  65. "__DATE__|__EOF__|__TIME__|__TIMESTAMP__|__VENDOR__|__VERSION__|"+
  66. "__FILE__|__MODULE__|__LINE__|__FUNCTION__|__PRETTY_FUNCTION__"
  67. );
  68. var operators = (
  69. "/|/\\=|&|&\\=|&&|\\|\\|\\=|\\|\\||\\-|\\-\\=|\\-\\-|\\+|" +
  70. "\\+\\=|\\+\\+|\\<|\\<\\=|\\<\\<|\\<\\<\\=|\\<\\>|\\<\\>\\=|\\>|\\>\\=|\\>\\>\\=|" +
  71. "\\>\\>\\>\\=|\\>\\>|\\>\\>\\>|\\!|\\!\\=|\\!\\<\\>|\\!\\<\\>\\=|\\!\\<|\\!\\<\\=|" +
  72. "\\!\\>|\\!\\>\\=|\\?|\\$|\\=|\\=\\=|\\*|\\*\\=|%|%\\=|" +
  73. "\\^|\\^\\=|\\^\\^|\\^\\^\\=|~|~\\=|\\=\\>|#"
  74. );
  75. var keywordMapper = this.$keywords = this.createKeywordMapper({
  76. "keyword.modifier" : modifiers,
  77. "keyword.control" : keywordControls,
  78. "keyword.type" : types,
  79. "keyword": keywords,
  80. "keyword.storage": storages,
  81. "punctation": "\\.|\\,|;|\\.\\.|\\.\\.\\.",
  82. "keyword.operator" : operators,
  83. "constant.language": builtinConstants
  84. }, "identifier");
  85. var identifierRe = "[a-zA-Z_\u00a1-\uffff][a-zA-Z\\d_\u00a1-\uffff]*\\b";
  86. // regexp must not have capturing parentheses. Use (?:) instead.
  87. // regexps are ordered -> the first match is used
  88. this.$rules = {
  89. "start" : [
  90. { //-------------------------------------------------------- COMMENTS
  91. token : "comment",
  92. regex : "\\/\\/.*$"
  93. },
  94. DocCommentHighlightRules.getStartRule("doc-start"),
  95. {
  96. token : "comment", // multi line comment
  97. regex : "\\/\\*",
  98. next : "star-comment"
  99. }, {
  100. token: "comment.shebang",
  101. regex: "^\s*#!.*"
  102. }, {
  103. token : "comment",
  104. regex : "\\/\\+",
  105. next: "plus-comment"
  106. }, { //-------------------------------------------------------- STRINGS
  107. onMatch: function(value, currentState, state) {
  108. state.unshift(this.next, value.substr(2));
  109. return "string";
  110. },
  111. regex: 'q"(?:[\\[\\(\\{\\<]+)',
  112. next: 'operator-heredoc-string'
  113. }, {
  114. onMatch: function(value, currentState, state) {
  115. state.unshift(this.next, value.substr(2));
  116. return "string";
  117. },
  118. regex: 'q"(?:[a-zA-Z_]+)$',
  119. next: 'identifier-heredoc-string'
  120. }, {
  121. token : "string", // multi line string start
  122. regex : '[xr]?"',
  123. next : "quote-string"
  124. }, {
  125. token : "string", // multi line string start
  126. regex : '[xr]?`',
  127. next : "backtick-string"
  128. }, {
  129. token : "string", // single line
  130. regex : "[xr]?['](?:(?:\\\\.)|(?:[^'\\\\]))*?['][cdw]?"
  131. }, { //-------------------------------------------------------- RULES
  132. token: ["keyword", "text", "paren.lparen"],
  133. regex: /(asm)(\s*)({)/,
  134. next: "d-asm"
  135. }, {
  136. token: ["keyword", "text", "paren.lparen", "constant.language"],
  137. regex: "(__traits)(\\s*)(\\()("+identifierRe+")"
  138. }, { // import|module abc
  139. token: ["keyword", "text", "variable.module"],
  140. regex: "(import|module)(\\s+)((?:"+identifierRe+"\\.?)*)"
  141. }, { // storage Name
  142. token: ["keyword.storage", "text", "entity.name.type"],
  143. regex: "("+storages+")(\\s*)("+identifierRe+")"
  144. }, { // alias|typedef foo bar;
  145. token: ["keyword", "text", "variable.storage", "text"],
  146. regex: "(alias|typedef)(\\s*)("+identifierRe+")(\\s*)"
  147. }, { //-------------------------------------------------------- OTHERS
  148. token : "constant.numeric", // hex
  149. regex : "0[xX][0-9a-fA-F_]+(l|ul|u|f|F|L|U|UL)?\\b"
  150. }, {
  151. token : "constant.numeric", // float
  152. regex : "[+-]?\\d[\\d_]*(?:(?:\\.[\\d_]*)?(?:[eE][+-]?[\\d_]+)?)?(l|ul|u|f|F|L|U|UL)?\\b"
  153. }, {
  154. token: "entity.other.attribute-name",
  155. regex: "@"+identifierRe
  156. }, {
  157. token : keywordMapper,
  158. regex : "[a-zA-Z_][a-zA-Z0-9_]*\\b"
  159. }, {
  160. token : "keyword.operator",
  161. regex : operators
  162. }, {
  163. token : "punctuation.operator",
  164. regex : "\\?|\\:|\\,|\\;|\\.|\\:"
  165. }, {
  166. token : "paren.lparen",
  167. regex : "[[({]"
  168. }, {
  169. token : "paren.rparen",
  170. regex : "[\\])}]"
  171. }, {
  172. token : "text",
  173. regex : "\\s+"
  174. }
  175. ],
  176. "star-comment" : [
  177. {
  178. token : "comment", // closing comment
  179. regex : "\\*\\/",
  180. next : "start"
  181. }, {
  182. defaultToken: 'comment'
  183. }
  184. ],
  185. "plus-comment" : [
  186. {
  187. token : "comment", // closing comment
  188. regex : "\\+\\/",
  189. next : "start"
  190. }, {
  191. defaultToken: 'comment'
  192. }
  193. ],
  194. "quote-string" : [
  195. stringEscapesSeq,
  196. {
  197. token : "string",
  198. regex : '"[cdw]?',
  199. next : "start"
  200. }, {
  201. defaultToken: 'string'
  202. }
  203. ],
  204. "backtick-string" : [
  205. stringEscapesSeq,
  206. {
  207. token : "string",
  208. regex : '`[cdw]?',
  209. next : "start"
  210. }, {
  211. defaultToken: 'string'
  212. }
  213. ],
  214. "operator-heredoc-string": [
  215. {
  216. onMatch: function(value, currentState, state) {
  217. value = value.substring(value.length-2, value.length-1);
  218. var map = {'>':'<',']':'[',')':'(','}':'{'};
  219. if(Object.keys(map).indexOf(value) != -1)
  220. value = map[value];
  221. if(value != state[1]) return "string";
  222. state.shift();
  223. state.shift();
  224. return "string";
  225. },
  226. regex: '(?:[\\]\\)}>]+)"',
  227. next: 'start'
  228. }, {
  229. token: 'string',
  230. regex: '[^\\]\\)}>]+'
  231. }
  232. ],
  233. "identifier-heredoc-string": [
  234. {
  235. onMatch: function(value, currentState, state) {
  236. value = value.substring(0, value.length-1);
  237. if(value != state[1]) return "string";
  238. state.shift();
  239. state.shift();
  240. return "string";
  241. },
  242. regex: '^(?:[A-Za-z_][a-zA-Z0-9]+)"',
  243. next: 'start'
  244. }, {
  245. token: 'string',
  246. regex: '[^\\]\\)}>]+'
  247. }
  248. ],
  249. "d-asm": [
  250. {
  251. token: "paren.rparen",
  252. regex: "\\}",
  253. next: "start"
  254. }, {
  255. token: 'keyword.instruction',
  256. regex: '[a-zA-Z]+',
  257. next: 'd-asm-instruction'
  258. }, {
  259. token: "text",
  260. regex: "\\s+"
  261. }
  262. ],
  263. // minimal asm support
  264. 'd-asm-instruction': [
  265. {
  266. token: 'constant.language',
  267. regex: /AL|AH|AX|EAX|BL|BH|BX|EBX|CL|CH|CX|ECX|DL|DH|DX|EDX|BP|EBP|SP|ESP|DI|EDI|SI|ESI/i
  268. }, {
  269. token: 'identifier',
  270. regex: '[a-zA-Z]+'
  271. }, {
  272. token: 'string',
  273. regex: '".*"'
  274. }, {
  275. token: 'comment',
  276. regex: '//.*$'
  277. }, {
  278. token: 'constant.numeric',
  279. regex: '[0-9.xA-F]+'
  280. }, {
  281. token: 'punctuation.operator',
  282. regex: '\\,'
  283. }, {
  284. token: 'punctuation.operator',
  285. regex: ';',
  286. next: 'd-asm'
  287. }, {
  288. token: 'text',
  289. regex: '\\s+'
  290. }
  291. ]
  292. };
  293. this.embedRules(DocCommentHighlightRules, "doc-",
  294. [ DocCommentHighlightRules.getEndRule("start") ]);
  295. };
  296. DHighlightRules.metaData = {
  297. comment: 'D language',
  298. fileTypes: [ 'd', 'di' ],
  299. firstLineMatch: '^#!.*\\b[glr]?dmd\\b.',
  300. foldingStartMarker: '(?x)/\\*\\*(?!\\*)|^(?![^{]*?//|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|//|/\\*(?!.*?\\*/.*\\S))',
  301. foldingStopMarker: '(?<!\\*)\\*\\*/|^\\s*\\}',
  302. keyEquivalent: '^~D',
  303. name: 'D',
  304. scopeName: 'source.d'
  305. };
  306. oop.inherits(DHighlightRules, TextHighlightRules);
  307. exports.DHighlightRules = DHighlightRules;
  308. });