-
Notifications
You must be signed in to change notification settings - Fork 3.7k
(swift) Revamped keywords and added support for operators #2908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
60a32b2
5d1e17c
4adf9ed
2bb4994
8a7c3f9
86b7c81
09be110
1026ac0
da01153
2a1163e
f8510bd
b5e2767
71ce42e
d249413
0d679d1
f5f3043
1e2c56d
1e55113
821d247
ea6d8df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -310,3 +310,4 @@ Contributors: | |
| - Kyle Brown <kylebrown9@github> | ||
| - Marcus Ortiz <[email protected]> | ||
| - Guillaume Grossetie <[email protected]> | ||
| - Steven Van Impe <[email protected]> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,39 +7,52 @@ Website: https://swift.org | |
| Category: common, system | ||
| */ | ||
|
|
||
| import { either } from "../lib/regex"; | ||
|
|
||
| export default function(hljs) { | ||
| var SWIFT_KEYWORDS = { | ||
| // override the pattern since the default of of /\w+/ is not sufficient to | ||
| // capture the keywords that start with the character "#" | ||
| $pattern: /[\w#]+/, | ||
| keyword: '#available #colorLiteral #column #else #elseif #endif #file ' + | ||
| '#fileLiteral #function #if #imageLiteral #line #selector #sourceLocation ' + | ||
| '_ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype ' + | ||
| 'associativity break case catch class continue convenience default defer deinit didSet do ' + | ||
| 'dynamic dynamicType else enum extension fallthrough false fileprivate final for func ' + | ||
| 'get guard if import in indirect infix init inout internal is lazy left let ' + | ||
| 'mutating nil none nonmutating open operator optional override postfix precedence ' + | ||
| 'prefix private protocol Protocol public repeat required rethrows return ' + | ||
| 'right self Self set some static struct subscript super switch throw throws true ' + | ||
| 'try try! try? Type typealias unowned var weak where while willSet', | ||
| literal: 'true false nil', | ||
| built_in: 'abs advance alignof alignofValue anyGenerator assert assertionFailure ' + | ||
| 'bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC ' + | ||
| 'bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros ' + | ||
| 'debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords ' + | ||
| 'enumerate equal fatalError filter find getBridgedObjectiveCType getVaList ' + | ||
| 'indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC ' + | ||
| 'isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare ' + | ||
| 'map max maxElement min minElement numericCast overlaps partition posix ' + | ||
| 'precondition preconditionFailure print println quickSort readLine reduce reflect ' + | ||
| 'reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split ' + | ||
| 'startsWith stride strideof strideofValue swap toString transcode ' + | ||
| 'underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap ' + | ||
| 'unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer ' + | ||
| 'withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers ' + | ||
| 'withUnsafePointer withUnsafePointers withVaList zip' | ||
| }; | ||
| // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID413 | ||
| // https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html | ||
| const SWIFT_KEYWORDS = { | ||
| // Override the pattern since the default of /\w+/ is not sufficient to capture | ||
| // the keywords that start with a number sign (#) or that have parentheses. | ||
| $pattern: /#?\w+(\(\w+\))?/, | ||
| keyword: | ||
| // Reserved keywords. These require backticks to use as an identifier: | ||
| '_ Any as associatedtype break case catch class continue default defer deinit do else enum extension ' + | ||
| 'fallthrough fileprivate fileprivate(set) for func guard if import in init inout internal internal(set) is ' + | ||
| 'let operator precedencegroup private private(set) protocol public public(set) repeat rethrows return ' + | ||
| 'self Self static struct subscript super switch throw throws try typealias var where while ' + | ||
| // This list includes as, is, and try, even though they're technically operators. | ||
| // The remaining operators as?, as!, try?, and try! are declared in the OPERATOR mode. | ||
|
|
||
| // Keywords that begin with a number sign: | ||
| '#available #colorLiteral #column #dsohandle #else #elseif #endif #error #file #fileID #fileLiteral #filePath ' + | ||
| '#function #if #imageLiteral #keyPath #line #selector #sourceLocation #warning ' + | ||
|
|
||
| // Keywords reserved in particular contexts. These can be used as identifiers: | ||
| 'convenience didSet dynamic final get infix indirect lazy mutating nonmutating open open(set) ' + | ||
| 'optional override postfix prefix Protocol required set some Type unowned unowned(safe) unowned(unsafe) weak willSet ', | ||
| // Ideally, these keywords should only be matched in specific modes, as they can result in false positives. | ||
| // For example, the following keywords are commented out because they're only used in | ||
| // precedencegroup declarations, so they will likely result in mostly false positives: | ||
| // 'assignment associativity higherThan left lowerThan none right ' | ||
| literal: 'true false nil', | ||
| built_in: 'abs advance alignof alignofValue anyGenerator assert assertionFailure ' + | ||
| 'bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC ' + | ||
| 'bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros ' + | ||
| 'debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords ' + | ||
| 'enumerate equal fatalError filter find getBridgedObjectiveCType getVaList ' + | ||
| 'indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC ' + | ||
| 'isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare ' + | ||
| 'map max maxElement min minElement numericCast overlaps partition posix ' + | ||
| 'precondition preconditionFailure print println quickSort readLine reduce reflect ' + | ||
| 'reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split ' + | ||
| 'startsWith stride strideof strideofValue swap toString transcode ' + | ||
| 'underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap ' + | ||
| 'unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer ' + | ||
| 'withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers ' + | ||
| 'withUnsafePointer withUnsafePointers withVaList zip' | ||
| }; | ||
|
|
||
| var TYPE = { | ||
| className: 'type', | ||
|
|
@@ -98,13 +111,72 @@ export default function(hljs) { | |
| }; | ||
| SUBST.contains = [NUMBER]; | ||
|
|
||
| // https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID418 | ||
| const operatorHead = either( | ||
| /[/=\-+!*%<>&|^~?]/, | ||
| /[\u00A1–\u00A7]/, | ||
| /[\u00A9\u00AB]/, | ||
| /[\u00AC\u00AE]/, | ||
| /[\u00B0\u00B1]/, | ||
| /[\u00B6\u00BB\u00BF\u00D7\u00F7]/, | ||
| /[\u2016–\u2017]/, | ||
| /[\u2020–\u2027]/, | ||
| /[\u2030–\u203E]/, | ||
| /[\u2041–\u2053]/, | ||
| /[\u2055–\u205E]/, | ||
| /[\u2190–\u23FF]/, | ||
| /[\u2500–\u2775]/, | ||
| /[\u2794–\u2BFF]/, | ||
| /[\u2E00–\u2E7F]/, | ||
| /[\u3001–\u3003]/, | ||
| /[\u3008–\u3020]/, | ||
| /[\u3030]/ | ||
| ); | ||
| const operatorCharacter = either( | ||
| operatorHead, | ||
| /[\u0300–\u036F]/, | ||
| /[\u1DC0–\u1DFF]/, | ||
| /[\u20D0–\u20FF]/, | ||
| /[\uFE00–\uFE0F]/, | ||
| /[\uFE20–\uFE2F]/, | ||
| // TODO: The following characters are also allowed, but the regex doesn't work as intended. | ||
| // For example, it also matches -10 as an operator. | ||
| // /[\u{E0100}–\u{E01EF}]/u | ||
|
||
| ); | ||
| const OPERATOR = { | ||
| className: 'operator', | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these operators or keywords?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this question about If so, the grammar specifies them as operators and keywords at the same time, so I'm highlighting them as keywords, which is what other grammars do too, although most don't bother highlighting the question or exlamation mark. I preferred to include that in the match, otherwise it would be matched as a postfix operator.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If they are keywords then you should remove "operator", it's not serving any purpose. We can't have them be both (not desirable).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I'll add them to list of "special" keywords (like the ones that have parentheses) instead, so I don't have to change the keywords $pattern to allow question marks or exclamation points. My goal here was to group these keywords under the "operator" umbrella as well, in case a future grammar says "any operator is allowed here", which would then also include these keywords.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think you may be over thinking that. :) |
||
| variants: [ | ||
| { // TODO: Replace with negative look-behind when available. | ||
| className: 'keyword', | ||
| begin: /\s(?=as[?!]?\s)/, | ||
| excludeBegin: true, | ||
joshgoebel marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| end: /as[?!]?(?=\s)/ | ||
| }, | ||
| { // TODO: Replace with negative look-behind when available. | ||
| className: 'keyword', | ||
| begin: /\s(?=is\s)/, | ||
| excludeBegin: true, | ||
| end: /is(?=\s)/ | ||
joshgoebel marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }, | ||
| { // TODO: Replace with negative look-behind when available. | ||
| className: 'keyword', | ||
| begin: /(^|[^.])(?=\btry[?!]?\s)/, | ||
| excludeBegin: true, | ||
| end: /try[?!]?(?=\s)/ | ||
| }, | ||
| { begin: `${operatorHead}${operatorCharacter}*` }, | ||
| { begin: `\\.(\\.|${operatorCharacter})+` } | ||
| ] | ||
| }; | ||
|
|
||
| return { | ||
| name: 'Swift', | ||
| keywords: SWIFT_KEYWORDS, | ||
| contains: [ | ||
| STRING, | ||
| hljs.C_LINE_COMMENT_MODE, | ||
| BLOCK_COMMENT, | ||
| OPERATOR, | ||
| OPTIONAL_USING_TYPE, | ||
| TYPE, | ||
| NUMBER, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| <span class="hljs-keyword">var</span> string = <span class="hljs-string">""" | ||
| <span class="hljs-keyword">var</span> string <span class="hljs-operator">=</span> <span class="hljs-string">""" | ||
| var a = not actually code | ||
| """</span> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| x <span class="hljs-keyword">is</span> y | ||
| x.is(y) | ||
| x <span class="hljs-keyword">as</span> y | ||
| x <span class="hljs-keyword">as?</span> y | ||
| x <span class="hljs-keyword">as!</span> y | ||
| a.as(y) | ||
| <span class="hljs-keyword">try</span> x | ||
| <span class="hljs-keyword">try?</span> x | ||
| <span class="hljs-keyword">try!</span> x | ||
| x.try(y) | ||
|
|
||
| <span class="hljs-operator">!</span><span class="hljs-literal">true</span> | ||
| <span class="hljs-operator">~</span>x | ||
| <span class="hljs-operator">+</span><span class="hljs-number">1</span> | ||
| <span class="hljs-operator">-</span><span class="hljs-number">1</span> | ||
| <span class="hljs-operator">..<</span><span class="hljs-number">1</span> | ||
| <span class="hljs-operator">...</span><span class="hljs-number">1</span> | ||
| <span class="hljs-number">0</span><span class="hljs-operator">...</span> | ||
| a<span class="hljs-operator">?</span> | ||
| a<span class="hljs-operator">!</span> | ||
|
|
||
| a <span class="hljs-operator"><<</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator"><<</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">>></span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">>></span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">*</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">*</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">/</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">/</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">%</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">%</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">&*</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">&*</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">&</span> b | ||
| a<span class="hljs-operator">&</span>b | ||
| a <span class="hljs-operator">+</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">+</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">-</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">-</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">&+</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">&+</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">&-</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">&-</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">|</span> b | ||
| a<span class="hljs-operator">|</span>b | ||
| a <span class="hljs-operator">^</span> b | ||
| a<span class="hljs-operator">^</span>b | ||
| <span class="hljs-number">0</span> <span class="hljs-operator">..<</span> <span class="hljs-number">1</span> | ||
| <span class="hljs-number">0</span><span class="hljs-operator">..<</span><span class="hljs-number">1</span> | ||
| <span class="hljs-number">0</span> <span class="hljs-operator">...</span> <span class="hljs-number">1</span> | ||
| <span class="hljs-number">0</span><span class="hljs-operator">...</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">??</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">??</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator"><</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator"><</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator"><=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator"><=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">></span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">></span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">>=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">>=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">==</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">==</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">!=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">!=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">===</span> b | ||
| a<span class="hljs-operator">===</span>b | ||
| a <span class="hljs-operator">!==</span> b | ||
| a<span class="hljs-operator">!==</span>b | ||
| a <span class="hljs-operator">~=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">~=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">.==</span> b | ||
| a<span class="hljs-operator">.==</span>b | ||
| a <span class="hljs-operator">.!=</span> b | ||
| a<span class="hljs-operator">.!=</span>b | ||
| a <span class="hljs-operator">.<</span> b | ||
| a<span class="hljs-operator">.<</span>b | ||
| a <span class="hljs-operator">.<=</span> b | ||
| a<span class="hljs-operator">.<=</span>b | ||
| a <span class="hljs-operator">.></span> b | ||
| a<span class="hljs-operator">.></span>b | ||
| a <span class="hljs-operator">.>=</span> b | ||
| a<span class="hljs-operator">.>=</span>b | ||
| <span class="hljs-literal">true</span> <span class="hljs-operator">&&</span> <span class="hljs-literal">false</span> | ||
| <span class="hljs-literal">true</span><span class="hljs-operator">&&</span><span class="hljs-literal">false</span> | ||
| <span class="hljs-literal">true</span> <span class="hljs-operator">||</span> <span class="hljs-literal">false</span> | ||
| <span class="hljs-literal">true</span><span class="hljs-operator">||</span><span class="hljs-literal">false</span> | ||
| a <span class="hljs-operator">=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">*=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">*=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">/=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">/=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">%=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">%=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">+=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">+=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">-=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">-=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator"><<=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator"><<=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">>>=</span> <span class="hljs-number">1</span> | ||
| a<span class="hljs-operator">>>=</span><span class="hljs-number">1</span> | ||
| a <span class="hljs-operator">&=</span> b | ||
| a<span class="hljs-operator">&=</span>b | ||
| a <span class="hljs-operator">|=</span> b | ||
| a<span class="hljs-operator">|=</span>b | ||
| a <span class="hljs-operator">^=</span> b | ||
| a<span class="hljs-operator">^=</span>b |
Uh oh!
There was an error while loading. Please reload this page.