kotlin.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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.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. SUBST.contains.push(STRING)
  62. var ANNOTATION_USE_SITE = {
  63. className: 'meta', begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'
  64. };
  65. var ANNOTATION = {
  66. className: 'meta', begin: '@' + hljs.UNDERSCORE_IDENT_RE,
  67. contains: [
  68. {
  69. begin: /\(/, end: /\)/,
  70. contains: [
  71. hljs.inherit(STRING, {className: 'meta-string'})
  72. ]
  73. }
  74. ]
  75. };
  76. // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals
  77. // According to the doc above, the number mode of kotlin is the same as java 8,
  78. // so the code below is copied from java.js
  79. var KOTLIN_NUMBER_RE = '\\b' +
  80. '(' +
  81. '0[bB]([01]+[01_]+[01]+|[01]+)' + // 0b...
  82. '|' +
  83. '0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)' + // 0x...
  84. '|' +
  85. '(' +
  86. '([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?' +
  87. '|' +
  88. '\\.([\\d]+[\\d_]+[\\d]+|[\\d]+)' +
  89. ')' +
  90. '([eE][-+]?\\d+)?' + // octal, decimal, float
  91. ')' +
  92. '[lLfF]?';
  93. var KOTLIN_NUMBER_MODE = {
  94. className: 'number',
  95. begin: KOTLIN_NUMBER_RE,
  96. relevance: 0
  97. };
  98. var KOTLIN_NESTED_COMMENT = hljs.COMMENT(
  99. '/\\*', '\\*/',
  100. { contains: [ hljs.C_BLOCK_COMMENT_MODE ] }
  101. );
  102. var KOTLIN_PAREN_TYPE = {
  103. variants: [
  104. { className: 'type',
  105. begin: hljs.UNDERSCORE_IDENT_RE
  106. },
  107. { begin: /\(/, end: /\)/,
  108. contains: [] //defined later
  109. }
  110. ]
  111. };
  112. var KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;
  113. KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];
  114. KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];
  115. return {
  116. aliases: ['kt'],
  117. keywords: KEYWORDS,
  118. contains : [
  119. hljs.COMMENT(
  120. '/\\*\\*',
  121. '\\*/',
  122. {
  123. relevance : 0,
  124. contains : [{
  125. className : 'doctag',
  126. begin : '@[A-Za-z]+'
  127. }]
  128. }
  129. ),
  130. hljs.C_LINE_COMMENT_MODE,
  131. KOTLIN_NESTED_COMMENT,
  132. KEYWORDS_WITH_LABEL,
  133. LABEL,
  134. ANNOTATION_USE_SITE,
  135. ANNOTATION,
  136. {
  137. className: 'function',
  138. beginKeywords: 'fun', end: '[(]|$',
  139. returnBegin: true,
  140. excludeEnd: true,
  141. keywords: KEYWORDS,
  142. illegal: /fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,
  143. relevance: 5,
  144. contains: [
  145. {
  146. begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(', returnBegin: true,
  147. relevance: 0,
  148. contains: [hljs.UNDERSCORE_TITLE_MODE]
  149. },
  150. {
  151. className: 'type',
  152. begin: /</, end: />/, keywords: 'reified',
  153. relevance: 0
  154. },
  155. {
  156. className: 'params',
  157. begin: /\(/, end: /\)/,
  158. endsParent: true,
  159. keywords: KEYWORDS,
  160. relevance: 0,
  161. contains: [
  162. {
  163. begin: /:/, end: /[=,\/]/, endsWithParent: true,
  164. contains: [
  165. KOTLIN_PAREN_TYPE,
  166. hljs.C_LINE_COMMENT_MODE,
  167. KOTLIN_NESTED_COMMENT
  168. ],
  169. relevance: 0
  170. },
  171. hljs.C_LINE_COMMENT_MODE,
  172. KOTLIN_NESTED_COMMENT,
  173. ANNOTATION_USE_SITE,
  174. ANNOTATION,
  175. STRING,
  176. hljs.C_NUMBER_MODE
  177. ]
  178. },
  179. KOTLIN_NESTED_COMMENT
  180. ]
  181. },
  182. {
  183. className: 'class',
  184. beginKeywords: 'class interface trait', end: /[:\{(]|$/, // remove 'trait' when removed from KEYWORDS
  185. excludeEnd: true,
  186. illegal: 'extends implements',
  187. contains: [
  188. {beginKeywords: 'public protected internal private constructor'},
  189. hljs.UNDERSCORE_TITLE_MODE,
  190. {
  191. className: 'type',
  192. begin: /</, end: />/, excludeBegin: true, excludeEnd: true,
  193. relevance: 0
  194. },
  195. {
  196. className: 'type',
  197. begin: /[,:]\s*/, end: /[<\(,]|$/, excludeBegin: true, returnEnd: true
  198. },
  199. ANNOTATION_USE_SITE,
  200. ANNOTATION
  201. ]
  202. },
  203. STRING,
  204. {
  205. className: 'meta',
  206. begin: "^#!/usr/bin/env", end: '$',
  207. illegal: '\n'
  208. },
  209. KOTLIN_NUMBER_MODE
  210. ]
  211. };
  212. };