java.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  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: Java
  32. Author: Vsevolod Solovyov <vsevolod.solovyov@gmail.com>
  33. Category: common, enterprise
  34. Website: https://www.java.com/
  35. */
  36. /**
  37. * Allows recursive regex expressions to a given depth
  38. *
  39. * ie: recurRegex("(abc~~~)", /~~~/g, 2) becomes:
  40. * (abc(abc(abc)))
  41. *
  42. * @param {string} re
  43. * @param {RegExp} substitution (should be a g mode regex)
  44. * @param {number} depth
  45. * @returns {string}``
  46. */
  47. function recurRegex(re, substitution, depth) {
  48. if (depth === -1) return "";
  49. return re.replace(substitution, _ => {
  50. return recurRegex(re, substitution, depth - 1);
  51. });
  52. }
  53. /** @type LanguageFn */
  54. function java(hljs) {
  55. const regex = hljs.regex;
  56. const JAVA_IDENT_RE = '[\u00C0-\u02B8a-zA-Z_$][\u00C0-\u02B8a-zA-Z_$0-9]*';
  57. const GENERIC_IDENT_RE = JAVA_IDENT_RE
  58. + recurRegex('(?:<' + JAVA_IDENT_RE + '~~~(?:\\s*,\\s*' + JAVA_IDENT_RE + '~~~)*>)?', /~~~/g, 2);
  59. const MAIN_KEYWORDS = [
  60. 'synchronized',
  61. 'abstract',
  62. 'private',
  63. 'var',
  64. 'static',
  65. 'if',
  66. 'const ',
  67. 'for',
  68. 'while',
  69. 'strictfp',
  70. 'finally',
  71. 'protected',
  72. 'import',
  73. 'native',
  74. 'final',
  75. 'void',
  76. 'enum',
  77. 'else',
  78. 'break',
  79. 'transient',
  80. 'catch',
  81. 'instanceof',
  82. 'volatile',
  83. 'case',
  84. 'assert',
  85. 'package',
  86. 'default',
  87. 'public',
  88. 'try',
  89. 'switch',
  90. 'continue',
  91. 'throws',
  92. 'protected',
  93. 'public',
  94. 'private',
  95. 'module',
  96. 'requires',
  97. 'exports',
  98. 'do',
  99. 'sealed',
  100. 'yield',
  101. 'permits',
  102. 'goto'
  103. ];
  104. const BUILT_INS = [
  105. 'super',
  106. 'this'
  107. ];
  108. const LITERALS = [
  109. 'false',
  110. 'true',
  111. 'null'
  112. ];
  113. const TYPES = [
  114. 'char',
  115. 'boolean',
  116. 'long',
  117. 'float',
  118. 'int',
  119. 'byte',
  120. 'short',
  121. 'double'
  122. ];
  123. const KEYWORDS = {
  124. keyword: MAIN_KEYWORDS,
  125. literal: LITERALS,
  126. type: TYPES,
  127. built_in: BUILT_INS
  128. };
  129. const ANNOTATION = {
  130. className: 'meta',
  131. begin: '@' + JAVA_IDENT_RE,
  132. contains: [
  133. {
  134. begin: /\(/,
  135. end: /\)/,
  136. contains: [ "self" ] // allow nested () inside our annotation
  137. }
  138. ]
  139. };
  140. const PARAMS = {
  141. className: 'params',
  142. begin: /\(/,
  143. end: /\)/,
  144. keywords: KEYWORDS,
  145. relevance: 0,
  146. contains: [ hljs.C_BLOCK_COMMENT_MODE ],
  147. endsParent: true
  148. };
  149. return {
  150. name: 'Java',
  151. aliases: [ 'jsp' ],
  152. keywords: KEYWORDS,
  153. illegal: /<\/|#/,
  154. contains: [
  155. hljs.COMMENT(
  156. '/\\*\\*',
  157. '\\*/',
  158. {
  159. relevance: 0,
  160. contains: [
  161. {
  162. // eat up @'s in emails to prevent them to be recognized as doctags
  163. begin: /\w+@/,
  164. relevance: 0
  165. },
  166. {
  167. className: 'doctag',
  168. begin: '@[A-Za-z]+'
  169. }
  170. ]
  171. }
  172. ),
  173. // relevance boost
  174. {
  175. begin: /import java\.[a-z]+\./,
  176. keywords: "import",
  177. relevance: 2
  178. },
  179. hljs.C_LINE_COMMENT_MODE,
  180. hljs.C_BLOCK_COMMENT_MODE,
  181. {
  182. begin: /"""/,
  183. end: /"""/,
  184. className: "string",
  185. contains: [ hljs.BACKSLASH_ESCAPE ]
  186. },
  187. hljs.APOS_STRING_MODE,
  188. hljs.QUOTE_STRING_MODE,
  189. {
  190. match: [
  191. /\b(?:class|interface|enum|extends|implements|new)/,
  192. /\s+/,
  193. JAVA_IDENT_RE
  194. ],
  195. className: {
  196. 1: "keyword",
  197. 3: "title.class"
  198. }
  199. },
  200. {
  201. // Exceptions for hyphenated keywords
  202. match: /non-sealed/,
  203. scope: "keyword"
  204. },
  205. {
  206. begin: [
  207. regex.concat(/(?!else)/, JAVA_IDENT_RE),
  208. /\s+/,
  209. JAVA_IDENT_RE,
  210. /\s+/,
  211. /=(?!=)/
  212. ],
  213. className: {
  214. 1: "type",
  215. 3: "variable",
  216. 5: "operator"
  217. }
  218. },
  219. {
  220. begin: [
  221. /record/,
  222. /\s+/,
  223. JAVA_IDENT_RE
  224. ],
  225. className: {
  226. 1: "keyword",
  227. 3: "title.class"
  228. },
  229. contains: [
  230. PARAMS,
  231. hljs.C_LINE_COMMENT_MODE,
  232. hljs.C_BLOCK_COMMENT_MODE
  233. ]
  234. },
  235. {
  236. // Expression keywords prevent 'keyword Name(...)' from being
  237. // recognized as a function definition
  238. beginKeywords: 'new throw return else',
  239. relevance: 0
  240. },
  241. {
  242. begin: [
  243. '(?:' + GENERIC_IDENT_RE + '\\s+)',
  244. hljs.UNDERSCORE_IDENT_RE,
  245. /\s*(?=\()/
  246. ],
  247. className: { 2: "title.function" },
  248. keywords: KEYWORDS,
  249. contains: [
  250. {
  251. className: 'params',
  252. begin: /\(/,
  253. end: /\)/,
  254. keywords: KEYWORDS,
  255. relevance: 0,
  256. contains: [
  257. ANNOTATION,
  258. hljs.APOS_STRING_MODE,
  259. hljs.QUOTE_STRING_MODE,
  260. NUMERIC,
  261. hljs.C_BLOCK_COMMENT_MODE
  262. ]
  263. },
  264. hljs.C_LINE_COMMENT_MODE,
  265. hljs.C_BLOCK_COMMENT_MODE
  266. ]
  267. },
  268. NUMERIC,
  269. ANNOTATION
  270. ]
  271. };
  272. }
  273. export { java as default };