source: node_modules/highlight.js/lib/languages/swift.js@ 75f5086

main
Last change on this file since 75f5086 was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 20.1 KB
Line 
1/**
2 * @param {string} value
3 * @returns {RegExp}
4 * */
5
6/**
7 * @param {RegExp | string } re
8 * @returns {string}
9 */
10function source(re) {
11 if (!re) return null;
12 if (typeof re === "string") return re;
13
14 return re.source;
15}
16
17/**
18 * @param {RegExp | string } re
19 * @returns {string}
20 */
21function lookahead(re) {
22 return concat('(?=', re, ')');
23}
24
25/**
26 * @param {...(RegExp | string) } args
27 * @returns {string}
28 */
29function concat(...args) {
30 const joined = args.map((x) => source(x)).join("");
31 return joined;
32}
33
34/**
35 * Any of the passed expresssions may match
36 *
37 * Creates a huge this | this | that | that match
38 * @param {(RegExp | string)[] } args
39 * @returns {string}
40 */
41function either(...args) {
42 const joined = '(' + args.map((x) => source(x)).join("|") + ")";
43 return joined;
44}
45
46const keywordWrapper = keyword => concat(
47 /\b/,
48 keyword,
49 /\w$/.test(keyword) ? /\b/ : /\B/
50);
51
52// Keywords that require a leading dot.
53const dotKeywords = [
54 'Protocol', // contextual
55 'Type' // contextual
56].map(keywordWrapper);
57
58// Keywords that may have a leading dot.
59const optionalDotKeywords = [
60 'init',
61 'self'
62].map(keywordWrapper);
63
64// should register as keyword, not type
65const keywordTypes = [
66 'Any',
67 'Self'
68];
69
70// Regular keywords and literals.
71const keywords = [
72 // strings below will be fed into the regular `keywords` engine while regex
73 // will result in additional modes being created to scan for those keywords to
74 // avoid conflicts with other rules
75 'associatedtype',
76 'async',
77 'await',
78 /as\?/, // operator
79 /as!/, // operator
80 'as', // operator
81 'break',
82 'case',
83 'catch',
84 'class',
85 'continue',
86 'convenience', // contextual
87 'default',
88 'defer',
89 'deinit',
90 'didSet', // contextual
91 'do',
92 'dynamic', // contextual
93 'else',
94 'enum',
95 'extension',
96 'fallthrough',
97 /fileprivate\(set\)/,
98 'fileprivate',
99 'final', // contextual
100 'for',
101 'func',
102 'get', // contextual
103 'guard',
104 'if',
105 'import',
106 'indirect', // contextual
107 'infix', // contextual
108 /init\?/,
109 /init!/,
110 'inout',
111 /internal\(set\)/,
112 'internal',
113 'in',
114 'is', // operator
115 'lazy', // contextual
116 'let',
117 'mutating', // contextual
118 'nonmutating', // contextual
119 /open\(set\)/, // contextual
120 'open', // contextual
121 'operator',
122 'optional', // contextual
123 'override', // contextual
124 'postfix', // contextual
125 'precedencegroup',
126 'prefix', // contextual
127 /private\(set\)/,
128 'private',
129 'protocol',
130 /public\(set\)/,
131 'public',
132 'repeat',
133 'required', // contextual
134 'rethrows',
135 'return',
136 'set', // contextual
137 'some', // contextual
138 'static',
139 'struct',
140 'subscript',
141 'super',
142 'switch',
143 'throws',
144 'throw',
145 /try\?/, // operator
146 /try!/, // operator
147 'try', // operator
148 'typealias',
149 /unowned\(safe\)/, // contextual
150 /unowned\(unsafe\)/, // contextual
151 'unowned', // contextual
152 'var',
153 'weak', // contextual
154 'where',
155 'while',
156 'willSet' // contextual
157];
158
159// NOTE: Contextual keywords are reserved only in specific contexts.
160// Ideally, these should be matched using modes to avoid false positives.
161
162// Literals.
163const literals = [
164 'false',
165 'nil',
166 'true'
167];
168
169// Keywords used in precedence groups.
170const precedencegroupKeywords = [
171 'assignment',
172 'associativity',
173 'higherThan',
174 'left',
175 'lowerThan',
176 'none',
177 'right'
178];
179
180// Keywords that start with a number sign (#).
181// #available is handled separately.
182const numberSignKeywords = [
183 '#colorLiteral',
184 '#column',
185 '#dsohandle',
186 '#else',
187 '#elseif',
188 '#endif',
189 '#error',
190 '#file',
191 '#fileID',
192 '#fileLiteral',
193 '#filePath',
194 '#function',
195 '#if',
196 '#imageLiteral',
197 '#keyPath',
198 '#line',
199 '#selector',
200 '#sourceLocation',
201 '#warn_unqualified_access',
202 '#warning'
203];
204
205// Global functions in the Standard Library.
206const builtIns = [
207 'abs',
208 'all',
209 'any',
210 'assert',
211 'assertionFailure',
212 'debugPrint',
213 'dump',
214 'fatalError',
215 'getVaList',
216 'isKnownUniquelyReferenced',
217 'max',
218 'min',
219 'numericCast',
220 'pointwiseMax',
221 'pointwiseMin',
222 'precondition',
223 'preconditionFailure',
224 'print',
225 'readLine',
226 'repeatElement',
227 'sequence',
228 'stride',
229 'swap',
230 'swift_unboxFromSwiftValueWithType',
231 'transcode',
232 'type',
233 'unsafeBitCast',
234 'unsafeDowncast',
235 'withExtendedLifetime',
236 'withUnsafeMutablePointer',
237 'withUnsafePointer',
238 'withVaList',
239 'withoutActuallyEscaping',
240 'zip'
241];
242
243// Valid first characters for operators.
244const operatorHead = either(
245 /[/=\-+!*%<>&|^~?]/,
246 /[\u00A1-\u00A7]/,
247 /[\u00A9\u00AB]/,
248 /[\u00AC\u00AE]/,
249 /[\u00B0\u00B1]/,
250 /[\u00B6\u00BB\u00BF\u00D7\u00F7]/,
251 /[\u2016-\u2017]/,
252 /[\u2020-\u2027]/,
253 /[\u2030-\u203E]/,
254 /[\u2041-\u2053]/,
255 /[\u2055-\u205E]/,
256 /[\u2190-\u23FF]/,
257 /[\u2500-\u2775]/,
258 /[\u2794-\u2BFF]/,
259 /[\u2E00-\u2E7F]/,
260 /[\u3001-\u3003]/,
261 /[\u3008-\u3020]/,
262 /[\u3030]/
263);
264
265// Valid characters for operators.
266const operatorCharacter = either(
267 operatorHead,
268 /[\u0300-\u036F]/,
269 /[\u1DC0-\u1DFF]/,
270 /[\u20D0-\u20FF]/,
271 /[\uFE00-\uFE0F]/,
272 /[\uFE20-\uFE2F]/
273 // TODO: The following characters are also allowed, but the regex isn't supported yet.
274 // /[\u{E0100}-\u{E01EF}]/u
275);
276
277// Valid operator.
278const operator = concat(operatorHead, operatorCharacter, '*');
279
280// Valid first characters for identifiers.
281const identifierHead = either(
282 /[a-zA-Z_]/,
283 /[\u00A8\u00AA\u00AD\u00AF\u00B2-\u00B5\u00B7-\u00BA]/,
284 /[\u00BC-\u00BE\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF]/,
285 /[\u0100-\u02FF\u0370-\u167F\u1681-\u180D\u180F-\u1DBF]/,
286 /[\u1E00-\u1FFF]/,
287 /[\u200B-\u200D\u202A-\u202E\u203F-\u2040\u2054\u2060-\u206F]/,
288 /[\u2070-\u20CF\u2100-\u218F\u2460-\u24FF\u2776-\u2793]/,
289 /[\u2C00-\u2DFF\u2E80-\u2FFF]/,
290 /[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/,
291 /[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/,
292 /[\uFE47-\uFEFE\uFF00-\uFFFD]/ // Should be /[\uFE47-\uFFFD]/, but we have to exclude FEFF.
293 // The following characters are also allowed, but the regexes aren't supported yet.
294 // /[\u{10000}-\u{1FFFD}\u{20000-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}]/u,
295 // /[\u{50000}-\u{5FFFD}\u{60000-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}]/u,
296 // /[\u{90000}-\u{9FFFD}\u{A0000-\u{AFFFD}\u{B0000}-\u{BFFFD}\u{C0000}-\u{CFFFD}]/u,
297 // /[\u{D0000}-\u{DFFFD}\u{E0000-\u{EFFFD}]/u
298);
299
300// Valid characters for identifiers.
301const identifierCharacter = either(
302 identifierHead,
303 /\d/,
304 /[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/
305);
306
307// Valid identifier.
308const identifier = concat(identifierHead, identifierCharacter, '*');
309
310// Valid type identifier.
311const typeIdentifier = concat(/[A-Z]/, identifierCharacter, '*');
312
313// Built-in attributes, which are highlighted as keywords.
314// @available is handled separately.
315const keywordAttributes = [
316 'autoclosure',
317 concat(/convention\(/, either('swift', 'block', 'c'), /\)/),
318 'discardableResult',
319 'dynamicCallable',
320 'dynamicMemberLookup',
321 'escaping',
322 'frozen',
323 'GKInspectable',
324 'IBAction',
325 'IBDesignable',
326 'IBInspectable',
327 'IBOutlet',
328 'IBSegueAction',
329 'inlinable',
330 'main',
331 'nonobjc',
332 'NSApplicationMain',
333 'NSCopying',
334 'NSManaged',
335 concat(/objc\(/, identifier, /\)/),
336 'objc',
337 'objcMembers',
338 'propertyWrapper',
339 'requires_stored_property_inits',
340 'testable',
341 'UIApplicationMain',
342 'unknown',
343 'usableFromInline'
344];
345
346// Contextual keywords used in @available and #available.
347const availabilityKeywords = [
348 'iOS',
349 'iOSApplicationExtension',
350 'macOS',
351 'macOSApplicationExtension',
352 'macCatalyst',
353 'macCatalystApplicationExtension',
354 'watchOS',
355 'watchOSApplicationExtension',
356 'tvOS',
357 'tvOSApplicationExtension',
358 'swift'
359];
360
361/*
362Language: Swift
363Description: Swift is a general-purpose programming language built using a modern approach to safety, performance, and software design patterns.
364Author: Steven Van Impe <steven.vanimpe@icloud.com>
365Contributors: Chris Eidhof <chris@eidhof.nl>, Nate Cook <natecook@gmail.com>, Alexander Lichter <manniL@gmx.net>, Richard Gibson <gibson042@github>
366Website: https://swift.org
367Category: common, system
368*/
369
370/** @type LanguageFn */
371function swift(hljs) {
372 const WHITESPACE = {
373 match: /\s+/,
374 relevance: 0
375 };
376 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID411
377 const BLOCK_COMMENT = hljs.COMMENT(
378 '/\\*',
379 '\\*/',
380 {
381 contains: [ 'self' ]
382 }
383 );
384 const COMMENTS = [
385 hljs.C_LINE_COMMENT_MODE,
386 BLOCK_COMMENT
387 ];
388
389 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID413
390 // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html
391 const DOT_KEYWORD = {
392 className: 'keyword',
393 begin: concat(/\./, lookahead(either(...dotKeywords, ...optionalDotKeywords))),
394 end: either(...dotKeywords, ...optionalDotKeywords),
395 excludeBegin: true
396 };
397 const KEYWORD_GUARD = {
398 // Consume .keyword to prevent highlighting properties and methods as keywords.
399 match: concat(/\./, either(...keywords)),
400 relevance: 0
401 };
402 const PLAIN_KEYWORDS = keywords
403 .filter(kw => typeof kw === 'string')
404 .concat([ "_|0" ]); // seems common, so 0 relevance
405 const REGEX_KEYWORDS = keywords
406 .filter(kw => typeof kw !== 'string') // find regex
407 .concat(keywordTypes)
408 .map(keywordWrapper);
409 const KEYWORD = {
410 variants: [
411 {
412 className: 'keyword',
413 match: either(...REGEX_KEYWORDS, ...optionalDotKeywords)
414 }
415 ]
416 };
417 // find all the regular keywords
418 const KEYWORDS = {
419 $pattern: either(
420 /\b\w+/, // regular keywords
421 /#\w+/ // number keywords
422 ),
423 keyword: PLAIN_KEYWORDS
424 .concat(numberSignKeywords),
425 literal: literals
426 };
427 const KEYWORD_MODES = [
428 DOT_KEYWORD,
429 KEYWORD_GUARD,
430 KEYWORD
431 ];
432
433 // https://github.com/apple/swift/tree/main/stdlib/public/core
434 const BUILT_IN_GUARD = {
435 // Consume .built_in to prevent highlighting properties and methods.
436 match: concat(/\./, either(...builtIns)),
437 relevance: 0
438 };
439 const BUILT_IN = {
440 className: 'built_in',
441 match: concat(/\b/, either(...builtIns), /(?=\()/)
442 };
443 const BUILT_INS = [
444 BUILT_IN_GUARD,
445 BUILT_IN
446 ];
447
448 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418
449 const OPERATOR_GUARD = {
450 // Prevent -> from being highlighting as an operator.
451 match: /->/,
452 relevance: 0
453 };
454 const OPERATOR = {
455 className: 'operator',
456 relevance: 0,
457 variants: [
458 {
459 match: operator
460 },
461 {
462 // dot-operator: only operators that start with a dot are allowed to use dots as
463 // characters (..., ...<, .*, etc). So there rule here is: a dot followed by one or more
464 // characters that may also include dots.
465 match: `\\.(\\.|${operatorCharacter})+`
466 }
467 ]
468 };
469 const OPERATORS = [
470 OPERATOR_GUARD,
471 OPERATOR
472 ];
473
474 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_numeric-literal
475 // TODO: Update for leading `-` after lookbehind is supported everywhere
476 const decimalDigits = '([0-9]_*)+';
477 const hexDigits = '([0-9a-fA-F]_*)+';
478 const NUMBER = {
479 className: 'number',
480 relevance: 0,
481 variants: [
482 // decimal floating-point-literal (subsumes decimal-literal)
483 {
484 match: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b`
485 },
486 // hexadecimal floating-point-literal (subsumes hexadecimal-literal)
487 {
488 match: `\\b0x(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b`
489 },
490 // octal-literal
491 {
492 match: /\b0o([0-7]_*)+\b/
493 },
494 // binary-literal
495 {
496 match: /\b0b([01]_*)+\b/
497 }
498 ]
499 };
500
501 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#grammar_string-literal
502 const ESCAPED_CHARACTER = (rawDelimiter = "") => ({
503 className: 'subst',
504 variants: [
505 {
506 match: concat(/\\/, rawDelimiter, /[0\\tnr"']/)
507 },
508 {
509 match: concat(/\\/, rawDelimiter, /u\{[0-9a-fA-F]{1,8}\}/)
510 }
511 ]
512 });
513 const ESCAPED_NEWLINE = (rawDelimiter = "") => ({
514 className: 'subst',
515 match: concat(/\\/, rawDelimiter, /[\t ]*(?:[\r\n]|\r\n)/)
516 });
517 const INTERPOLATION = (rawDelimiter = "") => ({
518 className: 'subst',
519 label: "interpol",
520 begin: concat(/\\/, rawDelimiter, /\(/),
521 end: /\)/
522 });
523 const MULTILINE_STRING = (rawDelimiter = "") => ({
524 begin: concat(rawDelimiter, /"""/),
525 end: concat(/"""/, rawDelimiter),
526 contains: [
527 ESCAPED_CHARACTER(rawDelimiter),
528 ESCAPED_NEWLINE(rawDelimiter),
529 INTERPOLATION(rawDelimiter)
530 ]
531 });
532 const SINGLE_LINE_STRING = (rawDelimiter = "") => ({
533 begin: concat(rawDelimiter, /"/),
534 end: concat(/"/, rawDelimiter),
535 contains: [
536 ESCAPED_CHARACTER(rawDelimiter),
537 INTERPOLATION(rawDelimiter)
538 ]
539 });
540 const STRING = {
541 className: 'string',
542 variants: [
543 MULTILINE_STRING(),
544 MULTILINE_STRING("#"),
545 MULTILINE_STRING("##"),
546 MULTILINE_STRING("###"),
547 SINGLE_LINE_STRING(),
548 SINGLE_LINE_STRING("#"),
549 SINGLE_LINE_STRING("##"),
550 SINGLE_LINE_STRING("###")
551 ]
552 };
553
554 // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412
555 const QUOTED_IDENTIFIER = {
556 match: concat(/`/, identifier, /`/)
557 };
558 const IMPLICIT_PARAMETER = {
559 className: 'variable',
560 match: /\$\d+/
561 };
562 const PROPERTY_WRAPPER_PROJECTION = {
563 className: 'variable',
564 match: `\\$${identifierCharacter}+`
565 };
566 const IDENTIFIERS = [
567 QUOTED_IDENTIFIER,
568 IMPLICIT_PARAMETER,
569 PROPERTY_WRAPPER_PROJECTION
570 ];
571
572 // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
573 const AVAILABLE_ATTRIBUTE = {
574 match: /(@|#)available/,
575 className: "keyword",
576 starts: {
577 contains: [
578 {
579 begin: /\(/,
580 end: /\)/,
581 keywords: availabilityKeywords,
582 contains: [
583 ...OPERATORS,
584 NUMBER,
585 STRING
586 ]
587 }
588 ]
589 }
590 };
591 const KEYWORD_ATTRIBUTE = {
592 className: 'keyword',
593 match: concat(/@/, either(...keywordAttributes))
594 };
595 const USER_DEFINED_ATTRIBUTE = {
596 className: 'meta',
597 match: concat(/@/, identifier)
598 };
599 const ATTRIBUTES = [
600 AVAILABLE_ATTRIBUTE,
601 KEYWORD_ATTRIBUTE,
602 USER_DEFINED_ATTRIBUTE
603 ];
604
605 // https://docs.swift.org/swift-book/ReferenceManual/Types.html
606 const TYPE = {
607 match: lookahead(/\b[A-Z]/),
608 relevance: 0,
609 contains: [
610 { // Common Apple frameworks, for relevance boost
611 className: 'type',
612 match: concat(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/, identifierCharacter, '+')
613 },
614 { // Type identifier
615 className: 'type',
616 match: typeIdentifier,
617 relevance: 0
618 },
619 { // Optional type
620 match: /[?!]+/,
621 relevance: 0
622 },
623 { // Variadic parameter
624 match: /\.\.\./,
625 relevance: 0
626 },
627 { // Protocol composition
628 match: concat(/\s+&\s+/, lookahead(typeIdentifier)),
629 relevance: 0
630 }
631 ]
632 };
633 const GENERIC_ARGUMENTS = {
634 begin: /</,
635 end: />/,
636 keywords: KEYWORDS,
637 contains: [
638 ...COMMENTS,
639 ...KEYWORD_MODES,
640 ...ATTRIBUTES,
641 OPERATOR_GUARD,
642 TYPE
643 ]
644 };
645 TYPE.contains.push(GENERIC_ARGUMENTS);
646
647 // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552
648 // Prevents element names from being highlighted as keywords.
649 const TUPLE_ELEMENT_NAME = {
650 match: concat(identifier, /\s*:/),
651 keywords: "_|0",
652 relevance: 0
653 };
654 // Matches tuples as well as the parameter list of a function type.
655 const TUPLE = {
656 begin: /\(/,
657 end: /\)/,
658 relevance: 0,
659 keywords: KEYWORDS,
660 contains: [
661 'self',
662 TUPLE_ELEMENT_NAME,
663 ...COMMENTS,
664 ...KEYWORD_MODES,
665 ...BUILT_INS,
666 ...OPERATORS,
667 NUMBER,
668 STRING,
669 ...IDENTIFIERS,
670 ...ATTRIBUTES,
671 TYPE
672 ]
673 };
674
675 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID362
676 // Matches both the keyword func and the function title.
677 // Grouping these lets us differentiate between the operator function <
678 // and the start of the generic parameter clause (also <).
679 const FUNC_PLUS_TITLE = {
680 beginKeywords: 'func',
681 contains: [
682 {
683 className: 'title',
684 match: either(QUOTED_IDENTIFIER.match, identifier, operator),
685 // Required to make sure the opening < of the generic parameter clause
686 // isn't parsed as a second title.
687 endsParent: true,
688 relevance: 0
689 },
690 WHITESPACE
691 ]
692 };
693 const GENERIC_PARAMETERS = {
694 begin: /</,
695 end: />/,
696 contains: [
697 ...COMMENTS,
698 TYPE
699 ]
700 };
701 const FUNCTION_PARAMETER_NAME = {
702 begin: either(
703 lookahead(concat(identifier, /\s*:/)),
704 lookahead(concat(identifier, /\s+/, identifier, /\s*:/))
705 ),
706 end: /:/,
707 relevance: 0,
708 contains: [
709 {
710 className: 'keyword',
711 match: /\b_\b/
712 },
713 {
714 className: 'params',
715 match: identifier
716 }
717 ]
718 };
719 const FUNCTION_PARAMETERS = {
720 begin: /\(/,
721 end: /\)/,
722 keywords: KEYWORDS,
723 contains: [
724 FUNCTION_PARAMETER_NAME,
725 ...COMMENTS,
726 ...KEYWORD_MODES,
727 ...OPERATORS,
728 NUMBER,
729 STRING,
730 ...ATTRIBUTES,
731 TYPE,
732 TUPLE
733 ],
734 endsParent: true,
735 illegal: /["']/
736 };
737 const FUNCTION = {
738 className: 'function',
739 match: lookahead(/\bfunc\b/),
740 contains: [
741 FUNC_PLUS_TITLE,
742 GENERIC_PARAMETERS,
743 FUNCTION_PARAMETERS,
744 WHITESPACE
745 ],
746 illegal: [
747 /\[/,
748 /%/
749 ]
750 };
751
752 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375
753 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379
754 const INIT_SUBSCRIPT = {
755 className: 'function',
756 match: /\b(subscript|init[?!]?)\s*(?=[<(])/,
757 keywords: {
758 keyword: "subscript init init? init!",
759 $pattern: /\w+[?!]?/
760 },
761 contains: [
762 GENERIC_PARAMETERS,
763 FUNCTION_PARAMETERS,
764 WHITESPACE
765 ],
766 illegal: /\[|%/
767 };
768 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID380
769 const OPERATOR_DECLARATION = {
770 beginKeywords: 'operator',
771 end: hljs.MATCH_NOTHING_RE,
772 contains: [
773 {
774 className: 'title',
775 match: operator,
776 endsParent: true,
777 relevance: 0
778 }
779 ]
780 };
781
782 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID550
783 const PRECEDENCEGROUP = {
784 beginKeywords: 'precedencegroup',
785 end: hljs.MATCH_NOTHING_RE,
786 contains: [
787 {
788 className: 'title',
789 match: typeIdentifier,
790 relevance: 0
791 },
792 {
793 begin: /{/,
794 end: /}/,
795 relevance: 0,
796 endsParent: true,
797 keywords: [
798 ...precedencegroupKeywords,
799 ...literals
800 ],
801 contains: [ TYPE ]
802 }
803 ]
804 };
805
806 // Add supported submodes to string interpolation.
807 for (const variant of STRING.variants) {
808 const interpolation = variant.contains.find(mode => mode.label === "interpol");
809 // TODO: Interpolation can contain any expression, so there's room for improvement here.
810 interpolation.keywords = KEYWORDS;
811 const submodes = [
812 ...KEYWORD_MODES,
813 ...BUILT_INS,
814 ...OPERATORS,
815 NUMBER,
816 STRING,
817 ...IDENTIFIERS
818 ];
819 interpolation.contains = [
820 ...submodes,
821 {
822 begin: /\(/,
823 end: /\)/,
824 contains: [
825 'self',
826 ...submodes
827 ]
828 }
829 ];
830 }
831
832 return {
833 name: 'Swift',
834 keywords: KEYWORDS,
835 contains: [
836 ...COMMENTS,
837 FUNCTION,
838 INIT_SUBSCRIPT,
839 {
840 className: 'class',
841 beginKeywords: 'struct protocol class extension enum',
842 end: '\\{',
843 excludeEnd: true,
844 keywords: KEYWORDS,
845 contains: [
846 hljs.inherit(hljs.TITLE_MODE, {
847 begin: /[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/
848 }),
849 ...KEYWORD_MODES
850 ]
851 },
852 OPERATOR_DECLARATION,
853 PRECEDENCEGROUP,
854 {
855 beginKeywords: 'import',
856 end: /$/,
857 contains: [ ...COMMENTS ],
858 relevance: 0
859 },
860 ...KEYWORD_MODES,
861 ...BUILT_INS,
862 ...OPERATORS,
863 NUMBER,
864 STRING,
865 ...IDENTIFIERS,
866 ...ATTRIBUTES,
867 TYPE,
868 TUPLE
869 ]
870 };
871}
872
873module.exports = swift;
Note: See TracBrowser for help on using the repository browser.