kotlin.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. module.exports = function(hljs) {
  2. var KEYWORDS = {
  3. keyword:
  4. 'abstract as val var vararg get set class object open private protected public noinline ' +
  5. 'crossinline dynamic final enum if else do while for when throw try catch finally ' +
  6. 'import package is in fun override companion reified inline lateinit init ' +
  7. 'interface annotation data sealed internal infix operator out by constructor super ' +
  8. 'tailrec where const inner suspend typealias external expect actual ' +
  9. // to be deleted soon
  10. 'trait volatile transient native default',
  11. built_in:
  12. 'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',
  13. literal:
  14. 'true false null'
  15. };
  16. var KEYWORDS_WITH_LABEL = {
  17. className: 'keyword',
  18. begin: /\b(break|continue|return|this)\b/,
  19. starts: {
  20. contains: [
  21. {
  22. className: 'symbol',
  23. begin: /@\w+/
  24. }
  25. ]
  26. }
  27. };
  28. var LABEL = {
  29. className: 'symbol', begin: hljs.UNDERSCORE_IDENT_RE + '@'
  30. };
  31. // for string templates
  32. var SUBST = {
  33. className: 'subst',
  34. begin: '\\${', end: '}', contains: [hljs.APOS_STRING_MODE, hljs.C_NUMBER_MODE]
  35. };
  36. var VARIABLE = {
  37. className: 'variable', begin: '\\$' + hljs.UNDERSCORE_IDENT_RE
  38. };
  39. var STRING = {
  40. className: 'string',
  41. variants: [
  42. {
  43. begin: '"""', end: '"""',
  44. contains: [VARIABLE, SUBST]
  45. },
  46. // Can't use built-in modes easily, as we want to use STRING in the meta
  47. // context as 'meta-string' and there's no syntax to remove explicitly set
  48. // classNames in built-in modes.
  49. {
  50. begin: '\'', end: '\'',
  51. illegal: /\n/,
  52. contains: [hljs.BACKSLASH_ESCAPE]
  53. },
  54. {
  55. begin: '"', end: '"',
  56. illegal: /\n/,
  57. contains: [hljs.BACKSLASH_ESCAPE, VARIABLE, SUBST]
  58. }
  59. ]
  60. };
  61. var ANNOTATION_USE_SITE = {
  62. className: 'meta', begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'
  63. };
  64. var ANNOTATION = {
  65. className: 'meta', begin: '@' + hljs.UNDERSCORE_IDENT_RE,
  66. contains: [
  67. {
  68. begin: /\(/, end: /\)/,
  69. contains: [
  70. hljs.inherit(STRING, {className: 'meta-string'})
  71. ]
  72. }
  73. ]
  74. };
  75. // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals
  76. // According to the doc above, the number mode of kotlin is the same as java 8,
  77. // so the code below is copied from java.js
  78. var KOTLIN_NUMBER_RE = '\\b' +
  79. '(' +
  80. '0[bB]([01]+[01_]+[01]+|[01]+)' + // 0b...
  81. '|' +
  82. '0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)' + // 0x...
  83. '|' +
  84. '(' +
  85. '([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?' +
  86. '|' +
  87. '\\.([\\d]+[\\d_]+[\\d]+|[\\d]+)' +
  88. ')' +
  89. '([eE][-+]?\\d+)?' + // octal, decimal, float
  90. ')' +
  91. '[lLfF]?';
  92. var KOTLIN_NUMBER_MODE = {
  93. className: 'number',
  94. begin: KOTLIN_NUMBER_RE,
  95. relevance: 0
  96. };
  97. return {
  98. aliases: ['kt'],
  99. keywords: KEYWORDS,
  100. contains : [
  101. hljs.COMMENT(
  102. '/\\*\\*',
  103. '\\*/',
  104. {
  105. relevance : 0,
  106. contains : [{
  107. className : 'doctag',
  108. begin : '@[A-Za-z]+'
  109. }]
  110. }
  111. ),
  112. hljs.C_LINE_COMMENT_MODE,
  113. hljs.C_BLOCK_COMMENT_MODE,
  114. KEYWORDS_WITH_LABEL,
  115. LABEL,
  116. ANNOTATION_USE_SITE,
  117. ANNOTATION,
  118. {
  119. className: 'function',
  120. beginKeywords: 'fun', end: '[(]|$',
  121. returnBegin: true,
  122. excludeEnd: true,
  123. keywords: KEYWORDS,
  124. illegal: /fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,
  125. relevance: 5,
  126. contains: [
  127. {
  128. begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true,
  129. relevance: 0,
  130. contains: [hljs.UNDERSCORE_TITLE_MODE]
  131. },
  132. {
  133. className: 'type',
  134. begin: /</, end: />/, keywords: 'reified',
  135. relevance: 0
  136. },
  137. {
  138. className: 'params',
  139. begin: /\(/, end: /\)/,
  140. endsParent: true,
  141. keywords: KEYWORDS,
  142. relevance: 0,
  143. contains: [
  144. {
  145. begin: /:/, end: /[=,\/]/, endsWithParent: true,
  146. contains: [
  147. {className: 'type', begin: hljs.UNDERSCORE_IDENT_RE},
  148. hljs.C_LINE_COMMENT_MODE,
  149. hljs.C_BLOCK_COMMENT_MODE
  150. ],
  151. relevance: 0
  152. },
  153. hljs.C_LINE_COMMENT_MODE,
  154. hljs.C_BLOCK_COMMENT_MODE,
  155. ANNOTATION_USE_SITE,
  156. ANNOTATION,
  157. STRING,
  158. hljs.C_NUMBER_MODE
  159. ]
  160. },
  161. hljs.C_BLOCK_COMMENT_MODE
  162. ]
  163. },
  164. {
  165. className: 'class',
  166. beginKeywords: 'class interface trait', end: /[:\{(]|$/, // remove 'trait' when removed from KEYWORDS
  167. excludeEnd: true,
  168. illegal: 'extends implements',
  169. contains: [
  170. {beginKeywords: 'public protected internal private constructor'},
  171. hljs.UNDERSCORE_TITLE_MODE,
  172. {
  173. className: 'type',
  174. begin: /</, end: />/, excludeBegin: true, excludeEnd: true,
  175. relevance: 0
  176. },
  177. {
  178. className: 'type',
  179. begin: /[,:]\s*/, end: /[<\(,]|$/, excludeBegin: true, returnEnd: true
  180. },
  181. ANNOTATION_USE_SITE,
  182. ANNOTATION
  183. ]
  184. },
  185. STRING,
  186. {
  187. className: 'meta',
  188. begin: "^#!/usr/bin/env", end: '$',
  189. illegal: '\n'
  190. },
  191. KOTLIN_NUMBER_MODE
  192. ]
  193. };
  194. };