kotlin.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // https://docs.oracle.com/javase/specs/jls/se15/html/jls-3.html#jls-3.10
  2. var decimalDigits = '[0-9](_*[0-9])*';
  3. var frac = `\\.(${decimalDigits})`;
  4. var hexDigits = '[0-9a-fA-F](_*[0-9a-fA-F])*';
  5. var NUMERIC = {
  6. className: 'number',
  7. variants: [
  8. // DecimalFloatingPointLiteral
  9. // including ExponentPart
  10. { begin: `(\\b(${decimalDigits})((${frac})|\\.)?|(${frac}))` +
  11. `[eE][+-]?(${decimalDigits})[fFdD]?\\b` },
  12. // excluding ExponentPart
  13. { begin: `\\b(${decimalDigits})((${frac})[fFdD]?\\b|\\.([fFdD]\\b)?)` },
  14. { begin: `(${frac})[fFdD]?\\b` },
  15. { begin: `\\b(${decimalDigits})[fFdD]\\b` },
  16. // HexadecimalFloatingPointLiteral
  17. { begin: `\\b0[xX]((${hexDigits})\\.?|(${hexDigits})?\\.(${hexDigits}))` +
  18. `[pP][+-]?(${decimalDigits})[fFdD]?\\b` },
  19. // DecimalIntegerLiteral
  20. { begin: '\\b(0|[1-9](_*[0-9])*)[lL]?\\b' },
  21. // HexIntegerLiteral
  22. { begin: `\\b0[xX](${hexDigits})[lL]?\\b` },
  23. // OctalIntegerLiteral
  24. { begin: '\\b0(_*[0-7])*[lL]?\\b' },
  25. // BinaryIntegerLiteral
  26. { begin: '\\b0[bB][01](_*[01])*[lL]?\\b' },
  27. ],
  28. relevance: 0
  29. };
  30. /*
  31. Language: Kotlin
  32. Description: Kotlin is an OSS statically typed programming language that targets the JVM, Android, JavaScript and Native.
  33. Author: Sergey Mashkov <cy6erGn0m@gmail.com>
  34. Website: https://kotlinlang.org
  35. Category: common
  36. */
  37. function kotlin(hljs) {
  38. const KEYWORDS = {
  39. keyword:
  40. 'abstract as val var vararg get set class object open private protected public noinline '
  41. + 'crossinline dynamic final enum if else do while for when throw try catch finally '
  42. + 'import package is in fun override companion reified inline lateinit init '
  43. + 'interface annotation data sealed internal infix operator out by constructor super '
  44. + 'tailrec where const inner suspend typealias external expect actual',
  45. built_in:
  46. 'Byte Short Char Int Long Boolean Float Double Void Unit Nothing',
  47. literal:
  48. 'true false null'
  49. };
  50. const KEYWORDS_WITH_LABEL = {
  51. className: 'keyword',
  52. begin: /\b(break|continue|return|this)\b/,
  53. starts: { contains: [
  54. {
  55. className: 'symbol',
  56. begin: /@\w+/
  57. }
  58. ] }
  59. };
  60. const LABEL = {
  61. className: 'symbol',
  62. begin: hljs.UNDERSCORE_IDENT_RE + '@'
  63. };
  64. // for string templates
  65. const SUBST = {
  66. className: 'subst',
  67. begin: /\$\{/,
  68. end: /\}/,
  69. contains: [ hljs.C_NUMBER_MODE ]
  70. };
  71. const VARIABLE = {
  72. className: 'variable',
  73. begin: '\\$' + hljs.UNDERSCORE_IDENT_RE
  74. };
  75. const STRING = {
  76. className: 'string',
  77. variants: [
  78. {
  79. begin: '"""',
  80. end: '"""(?=[^"])',
  81. contains: [
  82. VARIABLE,
  83. SUBST
  84. ]
  85. },
  86. // Can't use built-in modes easily, as we want to use STRING in the meta
  87. // context as 'meta-string' and there's no syntax to remove explicitly set
  88. // classNames in built-in modes.
  89. {
  90. begin: '\'',
  91. end: '\'',
  92. illegal: /\n/,
  93. contains: [ hljs.BACKSLASH_ESCAPE ]
  94. },
  95. {
  96. begin: '"',
  97. end: '"',
  98. illegal: /\n/,
  99. contains: [
  100. hljs.BACKSLASH_ESCAPE,
  101. VARIABLE,
  102. SUBST
  103. ]
  104. }
  105. ]
  106. };
  107. SUBST.contains.push(STRING);
  108. const ANNOTATION_USE_SITE = {
  109. className: 'meta',
  110. begin: '@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*' + hljs.UNDERSCORE_IDENT_RE + ')?'
  111. };
  112. const ANNOTATION = {
  113. className: 'meta',
  114. begin: '@' + hljs.UNDERSCORE_IDENT_RE,
  115. contains: [
  116. {
  117. begin: /\(/,
  118. end: /\)/,
  119. contains: [
  120. hljs.inherit(STRING, { className: 'string' }),
  121. "self"
  122. ]
  123. }
  124. ]
  125. };
  126. // https://kotlinlang.org/docs/reference/whatsnew11.html#underscores-in-numeric-literals
  127. // According to the doc above, the number mode of kotlin is the same as java 8,
  128. // so the code below is copied from java.js
  129. const KOTLIN_NUMBER_MODE = NUMERIC;
  130. const KOTLIN_NESTED_COMMENT = hljs.COMMENT(
  131. '/\\*', '\\*/',
  132. { contains: [ hljs.C_BLOCK_COMMENT_MODE ] }
  133. );
  134. const KOTLIN_PAREN_TYPE = { variants: [
  135. {
  136. className: 'type',
  137. begin: hljs.UNDERSCORE_IDENT_RE
  138. },
  139. {
  140. begin: /\(/,
  141. end: /\)/,
  142. contains: [] // defined later
  143. }
  144. ] };
  145. const KOTLIN_PAREN_TYPE2 = KOTLIN_PAREN_TYPE;
  146. KOTLIN_PAREN_TYPE2.variants[1].contains = [ KOTLIN_PAREN_TYPE ];
  147. KOTLIN_PAREN_TYPE.variants[1].contains = [ KOTLIN_PAREN_TYPE2 ];
  148. return {
  149. name: 'Kotlin',
  150. aliases: [
  151. 'kt',
  152. 'kts'
  153. ],
  154. keywords: KEYWORDS,
  155. contains: [
  156. hljs.COMMENT(
  157. '/\\*\\*',
  158. '\\*/',
  159. {
  160. relevance: 0,
  161. contains: [
  162. {
  163. className: 'doctag',
  164. begin: '@[A-Za-z]+'
  165. }
  166. ]
  167. }
  168. ),
  169. hljs.C_LINE_COMMENT_MODE,
  170. KOTLIN_NESTED_COMMENT,
  171. KEYWORDS_WITH_LABEL,
  172. LABEL,
  173. ANNOTATION_USE_SITE,
  174. ANNOTATION,
  175. {
  176. className: 'function',
  177. beginKeywords: 'fun',
  178. end: '[(]|$',
  179. returnBegin: true,
  180. excludeEnd: true,
  181. keywords: KEYWORDS,
  182. relevance: 5,
  183. contains: [
  184. {
  185. begin: hljs.UNDERSCORE_IDENT_RE + '\\s*\\(',
  186. returnBegin: true,
  187. relevance: 0,
  188. contains: [ hljs.UNDERSCORE_TITLE_MODE ]
  189. },
  190. {
  191. className: 'type',
  192. begin: /</,
  193. end: />/,
  194. keywords: 'reified',
  195. relevance: 0
  196. },
  197. {
  198. className: 'params',
  199. begin: /\(/,
  200. end: /\)/,
  201. endsParent: true,
  202. keywords: KEYWORDS,
  203. relevance: 0,
  204. contains: [
  205. {
  206. begin: /:/,
  207. end: /[=,\/]/,
  208. endsWithParent: true,
  209. contains: [
  210. KOTLIN_PAREN_TYPE,
  211. hljs.C_LINE_COMMENT_MODE,
  212. KOTLIN_NESTED_COMMENT
  213. ],
  214. relevance: 0
  215. },
  216. hljs.C_LINE_COMMENT_MODE,
  217. KOTLIN_NESTED_COMMENT,
  218. ANNOTATION_USE_SITE,
  219. ANNOTATION,
  220. STRING,
  221. hljs.C_NUMBER_MODE
  222. ]
  223. },
  224. KOTLIN_NESTED_COMMENT
  225. ]
  226. },
  227. {
  228. begin: [
  229. /class|interface|trait/,
  230. /\s+/,
  231. hljs.UNDERSCORE_IDENT_RE
  232. ],
  233. beginScope: {
  234. 3: "title.class"
  235. },
  236. keywords: 'class interface trait',
  237. end: /[:\{(]|$/,
  238. excludeEnd: true,
  239. illegal: 'extends implements',
  240. contains: [
  241. { beginKeywords: 'public protected internal private constructor' },
  242. hljs.UNDERSCORE_TITLE_MODE,
  243. {
  244. className: 'type',
  245. begin: /</,
  246. end: />/,
  247. excludeBegin: true,
  248. excludeEnd: true,
  249. relevance: 0
  250. },
  251. {
  252. className: 'type',
  253. begin: /[,:]\s*/,
  254. end: /[<\(,){\s]|$/,
  255. excludeBegin: true,
  256. returnEnd: true
  257. },
  258. ANNOTATION_USE_SITE,
  259. ANNOTATION
  260. ]
  261. },
  262. STRING,
  263. {
  264. className: 'meta',
  265. begin: "^#!/usr/bin/env",
  266. end: '$',
  267. illegal: '\n'
  268. },
  269. KOTLIN_NUMBER_MODE
  270. ]
  271. };
  272. }
  273. export { kotlin as default };