coffeescript.js 6.7 KB

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