|
@@ -26,6 +26,7 @@ class JavaScriptHighlighter {
|
26
|
26
|
private var attributed: NSMutableAttributedString
|
27
|
27
|
private var currentIndex: String.Index!
|
28
|
28
|
private var indent = ""
|
|
29
|
+ private(set) var tokens = [(token: TokenType, range: NSRange)]()
|
29
|
30
|
|
30
|
31
|
init(text: String) {
|
31
|
32
|
self.text = text
|
|
@@ -94,6 +95,7 @@ class JavaScriptHighlighter {
|
94
|
95
|
return
|
95
|
96
|
}
|
96
|
97
|
attributed.addAttribute(.foregroundColor, value: color, range: range)
|
|
98
|
+ tokens.append((token, range))
|
97
|
99
|
}
|
98
|
100
|
|
99
|
101
|
private func consumeExpression() {
|
|
@@ -173,32 +175,42 @@ class JavaScriptHighlighter {
|
173
|
175
|
|
174
|
176
|
private func consumeTemplateString() {
|
175
|
177
|
var stringFragmentStart: String.Index? = currentIndex
|
|
178
|
+
|
|
179
|
+ func emitTemplateStringFragment() {
|
|
180
|
+ guard stringFragmentStart != currentIndex else { return }
|
|
181
|
+ print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'")
|
|
182
|
+ emit(token: .string, range: range(from: stringFragmentStart!, to: currentIndex))
|
|
183
|
+ stringFragmentStart = currentIndex
|
|
184
|
+ }
|
|
185
|
+
|
176
|
186
|
consume() // opening `
|
|
187
|
+
|
177
|
188
|
while currentIndex < text.endIndex {
|
178
|
|
- if peek(length: 2) == "${" {
|
|
189
|
+ if peek() == "$" {
|
|
190
|
+ emitTemplateStringFragment()
|
179
|
191
|
consume() // $
|
180
|
|
- consume() // {
|
181
|
|
- print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'")
|
182
|
|
- emit(token: .string, range: range(from: stringFragmentStart!, to: currentIndex))
|
183
|
|
- consumeTemplateStringExpression()
|
184
|
|
- stringFragmentStart = currentIndex
|
185
|
|
- if currentIndex < text.endIndex && peek() == "}" {
|
186
|
|
- consume()
|
|
192
|
+ if peek() == "{" {
|
|
193
|
+ consume() // {
|
|
194
|
+ emitTemplateStringFragment()
|
|
195
|
+ consumeTemplateStringExpression()
|
|
196
|
+ stringFragmentStart = currentIndex
|
|
197
|
+ if currentIndex < text.endIndex && peek() == "}" {
|
|
198
|
+ consume() // }
|
|
199
|
+ }
|
|
200
|
+
|
187
|
201
|
}
|
188
|
202
|
} else if peek() == "`" {
|
189
|
203
|
stringFragmentStart = stringFragmentStart ?? currentIndex
|
190
|
204
|
consume() // `
|
191
|
|
- print("Template string fragment: '\(text[stringFragmentStart!..<currentIndex])'")
|
192
|
|
- emit(token: .string, range: range(from: stringFragmentStart!, to: currentIndex))
|
|
205
|
+ emitTemplateStringFragment()
|
193
|
206
|
stringFragmentStart = nil
|
194
|
207
|
break
|
195
|
208
|
} else {
|
196
|
209
|
consume()
|
197
|
210
|
}
|
198
|
211
|
}
|
199
|
|
- if let start = stringFragmentStart {
|
200
|
|
- print("Template string fragment: '\(text[start..<currentIndex])'")
|
201
|
|
- emit(token: .string, range: range(from: start, to: currentIndex))
|
|
212
|
+ if stringFragmentStart != nil {
|
|
213
|
+ emitTemplateStringFragment()
|
202
|
214
|
}
|
203
|
215
|
}
|
204
|
216
|
|