1 /*! `typescript` grammar compiled for Highlight.js 11.11.1 */
3 var hljsGrammar
= (function () {
6 const IDENT_RE
= '[A-Za-z$_][0-9A-Za-z$_]*';
38 // JS handles these with a special rule
49 // It's reached stage 3, which is "recommended for implementation":
61 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
63 // Fundamental objects
76 // Indexed collections
100 // Control abstraction objects
108 // Internationalization
114 const ERROR_TYPES
= [
125 const BUILT_IN_GLOBALS
= [
140 "decodeURIComponent",
142 "encodeURIComponent",
147 const BUILT_IN_VARIABLES
= [
160 const BUILT_INS
= [].concat(
168 Description: JavaScript (JS) is a lightweight, interpreted, or just-in-time compiled programming language with first-class functions.
169 Category: common, scripting, web
170 Website: https://developer.mozilla.org/en-US/docs/Web/JavaScript
174 /** @type LanguageFn */
175 function javascript(hljs
) {
176 const regex
= hljs
.regex
;
178 * Takes a string like "<Booger" and checks to see
179 * if we can find a matching "</Booger" later in the
181 * @param {RegExpMatchArray} match
182 * @param {{after:number}} param1
184 const hasClosingTag
= (match
, { after
}) => {
185 const tag
= "</" + match
[0].slice(1);
186 const pos
= match
.input
.indexOf(tag
, after
);
190 const IDENT_RE
$1 = IDENT_RE
;
195 // to avoid some special cases inside isTrulyOpeningTag
196 const XML_SELF_CLOSING
= /<[A-Za-z0-9\\._:-]+\s*\/>/;
198 begin: /<[A-Za-z0-9\\._:-]+/,
199 end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
201 * @param {RegExpMatchArray} match
202 * @param {CallbackResponse} response
204 isTrulyOpeningTag: (match
, response
) => {
205 const afterMatchIndex
= match
[0].length
+ match
.index
;
206 const nextChar
= match
.input
[afterMatchIndex
];
208 // HTML should not include another raw `<` inside a tag
210 // `<Array<Array<number>>`, etc.
212 // the , gives away that this is not HTML
213 // `<T, A extends keyof T, V>`
216 response
.ignoreMatch();
221 // Quite possibly a tag, lets look for a matching closing tag...
222 if (nextChar
=== ">") {
223 // if we cannot find a matching closing tag, then we
225 if (!hasClosingTag(match
, { after: afterMatchIndex
})) {
226 response
.ignoreMatch();
230 // `<blah />` (self-closing)
231 // handled by simpleSelfClosing rule
234 const afterMatch
= match
.input
.substring(afterMatchIndex
);
236 // some more template typing stuff
237 // <T = any>(key?: string) => Modify<
238 if ((m
= afterMatch
.match(/^\s*=/))) {
239 response
.ignoreMatch();
243 // `<From extends string>`
244 // technically this could be HTML, but it smells like a type
245 // NOTE: This is ugh, but added specifically for https://github.com/highlightjs/highlight.js/issues/3276
246 if ((m
= afterMatch
.match(/^\s+extends\s+/))) {
248 response
.ignoreMatch();
249 // eslint-disable-next-line no-useless-return
260 "variable.language": BUILT_IN_VARIABLES
263 // https://tc39.es/ecma262/#sec-literals-numeric-literals
264 const decimalDigits
= '[0-9](_?[0-9])*';
265 const frac
= `\\.(${decimalDigits})`;
266 // DecimalIntegerLiteral, including Annex B NonOctalDecimalIntegerLiteral
267 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
268 const decimalInteger
= `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;
273 { begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))` +
274 `[eE][+-]?(${decimalDigits})\\b` },
275 { begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` },
277 // DecimalBigIntegerLiteral
278 { begin: `\\b(0|[1-9](_?[0-9])*)n\\b` },
280 // NonDecimalIntegerLiteral
281 { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" },
282 { begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" },
283 { begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" },
285 // LegacyOctalIntegerLiteral (does not include underscore separators)
286 // https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
287 { begin: "\\b0[0-7]+n?\\b" },
296 keywords: KEYWORDS
$1,
297 contains: [] // defined later
299 const HTML_TEMPLATE
= {
306 hljs
.BACKSLASH_ESCAPE
,
312 const CSS_TEMPLATE
= {
319 hljs
.BACKSLASH_ESCAPE
,
325 const GRAPHQL_TEMPLATE
= {
332 hljs
.BACKSLASH_ESCAPE
,
335 subLanguage: 'graphql'
338 const TEMPLATE_STRING
= {
343 hljs
.BACKSLASH_ESCAPE
,
347 const JSDOC_COMMENT
= hljs
.COMMENT(
354 begin: '(?=@[A-Za-z]+)',
370 className: 'variable',
371 begin: IDENT_RE
$1 + '(?=\\s*(-)|$)',
375 // eat spaces (not newlines) so we can find
376 // types or variables
378 begin: /(?=[^\n])\s/,
387 className: "comment",
390 hljs
.C_BLOCK_COMMENT_MODE
,
391 hljs
.C_LINE_COMMENT_MODE
394 const SUBST_INTERNALS
= [
395 hljs
.APOS_STRING_MODE
,
396 hljs
.QUOTE_STRING_MODE
,
401 // Skip numbers when they are part of a variable name
404 // This is intentional:
405 // See https://github.com/highlightjs/highlight.js/issues/3288
408 SUBST
.contains
= SUBST_INTERNALS
410 // we need to pair up {} inside our subst to prevent
411 // it from ending too early by matching another }
414 keywords: KEYWORDS
$1,
417 ].concat(SUBST_INTERNALS
)
419 const SUBST_AND_COMMENTS
= [].concat(COMMENT
, SUBST
.contains
);
420 const PARAMS_CONTAINS
= SUBST_AND_COMMENTS
.concat([
421 // eat recursive parens in sub expressions
425 keywords: KEYWORDS
$1,
426 contains: ["self"].concat(SUBST_AND_COMMENTS
)
431 // convert this to negative lookbehind in v12
432 begin: /(\s*)\(/, // to match the parms with
436 keywords: KEYWORDS
$1,
437 contains: PARAMS_CONTAINS
441 const CLASS_OR_EXTENDS
= {
443 // class Car extends vehicle
452 regex
.concat(IDENT_RE
$1, "(", regex
.concat(/\./, IDENT_RE
$1), ")*")
458 7: "title.class.inherited"
477 const CLASS_REFERENCE
= {
481 // Hard coded exceptions
483 // Float32Array, OutT
484 /\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
485 // CSSFactory, CSSFactoryT
486 /\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
488 /\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/,
490 // single letters are not highlighted
492 // this will be flagged as a UPPER_CASE_CONSTANT instead
494 className: "title.class",
497 // se we still get relevance credit for JS library classes
508 begin: /^\s
*['"]use (strict|asm)['"]/
511 const FUNCTION_DEFINITION = {
521 // anonymous function
534 contains: [ PARAMS ],
538 const UPPER_CASE_CONSTANT = {
540 match: /\b[A-Z][A-Z_0-9]+\b/,
541 className: "variable
.constant
"
544 function noneOf(list) {
545 return regex.concat("(?!", list.join("|"), ")");
548 const FUNCTION_CALL = {
555 ].map(x => `${x}\\s*\\(`)),
556 IDENT_RE$1, regex.lookahead(/\s*\(/)),
557 className: "title
.function",
561 const PROPERTY_ACCESS = {
562 begin: regex.concat(/\./, regex.lookahead(
563 regex.concat(IDENT_RE$1, /(?![0-9A-Za-z$_(])/)
567 keywords: "prototype",
568 className: "property
",
572 const GETTER_OR_SETTER = {
584 { // eat to avoid empty params
591 const FUNC_LEAD_IN_RE = '(\\(' +
597 '\\)|' + hljs.UNDERSCORE_IDENT_RE + ')\\s*=>';
599 const FUNCTION_VARIABLE = {
601 /const|var|let/, /\s+/,
604 /(async\s*)?/, // async is optional
605 regex.lookahead(FUNC_LEAD_IN_RE)
619 aliases: ['js', 'jsx', 'mjs', 'cjs'],
620 keywords: KEYWORDS$1,
621 // this will be extended by TypeScript
622 exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
623 illegal: /#(?![$_A-z])/,
631 hljs.APOS_STRING_MODE,
632 hljs.QUOTE_STRING_MODE,
638 // Skip numbers when they are part of a variable name
644 match: IDENT_RE$1 + regex.lookahead(':'),
648 { // "value
" container
649 begin: '(' + hljs.RE_STARTERS_RE + '|\\b(case|return|throw)\\b)\\s*',
650 keywords: 'return throw case',
656 className: 'function',
657 // we have to count the parens to make sure we actually have the
658 // correct bounding ( ) before the =>. There could be any number of
659 // sub-expressions inside also surrounded by parens.
660 begin: FUNC_LEAD_IN_RE,
668 begin: hljs.UNDERSCORE_IDENT_RE,
681 keywords: KEYWORDS$1,
682 contains: PARAMS_CONTAINS
688 { // could be a comma delimited list of params to a function call
698 { begin: FRAGMENT.begin, end: FRAGMENT.end },
699 { match: XML_SELF_CLOSING },
701 begin: XML_TAG.begin,
702 // we carefully check the opening tag to see if it truly
703 // is a tag and not a false positive
704 'on:begin': XML_TAG.isTrulyOpeningTag,
711 begin: XML_TAG.begin,
722 // prevent this from getting swallowed up by function
723 // since they appear "function like
"
724 beginKeywords: "while if switch catch for"
727 // we have to count the parens to make sure we actually have the correct
728 // bounding ( ). There could be any number of sub-expressions inside
729 // also surrounded by parens.
730 begin: '\\b(?!function)' + hljs.UNDERSCORE_IDENT_RE +
731 '\\(' + // first parens
737 '\\)\\s*\\{', // end parens
742 hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1, className: "title
.function" })
745 // catch ... so it won't trigger the property rule below
751 // hack: prevents detection of keywords in some circumstances
755 match: '\\$' + IDENT_RE$1,
759 match: [ /\bconstructor(?=\s*\()/ ],
760 className: { 1: "title
.function" },
768 match: /\$[(.]/ // relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
776 Author: Panu Horsmalahti <panu.horsmalahti@iki.fi>
777 Contributors: Ike Ku <dempfi@yahoo.com>
778 Description: TypeScript is a strict superset of JavaScript
779 Website: https://www.typescriptlang.org
780 Category: common, scripting
784 /** @type LanguageFn */
785 function typescript(hljs) {
786 const regex = hljs.regex;
787 const tsLanguage = javascript(hljs);
789 const IDENT_RE$1 = IDENT_RE;
814 beginKeywords: 'interface',
818 keyword: 'interface extends',
821 contains: [ tsLanguage.exports.CLASS_REFERENCE ]
826 begin: /^\s*['"]use strict
['"]/
828 const TS_SPECIFIC_KEYWORDS = [
844 namespace is a TS keyword but it's fine to
use it as a variable name too
.
845 const message
= 'foo';
846 const namespace = 'bar';
850 keyword: KEYWORDS
.concat(TS_SPECIFIC_KEYWORDS
),
852 built_in: BUILT_INS
.concat(TYPES
),
853 "variable.language": BUILT_IN_VARIABLES
858 begin: '@' + IDENT_RE
$1,
861 const swapMode
= (mode
, label
, replacement
) => {
862 const indx
= mode
.contains
.findIndex(m
=> m
.label
=== label
);
863 if (indx
=== -1) { throw new Error("can not find mode to replace"); }
865 mode
.contains
.splice(indx
, 1, replacement
);
869 // this should update anywhere keywords is used since
870 // it will be the same actual JS object
871 Object
.assign(tsLanguage
.keywords
, KEYWORDS
$1);
873 tsLanguage
.exports
.PARAMS_CONTAINS
.push(DECORATOR
);
875 // highlight the function params
876 const ATTRIBUTE_HIGHLIGHT
= tsLanguage
.contains
.find(c
=> c
.scope
=== "attr");
878 // take default attr rule and extend it to support optionals
879 const OPTIONAL_KEY_OR_ARGUMENT
= Object
.assign({},
881 { match: regex
.concat(IDENT_RE
$1, regex
.lookahead(/\s*\?:/)) }
883 tsLanguage
.exports
.PARAMS_CONTAINS
.push([
884 tsLanguage
.exports
.CLASS_REFERENCE
, // class reference for highlighting the params types
885 ATTRIBUTE_HIGHLIGHT
, // highlight the params key
886 OPTIONAL_KEY_OR_ARGUMENT
, // Added for optional property assignment highlighting
889 // Add the optional property assignment highlighting for objects or classes
890 tsLanguage
.contains
= tsLanguage
.contains
.concat([
894 OPTIONAL_KEY_OR_ARGUMENT
, // Added for optional property assignment highlighting
897 // TS gets a simpler shebang rule than JS
898 swapMode(tsLanguage
, "shebang", hljs
.SHEBANG());
899 // JS use strict rule purposely excludes `asm` which makes no sense
900 swapMode(tsLanguage
, "use_strict", USE_STRICT
);
902 const functionDeclaration
= tsLanguage
.contains
.find(m
=> m
.label
=== "func.def");
903 functionDeclaration
.relevance
= 0; // () => {} is more typical in TypeScript
905 Object
.assign(tsLanguage
, {
922 hljs
.registerLanguage('typescript', hljsGrammar
);