coffeescript.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. const KEYWORDS = [
  2. "as", // for exports
  3. "in",
  4. "of",
  5. "if",
  6. "for",
  7. "while",
  8. "finally",
  9. "var",
  10. "new",
  11. "function",
  12. "do",
  13. "return",
  14. "void",
  15. "else",
  16. "break",
  17. "catch",
  18. "instanceof",
  19. "with",
  20. "throw",
  21. "case",
  22. "default",
  23. "try",
  24. "switch",
  25. "continue",
  26. "typeof",
  27. "delete",
  28. "let",
  29. "yield",
  30. "const",
  31. "class",
  32. // JS handles these with a special rule
  33. // "get",
  34. // "set",
  35. "debugger",
  36. "async",
  37. "await",
  38. "static",
  39. "import",
  40. "from",
  41. "export",
  42. "extends"
  43. ];
  44. const LITERALS = [
  45. "true",
  46. "false",
  47. "null",
  48. "undefined",
  49. "NaN",
  50. "Infinity"
  51. ];
  52. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
  53. const TYPES = [
  54. // Fundamental objects
  55. "Object",
  56. "Function",
  57. "Boolean",
  58. "Symbol",
  59. // numbers and dates
  60. "Math",
  61. "Date",
  62. "Number",
  63. "BigInt",
  64. // text
  65. "String",
  66. "RegExp",
  67. // Indexed collections
  68. "Array",
  69. "Float32Array",
  70. "Float64Array",
  71. "Int8Array",
  72. "Uint8Array",
  73. "Uint8ClampedArray",
  74. "Int16Array",
  75. "Int32Array",
  76. "Uint16Array",
  77. "Uint32Array",
  78. "BigInt64Array",
  79. "BigUint64Array",
  80. // Keyed collections
  81. "Set",
  82. "Map",
  83. "WeakSet",
  84. "WeakMap",
  85. // Structured data
  86. "ArrayBuffer",
  87. "SharedArrayBuffer",
  88. "Atomics",
  89. "DataView",
  90. "JSON",
  91. // Control abstraction objects
  92. "Promise",
  93. "Generator",
  94. "GeneratorFunction",
  95. "AsyncFunction",
  96. // Reflection
  97. "Reflect",
  98. "Proxy",
  99. // Internationalization
  100. "Intl",
  101. // WebAssembly
  102. "WebAssembly"
  103. ];
  104. const ERROR_TYPES = [
  105. "Error",
  106. "EvalError",
  107. "InternalError",
  108. "RangeError",
  109. "ReferenceError",
  110. "SyntaxError",
  111. "TypeError",
  112. "URIError"
  113. ];
  114. const BUILT_IN_GLOBALS = [
  115. "setInterval",
  116. "setTimeout",
  117. "clearInterval",
  118. "clearTimeout",
  119. "require",
  120. "exports",
  121. "eval",
  122. "isFinite",
  123. "isNaN",
  124. "parseFloat",
  125. "parseInt",
  126. "decodeURI",
  127. "decodeURIComponent",
  128. "encodeURI",
  129. "encodeURIComponent",
  130. "escape",
  131. "unescape"
  132. ];
  133. const BUILT_INS = [].concat(
  134. BUILT_IN_GLOBALS,
  135. TYPES,
  136. ERROR_TYPES
  137. );
  138. /*
  139. Language: CoffeeScript
  140. Author: Dmytrii Nagirniak <dnagir@gmail.com>
  141. Contributors: Oleg Efimov <efimovov@gmail.com>, Cédric Néhémie <cedric.nehemie@gmail.com>
  142. Description: CoffeeScript is a programming language that transcompiles to JavaScript. For info about language see http://coffeescript.org/
  143. Category: scripting
  144. Website: https://coffeescript.org
  145. */
  146. /** @type LanguageFn */
  147. function coffeescript(hljs) {
  148. const COFFEE_BUILT_INS = [
  149. 'npm',
  150. 'print'
  151. ];
  152. const COFFEE_LITERALS = [
  153. 'yes',
  154. 'no',
  155. 'on',
  156. 'off'
  157. ];
  158. const COFFEE_KEYWORDS = [
  159. 'then',
  160. 'unless',
  161. 'until',
  162. 'loop',
  163. 'by',
  164. 'when',
  165. 'and',
  166. 'or',
  167. 'is',
  168. 'isnt',
  169. 'not'
  170. ];
  171. const NOT_VALID_KEYWORDS = [
  172. "var",
  173. "const",
  174. "let",
  175. "function",
  176. "static"
  177. ];
  178. const excluding = (list) =>
  179. (kw) => !list.includes(kw);
  180. const KEYWORDS$1 = {
  181. keyword: KEYWORDS.concat(COFFEE_KEYWORDS).filter(excluding(NOT_VALID_KEYWORDS)),
  182. literal: LITERALS.concat(COFFEE_LITERALS),
  183. built_in: BUILT_INS.concat(COFFEE_BUILT_INS)
  184. };
  185. const JS_IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*';
  186. const SUBST = {
  187. className: 'subst',
  188. begin: /#\{/,
  189. end: /\}/,
  190. keywords: KEYWORDS$1
  191. };
  192. const EXPRESSIONS = [
  193. hljs.BINARY_NUMBER_MODE,
  194. hljs.inherit(hljs.C_NUMBER_MODE, { starts: {
  195. end: '(\\s*/)?',
  196. relevance: 0
  197. } }), // a number tries to eat the following slash to prevent treating it as a regexp
  198. {
  199. className: 'string',
  200. variants: [
  201. {
  202. begin: /'''/,
  203. end: /'''/,
  204. contains: [ hljs.BACKSLASH_ESCAPE ]
  205. },
  206. {
  207. begin: /'/,
  208. end: /'/,
  209. contains: [ hljs.BACKSLASH_ESCAPE ]
  210. },
  211. {
  212. begin: /"""/,
  213. end: /"""/,
  214. contains: [
  215. hljs.BACKSLASH_ESCAPE,
  216. SUBST
  217. ]
  218. },
  219. {
  220. begin: /"/,
  221. end: /"/,
  222. contains: [
  223. hljs.BACKSLASH_ESCAPE,
  224. SUBST
  225. ]
  226. }
  227. ]
  228. },
  229. {
  230. className: 'regexp',
  231. variants: [
  232. {
  233. begin: '///',
  234. end: '///',
  235. contains: [
  236. SUBST,
  237. hljs.HASH_COMMENT_MODE
  238. ]
  239. },
  240. {
  241. begin: '//[gim]{0,3}(?=\\W)',
  242. relevance: 0
  243. },
  244. {
  245. // regex can't start with space to parse x / 2 / 3 as two divisions
  246. // regex can't start with *, and it supports an "illegal" in the main mode
  247. begin: /\/(?![ *]).*?(?![\\]).\/[gim]{0,3}(?=\W)/ }
  248. ]
  249. },
  250. { begin: '@' + JS_IDENT_RE // relevance booster
  251. },
  252. {
  253. subLanguage: 'javascript',
  254. excludeBegin: true,
  255. excludeEnd: true,
  256. variants: [
  257. {
  258. begin: '```',
  259. end: '```'
  260. },
  261. {
  262. begin: '`',
  263. end: '`'
  264. }
  265. ]
  266. }
  267. ];
  268. SUBST.contains = EXPRESSIONS;
  269. const TITLE = hljs.inherit(hljs.TITLE_MODE, { begin: JS_IDENT_RE });
  270. const POSSIBLE_PARAMS_RE = '(\\(.*\\)\\s*)?\\B[-=]>';
  271. const PARAMS = {
  272. className: 'params',
  273. begin: '\\([^\\(]',
  274. returnBegin: true,
  275. /* We need another contained nameless mode to not have every nested
  276. pair of parens to be called "params" */
  277. contains: [
  278. {
  279. begin: /\(/,
  280. end: /\)/,
  281. keywords: KEYWORDS$1,
  282. contains: [ 'self' ].concat(EXPRESSIONS)
  283. }
  284. ]
  285. };
  286. const CLASS_DEFINITION = {
  287. variants: [
  288. { match: [
  289. /class\s+/,
  290. JS_IDENT_RE,
  291. /\s+extends\s+/,
  292. JS_IDENT_RE
  293. ] },
  294. { match: [
  295. /class\s+/,
  296. JS_IDENT_RE
  297. ] }
  298. ],
  299. scope: {
  300. 2: "title.class",
  301. 4: "title.class.inherited"
  302. },
  303. keywords: KEYWORDS$1
  304. };
  305. return {
  306. name: 'CoffeeScript',
  307. aliases: [
  308. 'coffee',
  309. 'cson',
  310. 'iced'
  311. ],
  312. keywords: KEYWORDS$1,
  313. illegal: /\/\*/,
  314. contains: [
  315. ...EXPRESSIONS,
  316. hljs.COMMENT('###', '###'),
  317. hljs.HASH_COMMENT_MODE,
  318. {
  319. className: 'function',
  320. begin: '^\\s*' + JS_IDENT_RE + '\\s*=\\s*' + POSSIBLE_PARAMS_RE,
  321. end: '[-=]>',
  322. returnBegin: true,
  323. contains: [
  324. TITLE,
  325. PARAMS
  326. ]
  327. },
  328. {
  329. // anonymous function start
  330. begin: /[:\(,=]\s*/,
  331. relevance: 0,
  332. contains: [
  333. {
  334. className: 'function',
  335. begin: POSSIBLE_PARAMS_RE,
  336. end: '[-=]>',
  337. returnBegin: true,
  338. contains: [ PARAMS ]
  339. }
  340. ]
  341. },
  342. CLASS_DEFINITION,
  343. {
  344. begin: JS_IDENT_RE + ':',
  345. end: ':',
  346. returnBegin: true,
  347. returnEnd: true,
  348. relevance: 0
  349. }
  350. ]
  351. };
  352. }
  353. export { coffeescript as default };