From a2a27fdad2a48bde07b8cd59ea7cdeed696a545c Mon Sep 17 00:00:00 2001 From: Steven Van Impe Date: Fri, 18 Dec 2020 17:26:42 +0100 Subject: [PATCH 1/4] (swift) Improved highlighting for functions, initializers, and subscripts --- CHANGES.md | 1 + src/languages/lib/kws_swift.js | 16 +-- src/languages/swift.js | 191 +++++++++++++++++++------ test/markup/swift/functions.expect.txt | 38 +++-- test/markup/swift/functions.txt | 38 +++-- test/markup/swift/keywords.expect.txt | 2 +- test/markup/swift/keywords.txt | 2 +- test/markup/swift/tuples.expect.txt | 14 ++ test/markup/swift/tuples.txt | 14 ++ test/markup/swift/types.expect.txt | 4 + test/markup/swift/types.txt | 4 + 11 files changed, 256 insertions(+), 68 deletions(-) create mode 100644 test/markup/swift/tuples.expect.txt create mode 100644 test/markup/swift/tuples.txt diff --git a/CHANGES.md b/CHANGES.md index 7c6e1d2c4c..61548bfd53 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ Language improvements: - Added support for quoted identifiers, implicit parameters, and property wrapper projections - Support for more complex expressions in string interpolation - enh(swift) Improved highlighting for types and generic arguments (#2920) [Steven Van Impe][] +- enh(swift) Improved highlighting for functions, initializers, and subscripts (#2930) [Steven Van Impe][] - fix(http) avoid recursive sublanguage and tighten rules (#2893) [Josh Goebel][] - fix(asciidoc): Handle section titles level 5 (#2868) [Vaibhav Chanana][] diff --git a/src/languages/lib/kws_swift.js b/src/languages/lib/kws_swift.js index 77b1021017..a52ca459bc 100644 --- a/src/languages/lib/kws_swift.js +++ b/src/languages/lib/kws_swift.js @@ -52,7 +52,7 @@ export const keywords = [ 'enum', 'extension', 'fallthrough', - 'fileprivate(set)', + /fileprivate\(set\)/, 'fileprivate', 'final', // contextual 'for', @@ -66,7 +66,7 @@ export const keywords = [ /init\?/, /init!/, 'inout', - 'internal(set)', + /internal\(set\)/, 'internal', 'in', 'is', // operator @@ -74,7 +74,7 @@ export const keywords = [ 'let', 'mutating', // contextual 'nonmutating', // contextual - 'open(set)', // contextual + /open\(set\)/, // contextual 'open', // contextual 'operator', 'optional', // contextual @@ -82,10 +82,10 @@ export const keywords = [ 'postfix', // contextual 'precedencegroup', 'prefix', // contextual - 'private(set)', + /private\(set\)/, 'private', 'protocol', - 'public(set)', + /public\(set\)/, 'public', 'repeat', 'required', // contextual @@ -104,8 +104,8 @@ export const keywords = [ /try!/, // operator 'try', // operator 'typealias', - 'unowned(safe)', // contextual - 'unowned(unsafe)', // contextual + /unowned\(safe\)/, // contextual + /unowned\(unsafe\)/, // contextual 'unowned', // contextual 'var', 'weak', // contextual @@ -240,7 +240,7 @@ export const identifierHead = either( /[\u2C00-\u2DFF\u2E80-\u2FFF]/, /[\u3004-\u3007\u3021-\u302F\u3031-\u303F\u3040-\uD7FF]/, /[\uF900-\uFD3D\uFD40-\uFDCF\uFDF0-\uFE1F\uFE30-\uFE44]/, - /[\uFE47-\uFFFD]/ + /[\uFE47-\uFEFE\uFF00-\uFFFD]/ // Should be /[\uFE47-\uFFFD]/, but we have to exclude FEFF. // The following characters are also allowed, but the regexes aren't supported yet. // /[\u{10000}-\u{1FFFD}\u{20000-\u{2FFFD}\u{30000}-\u{3FFFD}\u{40000}-\u{4FFFD}]/u, // /[\u{50000}-\u{5FFFD}\u{60000-\u{6FFFD}\u{70000}-\u{7FFFD}\u{80000}-\u{8FFFD}]/u, diff --git a/src/languages/swift.js b/src/languages/swift.js index 3b95e40676..a085184def 100644 --- a/src/languages/swift.js +++ b/src/languages/swift.js @@ -24,6 +24,10 @@ export default function(hljs) { contains: [ 'self' ] } ); + const COMMENTS = [ + hljs.C_LINE_COMMENT_MODE, + BLOCK_COMMENT + ]; // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID413 // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html @@ -56,7 +60,7 @@ export default function(hljs) { // find all the regular keywords const KEYWORDS = { $pattern: either( - /\b\w+(\(\w+\))?/, // kw or kw(arg) + /\b\w+/, // regular keywords /#\w+/ // number keywords ), keyword: PLAIN_KEYWORDS @@ -275,6 +279,7 @@ export default function(hljs) { end: />/, keywords: KEYWORDS, contains: [ + ...COMMENTS, ...KEYWORD_MODES, ...ATTRIBUTES, OPERATOR_GUARD, @@ -283,6 +288,143 @@ export default function(hljs) { }; TYPE.contains.push(GENERIC_ARGUMENTS); + // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552 + // Prevents element names from being highlighted as keywords. + const TUPLE_ELEMENT_NAME = { + begin: lookahead(concat(Swift.identifier, /\s*:/)), + end: lookahead(/:/), + keywords: "_", + relevance: 0 + }; + // Matches tuples as well as the parameter list of a function type. + const TUPLE = { + begin: /\(/, + end: /\)/, + relevance: 0, + keywords: KEYWORDS, + contains: [ + 'self', + TUPLE_ELEMENT_NAME, + ...COMMENTS, + ...KEYWORD_MODES, + ...BUILT_INS, + ...OPERATORS, + NUMBER, + STRING, + ...IDENTIFIERS, + ...ATTRIBUTES, + TYPE + ] + }; + + // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID362 + // Matches both the keyword func and the function title. + // Grouping these lets us differentiate between the operator function < + // and the start of the generic parameter clause (also <). + const FUNCTION_TITLE = { + begin: lookahead(/\bfunc\b/), + relevance: 0, + contains: [ + { + className: 'keyword', + begin: /\bfunc\b/ + }, + { + begin: /\s+/, + relevance: 0 + }, + { + className: 'title', + begin: either(QUOTED_IDENTIFIER.begin, Swift.identifier, Swift.operator), + // Required to make sure the opening < of the generic parameter clause + // isn't parsed as a second title. + endsParent: true, + relevance: 0 + } + ] + }; + const GENERIC_PARAMETERS = { + begin: /\s*/, + contains: [ + ...COMMENTS, + TYPE + ] + }; + const FUNCTION_PARAMETER_NAME = { + begin: either( + lookahead(concat(Swift.identifier, /\s*:/)), + lookahead(concat(Swift.identifier, /\s+/, Swift.identifier, /\s*:/)) + ), + end: lookahead(/:/), + relevance: 0, + contains: [ + { + className: 'keyword', + begin: /\b_\b/ + }, + { + className: 'params', + begin: Swift.identifier + } + ] + }; + const FUNCTION_PARAMETERS = { + begin: /\s*\(/, + end: /\)/, + keywords: KEYWORDS, + contains: [ + FUNCTION_PARAMETER_NAME, + ...COMMENTS, + ...KEYWORD_MODES, + ...OPERATORS, + NUMBER, + STRING, + ...ATTRIBUTES, + TYPE, + TUPLE + ], + illegal: /["']/ + }; + const FUNCTION = { + className: 'function', + begin: lookahead(/\bfunc\b/), + contains: [ + FUNCTION_TITLE, + GENERIC_PARAMETERS, + FUNCTION_PARAMETERS + ], + illegal: /\[|%/ + }; + + // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375 + // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379 + const INIT_SUBSCRIPT_TITLE = { + begin: lookahead(/\b(subscript|init[?!]?)\s*[<(]/), + end: lookahead(/[<(]/), + relevance: 0, + contains: [ + { + className: 'keyword', + begin: /subscript|init[?!]?/ + }, + { + begin: /\s+/, + relevance: 0 + } + ] + }; + const INIT_SUBSCRIPT = { + className: 'function', + begin: lookahead(/\b(subscript|init[?!]?)\s*[<(]/), + contains: [ + INIT_SUBSCRIPT_TITLE, + GENERIC_PARAMETERS, + FUNCTION_PARAMETERS + ], + illegal: /\[|%/ + }; + // Add supported submodes to string interpolation. for (const variant of STRING.variants) { const interpolation = variant.contains.find(mode => mode.label === "interpol"); @@ -313,42 +455,9 @@ export default function(hljs) { name: 'Swift', keywords: KEYWORDS, contains: [ - hljs.C_LINE_COMMENT_MODE, - BLOCK_COMMENT, - { - className: 'function', - beginKeywords: 'func', - end: /\{/, - excludeEnd: true, - contains: [ - hljs.inherit(hljs.TITLE_MODE, { - begin: /[A-Za-z$_][0-9A-Za-z$_]*/ - }), - { - begin: // - }, - { - className: 'params', - begin: /\(/, - end: /\)/, - endsParent: true, - keywords: KEYWORDS, - contains: [ - 'self', - ...KEYWORD_MODES, - NUMBER, - STRING, - hljs.C_BLOCK_COMMENT_MODE, - { // relevance booster - begin: ':' - } - ], - illegal: /["']/ - } - ], - illegal: /\[|%/ - }, + ...COMMENTS, + FUNCTION, + INIT_SUBSCRIPT, { className: 'class', beginKeywords: 'struct protocol class extension enum', @@ -365,10 +474,7 @@ export default function(hljs) { { beginKeywords: 'import', end: /$/, - contains: [ - hljs.C_LINE_COMMENT_MODE, - BLOCK_COMMENT - ], + contains: [ ...COMMENTS ], relevance: 0 }, ...KEYWORD_MODES, @@ -378,7 +484,8 @@ export default function(hljs) { STRING, ...IDENTIFIERS, ...ATTRIBUTES, - TYPE + TYPE, + TUPLE ] }; } diff --git a/test/markup/swift/functions.expect.txt b/test/markup/swift/functions.expect.txt index a83afdfb6b..0a10c71ff0 100644 --- a/test/markup/swift/functions.expect.txt +++ b/test/markup/swift/functions.expect.txt @@ -1,10 +1,32 @@ -protocol Protocol { - func f1() - func f2() -} +func f1< + X, + Y: A, + // documentation + Z: B & C<D> +>() where X == Y, Y: A, Z: B & C<D> { } + +func < <T>() { } + +func f2(_ p: @escaping () throws -> Void) rethrows -> some Collection { } + +func f3( + p1e p1i: inout Int = 5, + _ p2: (x: Int, y: Int), + p3: (var: Int, let: Int) throws -> Int, + p4: Int... + p5: @attribute String? = "text" +) { } + +init<X: A>(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } +init?(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } +init! (_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } + +subscript<X: A>(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } + +protocol Comparable: Equatable { -class MyClass { - func f() { - return true - } + static func < (lhs: Self, rhs: Self) -> Bool + static func <= (lhs: Self, rhs: Self) -> Bool + static func > (lhs: Self, rhs: Self) -> Bool + static func >= (lhs: Self, rhs: Self) -> Bool } diff --git a/test/markup/swift/functions.txt b/test/markup/swift/functions.txt index cfd64aed92..1f8807d3c2 100644 --- a/test/markup/swift/functions.txt +++ b/test/markup/swift/functions.txt @@ -1,10 +1,32 @@ -protocol Protocol { - func f1() - func f2() -} +func f1< + X, + Y: A, + // documentation + Z: B & C +>() where X == Y, Y: A, Z: B & C { } + +func < () { } + +func f2(_ p: @escaping () throws -> Void) rethrows -> some Collection { } + +func f3( + p1e p1i: inout Int = 5, + _ p2: (x: Int, y: Int), + p3: (var: Int, let: Int) throws -> Int, + p4: Int... + p5: @attribute String? = "text" +) { } + +init(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } +init?(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } +init! (_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } + +subscript(_ p: @attribute inout (x: Int, var: Int) = (0, 0)) { } + +protocol Comparable: Equatable { -class MyClass { - func f() { - return true - } + static func < (lhs: Self, rhs: Self) -> Bool + static func <= (lhs: Self, rhs: Self) -> Bool + static func > (lhs: Self, rhs: Self) -> Bool + static func >= (lhs: Self, rhs: Self) -> Bool } diff --git a/test/markup/swift/keywords.expect.txt b/test/markup/swift/keywords.expect.txt index a7f03bca5e..73adf593a4 100644 --- a/test/markup/swift/keywords.expect.txt +++ b/test/markup/swift/keywords.expect.txt @@ -10,7 +10,7 @@ x as Int x as? Double x as! String x is String -init?() init!() init +init? init! init try? try! try true false nil fileprivate(set) internal(set) open(set) private(set) public(set) diff --git a/test/markup/swift/keywords.txt b/test/markup/swift/keywords.txt index 6b354c0db1..53358810d9 100644 --- a/test/markup/swift/keywords.txt +++ b/test/markup/swift/keywords.txt @@ -10,7 +10,7 @@ x as Int x as? Double x as! String x is String -init?() init!() init +init? init! init try? try! try true false nil fileprivate(set) internal(set) open(set) private(set) public(set) diff --git a/test/markup/swift/tuples.expect.txt b/test/markup/swift/tuples.expect.txt new file mode 100644 index 0000000000..28b22545fb --- /dev/null +++ b/test/markup/swift/tuples.expect.txt @@ -0,0 +1,14 @@ +(3, "string") +(c: (x: 1, y: 1), z: 1) +(var: Array<Int>, let: Array<Double>) +(_ x: inout Int) throws -> Int +(abs(-2), abs(2)) +(x < y, a > b) +($0, $1) +(@escaping (String) -> Void, @autoclosure () -> String) -> String +( + // x + x, + /* y */ + y +) diff --git a/test/markup/swift/tuples.txt b/test/markup/swift/tuples.txt new file mode 100644 index 0000000000..06ebea5c1f --- /dev/null +++ b/test/markup/swift/tuples.txt @@ -0,0 +1,14 @@ +(3, "string") +(c: (x: 1, y: 1), z: 1) +(var: Array, let: Array) +(_ x: inout Int) throws -> Int +(abs(-2), abs(2)) +(x < y, a > b) +($0, $1) +(@escaping (String) -> Void, @autoclosure () -> String) -> String +( + // x + x, + /* y */ + y +) diff --git a/test/markup/swift/types.expect.txt b/test/markup/swift/types.expect.txt index 731db7c394..4bd3695140 100644 --- a/test/markup/swift/types.expect.txt +++ b/test/markup/swift/types.expect.txt @@ -41,3 +41,7 @@ Dictionary<String, Any> Dictionary<String, Array<Int>> Array<(@autoclosure () -> String) throws -> String?> +Array< + // documentation + Int +> diff --git a/test/markup/swift/types.txt b/test/markup/swift/types.txt index 0348b00e9a..89a27ea6a9 100644 --- a/test/markup/swift/types.txt +++ b/test/markup/swift/types.txt @@ -41,3 +41,7 @@ Array Dictionary Dictionary> Array<(@autoclosure () -> String) throws -> String?> +Array< + // documentation + Int +> From 94534b414ae82e79780f2695121b8de15f375cae Mon Sep 17 00:00:00 2001 From: Steven Van Impe Date: Tue, 22 Dec 2020 11:10:24 +0100 Subject: [PATCH 2/4] Simplifications --- src/languages/swift.js | 46 ++++++++++++----------------- test/markup/swift/tuples.expect.txt | 2 ++ test/markup/swift/tuples.txt | 2 ++ 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/languages/swift.js b/src/languages/swift.js index a085184def..5ed41a390c 100644 --- a/src/languages/swift.js +++ b/src/languages/swift.js @@ -293,7 +293,7 @@ export default function(hljs) { const TUPLE_ELEMENT_NAME = { begin: lookahead(concat(Swift.identifier, /\s*:/)), end: lookahead(/:/), - keywords: "_", + keywords: "_|0", relevance: 0 }; // Matches tuples as well as the parameter list of a function type. @@ -322,13 +322,8 @@ export default function(hljs) { // Grouping these lets us differentiate between the operator function < // and the start of the generic parameter clause (also <). const FUNCTION_TITLE = { - begin: lookahead(/\bfunc\b/), - relevance: 0, + beginKeywords: 'func', contains: [ - { - className: 'keyword', - begin: /\bfunc\b/ - }, { begin: /\s+/, relevance: 0 @@ -344,7 +339,7 @@ export default function(hljs) { ] }; const GENERIC_PARAMETERS = { - begin: /\s*/, contains: [ ...COMMENTS, @@ -370,7 +365,7 @@ export default function(hljs) { ] }; const FUNCTION_PARAMETERS = { - begin: /\s*\(/, + begin: /\(/, end: /\)/, keywords: KEYWORDS, contains: [ @@ -384,6 +379,7 @@ export default function(hljs) { TYPE, TUPLE ], + endsParent: true, illegal: /["']/ }; const FUNCTION = { @@ -392,35 +388,31 @@ export default function(hljs) { contains: [ FUNCTION_TITLE, GENERIC_PARAMETERS, - FUNCTION_PARAMETERS + FUNCTION_PARAMETERS, + { + begin: /\s+/, + relevance: 0 + } ], illegal: /\[|%/ }; // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379 - const INIT_SUBSCRIPT_TITLE = { - begin: lookahead(/\b(subscript|init[?!]?)\s*[<(]/), - end: lookahead(/[<(]/), - relevance: 0, + const INIT_SUBSCRIPT = { + className: 'function', + begin: /\b(subscript|init[?!]?)\s*(?=[<(])/, + keywords: { + keyword: "subscript init init? init!", + $pattern: /\w+[?!]?/ + }, contains: [ - { - className: 'keyword', - begin: /subscript|init[?!]?/ - }, + GENERIC_PARAMETERS, + FUNCTION_PARAMETERS, { begin: /\s+/, relevance: 0 } - ] - }; - const INIT_SUBSCRIPT = { - className: 'function', - begin: lookahead(/\b(subscript|init[?!]?)\s*[<(]/), - contains: [ - INIT_SUBSCRIPT_TITLE, - GENERIC_PARAMETERS, - FUNCTION_PARAMETERS ], illegal: /\[|%/ }; diff --git a/test/markup/swift/tuples.expect.txt b/test/markup/swift/tuples.expect.txt index 28b22545fb..6b259a3343 100644 --- a/test/markup/swift/tuples.expect.txt +++ b/test/markup/swift/tuples.expect.txt @@ -12,3 +12,5 @@ /* y */ y ) +(let x, var y) +([key: value, key: value]) diff --git a/test/markup/swift/tuples.txt b/test/markup/swift/tuples.txt index 06ebea5c1f..c66e4bd33a 100644 --- a/test/markup/swift/tuples.txt +++ b/test/markup/swift/tuples.txt @@ -12,3 +12,5 @@ /* y */ y ) +(let x, var y) +([key: value, key: value]) From 9f2b9765b293e2b9983957b49d07eae71c609669 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Tue, 22 Dec 2020 10:22:52 -0500 Subject: [PATCH 3/4] simplify --- src/languages/swift.js | 62 +++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/src/languages/swift.js b/src/languages/swift.js index 5ed41a390c..2fdf4678cd 100644 --- a/src/languages/swift.js +++ b/src/languages/swift.js @@ -16,6 +16,10 @@ import { /** @type LanguageFn */ export default function(hljs) { + const WHITESPACE = { + begin: /\s+/, + relevance: 0 + }; // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID411 const BLOCK_COMMENT = hljs.COMMENT( '/\\*', @@ -215,22 +219,22 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html const AVAILABLE_ATTRIBUTE = { - begin: /(@|#)available\(/, - end: /\)/, - keywords: { - $pattern: /[@#]?\w+/, - keyword: Swift.availabilityKeywords - .concat([ - "@available", - "#available" - ]) - .join(' ') - }, - contains: [ - ...OPERATORS, - NUMBER, - STRING - ] + begin: /(@|#)available/, + className: "keyword", + starts: { + contains: [ + { + begin: /\(/, + end: /\)/, + keywords: Swift.availabilityKeywords.join(' '), + contains: [ + ...OPERATORS, + NUMBER, + STRING + ] + } + ] + } }; const KEYWORD_ATTRIBUTE = { className: 'keyword', @@ -291,8 +295,7 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552 // Prevents element names from being highlighted as keywords. const TUPLE_ELEMENT_NAME = { - begin: lookahead(concat(Swift.identifier, /\s*:/)), - end: lookahead(/:/), + begin: concat(Swift.identifier, /\s*:/), keywords: "_|0", relevance: 0 }; @@ -321,13 +324,9 @@ export default function(hljs) { // Matches both the keyword func and the function title. // Grouping these lets us differentiate between the operator function < // and the start of the generic parameter clause (also <). - const FUNCTION_TITLE = { + const FUNC_PLUS_TITLE = { beginKeywords: 'func', contains: [ - { - begin: /\s+/, - relevance: 0 - }, { className: 'title', begin: either(QUOTED_IDENTIFIER.begin, Swift.identifier, Swift.operator), @@ -335,7 +334,8 @@ export default function(hljs) { // isn't parsed as a second title. endsParent: true, relevance: 0 - } + }, + WHITESPACE ] }; const GENERIC_PARAMETERS = { @@ -351,7 +351,7 @@ export default function(hljs) { lookahead(concat(Swift.identifier, /\s*:/)), lookahead(concat(Swift.identifier, /\s+/, Swift.identifier, /\s*:/)) ), - end: lookahead(/:/), + end: /:/, relevance: 0, contains: [ { @@ -386,13 +386,10 @@ export default function(hljs) { className: 'function', begin: lookahead(/\bfunc\b/), contains: [ - FUNCTION_TITLE, + FUNC_PLUS_TITLE, GENERIC_PARAMETERS, FUNCTION_PARAMETERS, - { - begin: /\s+/, - relevance: 0 - } + WHITESPACE ], illegal: /\[|%/ }; @@ -409,10 +406,7 @@ export default function(hljs) { contains: [ GENERIC_PARAMETERS, FUNCTION_PARAMETERS, - { - begin: /\s+/, - relevance: 0 - } + WHITESPACE ], illegal: /\[|%/ }; From f4f714207214aa3691d42aa928385d61f9ad78b9 Mon Sep 17 00:00:00 2001 From: Josh Goebel Date: Wed, 23 Dec 2020 10:17:15 -0500 Subject: [PATCH 4/4] use match --- src/languages/swift.js | 71 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/languages/swift.js b/src/languages/swift.js index 2fdf4678cd..5f8e1a7389 100644 --- a/src/languages/swift.js +++ b/src/languages/swift.js @@ -17,7 +17,7 @@ import { /** @type LanguageFn */ export default function(hljs) { const WHITESPACE = { - begin: /\s+/, + match: /\s+/, relevance: 0 }; // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID411 @@ -43,7 +43,7 @@ export default function(hljs) { }; const KEYWORD_GUARD = { // Consume .keyword to prevent highlighting properties and methods as keywords. - begin: concat(/\./, either(...Swift.keywords)), + match: concat(/\./, either(...Swift.keywords)), relevance: 0 }; const PLAIN_KEYWORDS = Swift.keywords @@ -57,7 +57,7 @@ export default function(hljs) { variants: [ { className: 'keyword', - begin: either(...REGEX_KEYWORDS, ...Swift.optionalDotKeywords) + match: either(...REGEX_KEYWORDS, ...Swift.optionalDotKeywords) } ] }; @@ -81,12 +81,12 @@ export default function(hljs) { // https://github.com/apple/swift/tree/main/stdlib/public/core const BUILT_IN_GUARD = { // Consume .built_in to prevent highlighting properties and methods. - begin: concat(/\./, either(...Swift.builtIns)), + match: concat(/\./, either(...Swift.builtIns)), relevance: 0 }; const BUILT_IN = { className: 'built_in', - begin: concat(/\b/, either(...Swift.builtIns), /(?=\()/) + match: concat(/\b/, either(...Swift.builtIns), /(?=\()/) }; const BUILT_INS = [ BUILT_IN_GUARD, @@ -96,7 +96,7 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418 const OPERATOR_GUARD = { // Prevent -> from being highlighting as an operator. - begin: /->/, + match: /->/, relevance: 0 }; const OPERATOR = { @@ -104,13 +104,13 @@ export default function(hljs) { relevance: 0, variants: [ { - begin: Swift.operator + match: Swift.operator }, { // dot-operator: only operators that start with a dot are allowed to use dots as // characters (..., ...<, .*, etc). So there rule here is: a dot followed by one or more // characters that may also include dots. - begin: `\\.(\\.|${Swift.operatorCharacter})+` + match: `\\.(\\.|${Swift.operatorCharacter})+` } ] }; @@ -129,19 +129,19 @@ export default function(hljs) { variants: [ // decimal floating-point-literal (subsumes decimal-literal) { - begin: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b` + match: `\\b(${decimalDigits})(\\.(${decimalDigits}))?` + `([eE][+-]?(${decimalDigits}))?\\b` }, // hexadecimal floating-point-literal (subsumes hexadecimal-literal) { - begin: `\\b0x(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b` + match: `\\b0x(${hexDigits})(\\.(${hexDigits}))?` + `([pP][+-]?(${decimalDigits}))?\\b` }, // octal-literal { - begin: /\b0o([0-7]_*)+\b/ + match: /\b0o([0-7]_*)+\b/ }, // binary-literal { - begin: /\b0b([01]_*)+\b/ + match: /\b0b([01]_*)+\b/ } ] }; @@ -151,16 +151,16 @@ export default function(hljs) { className: 'subst', variants: [ { - begin: concat(/\\/, rawDelimiter, /[0\\tnr"']/) + match: concat(/\\/, rawDelimiter, /[0\\tnr"']/) }, { - begin: concat(/\\/, rawDelimiter, /u\{[0-9a-fA-F]{1,8}\}/) + match: concat(/\\/, rawDelimiter, /u\{[0-9a-fA-F]{1,8}\}/) } ] }); const ESCAPED_NEWLINE = (rawDelimiter = "") => ({ className: 'subst', - begin: concat(/\\/, rawDelimiter, /[\t ]*(?:[\r\n]|\r\n)/) + match: concat(/\\/, rawDelimiter, /[\t ]*(?:[\r\n]|\r\n)/) }); const INTERPOLATION = (rawDelimiter = "") => ({ className: 'subst', @@ -201,15 +201,15 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412 const QUOTED_IDENTIFIER = { - begin: concat(/`/, Swift.identifier, /`/) + match: concat(/`/, Swift.identifier, /`/) }; const IMPLICIT_PARAMETER = { className: 'variable', - begin: /\$\d+/ + match: /\$\d+/ }; const PROPERTY_WRAPPER_PROJECTION = { className: 'variable', - begin: `\\$${Swift.identifierCharacter}+` + match: `\\$${Swift.identifierCharacter}+` }; const IDENTIFIERS = [ QUOTED_IDENTIFIER, @@ -219,7 +219,7 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Attributes.html const AVAILABLE_ATTRIBUTE = { - begin: /(@|#)available/, + match: /(@|#)available/, className: "keyword", starts: { contains: [ @@ -238,11 +238,11 @@ export default function(hljs) { }; const KEYWORD_ATTRIBUTE = { className: 'keyword', - begin: concat(/@/, either(...Swift.keywordAttributes)) + match: concat(/@/, either(...Swift.keywordAttributes)) }; const USER_DEFINED_ATTRIBUTE = { className: 'meta', - begin: concat(/@/, Swift.identifier) + match: concat(/@/, Swift.identifier) }; const ATTRIBUTES = [ AVAILABLE_ATTRIBUTE, @@ -252,28 +252,28 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Types.html const TYPE = { - begin: lookahead(/\b[A-Z]/), + match: lookahead(/\b[A-Z]/), relevance: 0, contains: [ { // Common Apple frameworks, for relevance boost className: 'type', - begin: concat(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/, Swift.identifierCharacter, '+') + match: concat(/(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)/, Swift.identifierCharacter, '+') }, { // Type identifier className: 'type', - begin: Swift.typeIdentifier, + match: Swift.typeIdentifier, relevance: 0 }, { // Optional type - begin: /[?!]+/, + match: /[?!]+/, relevance: 0 }, { // Variadic parameter - begin: /\.\.\./, + match: /\.\.\./, relevance: 0 }, { // Protocol composition - begin: concat(/\s+&\s+/, lookahead(Swift.typeIdentifier)), + match: concat(/\s+&\s+/, lookahead(Swift.typeIdentifier)), relevance: 0 } ] @@ -295,7 +295,7 @@ export default function(hljs) { // https://docs.swift.org/swift-book/ReferenceManual/Expressions.html#ID552 // Prevents element names from being highlighted as keywords. const TUPLE_ELEMENT_NAME = { - begin: concat(Swift.identifier, /\s*:/), + match: concat(Swift.identifier, /\s*:/), keywords: "_|0", relevance: 0 }; @@ -329,7 +329,7 @@ export default function(hljs) { contains: [ { className: 'title', - begin: either(QUOTED_IDENTIFIER.begin, Swift.identifier, Swift.operator), + match: either(QUOTED_IDENTIFIER.match, Swift.identifier, Swift.operator), // Required to make sure the opening < of the generic parameter clause // isn't parsed as a second title. endsParent: true, @@ -356,11 +356,11 @@ export default function(hljs) { contains: [ { className: 'keyword', - begin: /\b_\b/ + match: /\b_\b/ }, { className: 'params', - begin: Swift.identifier + match: Swift.identifier } ] }; @@ -384,21 +384,24 @@ export default function(hljs) { }; const FUNCTION = { className: 'function', - begin: lookahead(/\bfunc\b/), + match: lookahead(/\bfunc\b/), contains: [ FUNC_PLUS_TITLE, GENERIC_PARAMETERS, FUNCTION_PARAMETERS, WHITESPACE ], - illegal: /\[|%/ + illegal: [ + /\[/, + /%/ + ] }; // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID375 // https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID379 const INIT_SUBSCRIPT = { className: 'function', - begin: /\b(subscript|init[?!]?)\s*(?=[<(])/, + match: /\b(subscript|init[?!]?)\s*(?=[<(])/, keywords: { keyword: "subscript init init? init!", $pattern: /\w+[?!]?/