Skip to content

Commit 8541db2

Browse files
Swift: Major improvements (#3022)
1 parent 748bb9a commit 8541db2

22 files changed

+883
-168
lines changed

components.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,6 @@
12211221
},
12221222
"swift": {
12231223
"title": "Swift",
1224-
"require": "clike",
12251224
"owner": "chrischares"
12261225
},
12271226
"t4-templating": {

components/prism-swift.js

Lines changed: 143 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,148 @@
1-
// issues: nested multiline comments
2-
Prism.languages.swift = Prism.languages.extend('clike', {
3-
'string': {
4-
pattern: /("|')(?:\\(?:\((?:[^()]|\([^)]+\))+\)|\r\n|[^(])|(?!\1)[^\\\r\n])*\1/,
5-
greedy: true,
6-
inside: {
7-
'interpolation': {
8-
pattern: /\\\((?:[^()]|\([^)]+\))+\)/,
9-
inside: {
10-
delimiter: {
11-
pattern: /^\\\(|\)$/,
12-
alias: 'variable'
13-
}
14-
// See rest below
15-
}
1+
Prism.languages.swift = {
2+
'comment': {
3+
// Nested comments are supported up to 2 levels
4+
pattern: /(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,
5+
lookbehind: true,
6+
greedy: true
7+
},
8+
'string-literal': [
9+
// https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
10+
{
11+
pattern: RegExp(
12+
/(^|[^"#])/.source
13+
+ '(?:'
14+
// single-line string
15+
+ /"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source
16+
+ '|'
17+
// multi-line string
18+
+ /"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source
19+
+ ')'
20+
+ /(?!["#])/.source
21+
),
22+
lookbehind: true,
23+
greedy: true,
24+
inside: {
25+
'interpolation': {
26+
pattern: /(\\\()(?:[^()]|\([^()]*\))*(?=\))/,
27+
lookbehind: true,
28+
inside: null // see below
29+
},
30+
'interpolation-punctuation': {
31+
pattern: /^\)|\\\($/,
32+
alias: 'punctuation'
33+
},
34+
'punctuation': /\\(?=[\r\n])/,
35+
'string': /[\s\S]+/
36+
}
37+
},
38+
{
39+
pattern: RegExp(
40+
/(^|[^"#])(#+)/.source
41+
+ '(?:'
42+
// single-line string
43+
+ /"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source
44+
+ '|'
45+
// multi-line string
46+
+ /"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source
47+
+ ')'
48+
+ '\\2'
49+
),
50+
lookbehind: true,
51+
greedy: true,
52+
inside: {
53+
'interpolation': {
54+
pattern: /(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,
55+
lookbehind: true,
56+
inside: null // see below
57+
},
58+
'interpolation-punctuation': {
59+
pattern: /^\)|\\#+\($/,
60+
alias: 'punctuation'
61+
},
62+
'string': /[\s\S]+/
1663
}
64+
},
65+
],
66+
67+
'directive': {
68+
// directives with conditions
69+
pattern: RegExp(
70+
/#/.source
71+
+ '(?:'
72+
+ (
73+
/(?:elseif|if)\b/.source
74+
+ '(?:[ \t]*'
75+
// This regex is a little complex. It's equivalent to this:
76+
// (?:![ \t]*)?(?:\b\w+\b(?:[ \t]*<round>)?|<round>)(?:[ \t]*(?:&&|\|\|))?
77+
// where <round> is a general parentheses expression.
78+
+ /(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source
79+
+ ')+'
80+
)
81+
+ '|'
82+
+ /(?:else|endif)\b/.source
83+
+ ')'
84+
),
85+
alias: 'property',
86+
inside: {
87+
'directive-name': /^#\w+/,
88+
'boolean': /\b(?:true|false)\b/,
89+
'number': /\b\d+(?:\.\d+)*\b/,
90+
'operator': /!|&&|\|\||[<>]=?/,
91+
'punctuation': /[(),]/
1792
}
1893
},
19-
'keyword': /\b(?:actor|as|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic(?:Type)?|else|enum|extension|fallthrough|final|for|func|get|guard|if|import|in|infix|init|inout|internal|is|lazy|left|let|mutating|new|none|nonisolated|nonmutating|operator|optional|override|postfix|precedence|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|Self|set|some|static|struct|subscript|super|switch|throws?|try|Type|typealias|unowned|unsafe|var|weak|where|while|willSet|__(?:COLUMN__|FILE__|FUNCTION__|LINE__))\b/,
94+
'literal': {
95+
pattern: /#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,
96+
alias: 'constant'
97+
},
98+
'other-directive': {
99+
pattern: /#\w+\b/,
100+
alias: 'property'
101+
},
102+
103+
'attribute': {
104+
pattern: /@\w+/,
105+
alias: 'atrule'
106+
},
107+
108+
'function-definition': {
109+
pattern: /(\bfunc\s+)\w+/,
110+
lookbehind: true,
111+
alias: 'function'
112+
},
113+
'label': {
114+
// https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html#ID141
115+
pattern: /\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,
116+
lookbehind: true,
117+
alias: 'important'
118+
},
119+
120+
'keyword': /\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,
121+
'boolean': /\b(?:true|false)\b/,
122+
'nil': {
123+
pattern: /\bnil\b/,
124+
alias: 'constant'
125+
},
126+
127+
'short-argument': /\$\d+\b/,
128+
'omit': {
129+
pattern: /\b_\b/,
130+
alias: 'keyword'
131+
},
20132
'number': /\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,
21-
'constant': /\b(?:nil|[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,
22-
'atrule': /@\b(?:IB(?:Outlet|Designable|Action|Inspectable)|class_protocol|exported|globalActor|MainActor|noreturn|NS(?:Copying|Managed)|objc|propertyWrapper|UIApplicationMain|auto_closure)\b/,
23-
'builtin': /\b(?:[A-Z]\S+|abs|advance|alignof(?:Value)?|assert|contains|count(?:Elements)?|debugPrint(?:ln)?|distance|drop(?:First|Last)|dump|enumerate|equal|filter|find|first|getVaList|indices|isEmpty|join|last|lexicographicalCompare|map|max(?:Element)?|min(?:Element)?|numericCast|overlaps|partition|print(?:ln)?|reduce|reflect|reverse|sizeof(?:Value)?|sort(?:ed)?|split|startsWith|stride(?:of(?:Value)?)?|suffix|swap|toDebugString|toString|transcode|underestimateCount|unsafeBitCast|with(?:ExtendedLifetime|Unsafe(?:MutablePointers?|Pointers?)|VaList))\b/
133+
134+
// A class name must start with an upper-case letter and be either 1 letter long or contain a lower-case letter.
135+
'class-name': /\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,
136+
'function': /\b[a-z_]\w*(?=\s*\()/i,
137+
'constant': /\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,
138+
139+
// Operators are generic in Swift. Developers can even create new operators (e.g. +++).
140+
// https://docs.swift.org/swift-book/ReferenceManual/zzSummaryOfTheGrammar.html#ID481
141+
// This regex only supports ASCII operators.
142+
'operator': /[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,
143+
'punctuation': /[{}[\]();,.:\\]/
144+
};
145+
146+
Prism.languages.swift['string-literal'].forEach(function (rule) {
147+
rule.inside['interpolation'].inside = Prism.languages.swift;
24148
});
25-
Prism.languages.swift['string'].inside['interpolation'].inside.rest = Prism.languages.swift;

components/prism-swift.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/autoloader/prism-autoloader.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@
135135
"sparql": "turtle",
136136
"sqf": "clike",
137137
"squirrel": "clike",
138-
"swift": "clike",
139138
"t4-cs": [
140139
"t4-templating",
141140
"csharp"

0 commit comments

Comments
 (0)