0001    // The MIT License
0002    //
0003    // Copyright (c) 2015 Gwendal Roué
0004    //
0005    // Permission is hereby granted, free of charge, to any person obtaining a copy
0006    // of this software and associated documentation files (the "Software"), to deal
0007    // in the Software without restriction, including without limitation the rights
0008    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0009    // copies of the Software, and to permit persons to whom the Software is
0010    // furnished to do so, subject to the following conditions:
0011    //
0012    // The above copyright notice and this permission notice shall be included in
0013    // all copies or substantial portions of the Software.
0014    //
0015    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0016    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0017    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0018    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0019    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0020    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0021    // THE SOFTWARE.
0022    
0023    protocol TemplateTokenConsumer
TemplateCompiler.swift:23
final class TemplateCompiler: TemplateTokenConsumer {
TemplateParser.swift:44
    let tokenConsumer: TemplateTokenConsumer
TemplateParser.swift:47
    init(tokenConsumer: TemplateTokenConsumer, tagDelimiterPair: TagDelimiterPair) {
{ 0024 func parser
TemplateParser.swift:100
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:115
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:130
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:152
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:163
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:174
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:185
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:196
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:207
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:218
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:229
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:240
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:251
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:271
                    if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:296
                    if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:324
            tokenConsumer.parser(self, shouldContinueAfterParsingToken: token)
(parser:TemplateParser, shouldContinueAfterParsingToken token:TemplateToken) -> Bool 0025 func parser
TemplateParser.swift:286
                        tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:327
            tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:330
            tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:333
            tokenConsumer.parser(self, didFailWithError: error)
(parser:TemplateParser, didFailWithError error:ErrorType) 0026 } 0027 0028 extension String { 0029 func hasPrefix
TemplateParser.swift:60
            return subs.hasPrefix(string)
(string: String) -> Bool { 0030 if string.characters.count > self.characters.count { 0031 return false 0032 } 0033 for i in 0 ..< string.characters.count { 0034 if string.characters[string.characters.startIndex.advancedBy(i)] != 0035 self.characters[self.characters.startIndex.advancedBy(i)] { 0036 return false 0037 } 0038 } 0039 return true 0040 } 0041 } 0042 0043 final class TemplateParser
TemplateCompiler.swift:57
    func parser(parser: TemplateParser, didFailWithError error: ErrorType) {
TemplateCompiler.swift:61
    func parser(parser: TemplateParser, shouldContinueAfterParsingToken token: TemplateToken) -> Bool {
TemplateParser.swift:24
    func parser(parser:TemplateParser, shouldContinueAfterParsingToken token:TemplateToken) -> Bool
TemplateParser.swift:25
    func parser(parser:TemplateParser, didFailWithError error:ErrorType)
TemplateRepository.swift:282
        let parser = TemplateParser(
{ 0044 let tokenConsumer
TemplateParser.swift:48
        self.tokenConsumer = tokenConsumer
TemplateParser.swift:100
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:115
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:130
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:152
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:163
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:174
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:185
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:196
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:207
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:218
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:229
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:240
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:251
                        if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:271
                    if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:286
                        tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:296
                    if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) {
TemplateParser.swift:324
            tokenConsumer.parser(self, shouldContinueAfterParsingToken: token)
TemplateParser.swift:327
            tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:330
            tokenConsumer.parser(self, didFailWithError: error)
TemplateParser.swift:333
            tokenConsumer.parser(self, didFailWithError: error)
: TemplateTokenConsumer 0045 private let tagDelimiterPair
TemplateParser.swift:49
        self.tagDelimiterPair = tagDelimiterPair
TemplateParser.swift:53
        var currentDelimiters = ParserTagDelimiters(tagDelimiterPair: tagDelimiterPair)
: TagDelimiterPair 0046 0047 init
TemplateRepository.swift:282
        let parser = TemplateParser(
(tokenConsumer: TemplateTokenConsumer, tagDelimiterPair: TagDelimiterPair) { 0048 self.tokenConsumer = tokenConsumer 0049 self.tagDelimiterPair = tagDelimiterPair 0050 } 0051 0052 func parse
TemplateRepository.swift:287
        parser.parse(string, templateID: templateID)
(templateString:String, templateID: TemplateID?) { 0053 var currentDelimiters = ParserTagDelimiters(tagDelimiterPair: tagDelimiterPair) 0054 0055 let atString = { (index: String.Index, string: String?) -> Bool in 0056 guard let string = string else { 0057 return false 0058 } 0059 let subs = templateString.substringFromIndex(index) 0060 return subs.hasPrefix(string) 0061 } 0062 0063 var state: State = .Start 0064 var lineNumber = 1 0065 var i = templateString.startIndex 0066 let end = templateString.endIndex 0067 0068 while i < end { 0069 let c = templateString[i] 0070 0071 switch state { 0072 case .Start: 0073 if c == "\n" { 0074 state = .Text(startIndex: i, startLineNumber: lineNumber) 0075 lineNumber -= 1 0076 } else if atString(i, currentDelimiters.unescapedTagStart) { 0077 state = .UnescapedTag(startIndex: i, startLineNumber: lineNumber) 0078 i = i.advancedBy(currentDelimiters.unescapedTagStartLength).predecessor() 0079 } else if atString(i, currentDelimiters.setDelimitersStart) { 0080 state = .SetDelimitersTag(startIndex: i, startLineNumber: lineNumber) 0081 i = i.advancedBy(currentDelimiters.setDelimitersStartLength).predecessor() 0082 } else if atString(i, currentDelimiters.tagDelimiterPair.0) { 0083 state = .Tag(startIndex: i, startLineNumber: lineNumber) 0084 i = i.advancedBy(currentDelimiters.tagStartLength).predecessor() 0085 } else { 0086 state = .Text(startIndex: i, startLineNumber: lineNumber) 0087 } 0088 case .Text(let startIndex, let startLineNumber): 0089 if c == "\n" { 0090 lineNumber -= 1 0091 } else if atString(i, currentDelimiters.unescapedTagStart) { 0092 if startIndex != i { 0093 let range = startIndex..<i 0094 let token = TemplateToken( 0095 type: .Text(text: templateString[range]), 0096 lineNumber: startLineNumber, 0097 templateID: templateID, 0098 templateString: templateString, 0099 range: startIndex..<i) 0100 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0101 return 0102 } 0103 } 0104 state = .UnescapedTag(startIndex: i, startLineNumber: lineNumber) 0105 i = i.advancedBy(currentDelimiters.unescapedTagStartLength).predecessor() 0106 } else if atString(i, currentDelimiters.setDelimitersStart) { 0107 if startIndex != i { 0108 let range = startIndex..<i 0109 let token = TemplateToken( 0110 type: .Text(text: templateString[range]), 0111 lineNumber: startLineNumber, 0112 templateID: templateID, 0113 templateString: templateString, 0114 range: startIndex..<i) 0115 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0116 return 0117 } 0118 } 0119 state = .SetDelimitersTag(startIndex: i, startLineNumber: lineNumber) 0120 i = i.advancedBy(currentDelimiters.setDelimitersStartLength).predecessor() 0121 } else if atString(i, currentDelimiters.tagDelimiterPair.0) { 0122 if startIndex != i { 0123 let range = startIndex..<i 0124 let token = TemplateToken( 0125 type: .Text(text: templateString[range]), 0126 lineNumber: startLineNumber, 0127 templateID: templateID, 0128 templateString: templateString, 0129 range: startIndex..<i) 0130 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0131 return 0132 } 0133 } 0134 state = .Tag(startIndex: i, startLineNumber: lineNumber) 0135 i = i.advancedBy(currentDelimiters.tagStartLength).predecessor() 0136 } 0137 case .Tag(let startIndex, let startLineNumber): 0138 if c == "\n" { 0139 lineNumber -= 1 0140 } else if atString(i, currentDelimiters.tagDelimiterPair.1) { 0141 let tagInitialIndex = startIndex.advancedBy(currentDelimiters.tagStartLength) 0142 let tagInitial = templateString[tagInitialIndex] 0143 let tokenRange = startIndex..<i.advancedBy(currentDelimiters.tagEndLength) 0144 switch tagInitial { 0145 case "!": 0146 let token = TemplateToken( 0147 type: .Comment, 0148 lineNumber: startLineNumber, 0149 templateID: templateID, 0150 templateString: templateString, 0151 range: tokenRange) 0152 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0153 return 0154 } 0155 case "#": 0156 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0157 let token = TemplateToken( 0158 type: .Section(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair), 0159 lineNumber: startLineNumber, 0160 templateID: templateID, 0161 templateString: templateString, 0162 range: tokenRange) 0163 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0164 return 0165 } 0166 case "^": 0167 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0168 let token = TemplateToken( 0169 type: .InvertedSection(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair), 0170 lineNumber: startLineNumber, 0171 templateID: templateID, 0172 templateString: templateString, 0173 range: tokenRange) 0174 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0175 return 0176 } 0177 case "$": 0178 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0179 let token = TemplateToken( 0180 type: .Block(content: content), 0181 lineNumber: startLineNumber, 0182 templateID: templateID, 0183 templateString: templateString, 0184 range: tokenRange) 0185 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0186 return 0187 } 0188 case "/": 0189 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0190 let token = TemplateToken( 0191 type: .Close(content: content), 0192 lineNumber: startLineNumber, 0193 templateID: templateID, 0194 templateString: templateString, 0195 range: tokenRange) 0196 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0197 return 0198 } 0199 case ">": 0200 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0201 let token = TemplateToken( 0202 type: .Partial(content: content), 0203 lineNumber: startLineNumber, 0204 templateID: templateID, 0205 templateString: templateString, 0206 range: tokenRange) 0207 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0208 return 0209 } 0210 case "<": 0211 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0212 let token = TemplateToken( 0213 type: .PartialOverride(content: content), 0214 lineNumber: startLineNumber, 0215 templateID: templateID, 0216 templateString: templateString, 0217 range: tokenRange) 0218 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0219 return 0220 } 0221 case "&": 0222 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0223 let token = TemplateToken( 0224 type: .UnescapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair), 0225 lineNumber: startLineNumber, 0226 templateID: templateID, 0227 templateString: templateString, 0228 range: tokenRange) 0229 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0230 return 0231 } 0232 case "%": 0233 let content = templateString.substringWithRange(tagInitialIndex.successor()..<i) 0234 let token = TemplateToken( 0235 type: .Pragma(content: content), 0236 lineNumber: startLineNumber, 0237 templateID: templateID, 0238 templateString: templateString, 0239 range: tokenRange) 0240 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0241 return 0242 } 0243 default: 0244 let content = templateString.substringWithRange(tagInitialIndex..<i) 0245 let token = TemplateToken( 0246 type: .EscapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair), 0247 lineNumber: startLineNumber, 0248 templateID: templateID, 0249 templateString: templateString, 0250 range: tokenRange) 0251 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0252 return 0253 } 0254 } 0255 state = .Start 0256 i = i.advancedBy(currentDelimiters.tagEndLength).predecessor() 0257 } 0258 break 0259 case .UnescapedTag(let startIndex, let startLineNumber): 0260 if c == "\n" { 0261 lineNumber -= 1 0262 } else if atString(i, currentDelimiters.unescapedTagEnd) { 0263 let tagInitialIndex = startIndex.advancedBy(currentDelimiters.unescapedTagStartLength) 0264 let content = templateString.substringWithRange(tagInitialIndex..<i) 0265 let token = TemplateToken( 0266 type: .UnescapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair), 0267 lineNumber: startLineNumber, 0268 templateID: templateID, 0269 templateString: templateString, 0270 range: startIndex..<i.advancedBy(currentDelimiters.unescapedTagEndLength)) 0271 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0272 return 0273 } 0274 state = .Start 0275 i = i.advancedBy(currentDelimiters.unescapedTagEndLength).predecessor() 0276 } 0277 case .SetDelimitersTag(let startIndex, let startLineNumber): 0278 if c == "\n" { 0279 lineNumber -= 1 0280 } else if atString(i, currentDelimiters.setDelimitersEnd) { 0281 let tagInitialIndex = startIndex.advancedBy(currentDelimiters.setDelimitersStartLength) 0282 let content = templateString.substringWithRange(tagInitialIndex..<i) 0283 let newDelimiters = content.componentsSeparatedByCharactersInSet(CharacterSet.whitespaceAndNewline).filter { $0.characters.count > 0 } 0284 if (newDelimiters.count != 2) { 0285 let error = MustacheError(kind: .ParseError, message: "Invalid set delimiters tag", templateID: templateID, lineNumber: startLineNumber) 0286 tokenConsumer.parser(self, didFailWithError: error) 0287 return; 0288 } 0289 0290 let token = TemplateToken( 0291 type: .SetDelimiters, 0292 lineNumber: startLineNumber, 0293 templateID: templateID, 0294 templateString: templateString, 0295 range: startIndex..<i.advancedBy(currentDelimiters.setDelimitersEndLength)) 0296 if !tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) { 0297 return 0298 } 0299 0300 state = .Start 0301 i = i.advancedBy(currentDelimiters.setDelimitersEndLength).predecessor() 0302 0303 currentDelimiters = ParserTagDelimiters(tagDelimiterPair: (newDelimiters[0], newDelimiters[1])) 0304 } 0305 } 0306 0307 i = i.successor() 0308 } 0309 0310 0311 // EOF 0312 0313 switch state { 0314 case .Start: 0315 break 0316 case .Text(let startIndex, let startLineNumber): 0317 let range = startIndex..<end 0318 let token = TemplateToken( 0319 type: .Text(text: templateString[range]), 0320 lineNumber: startLineNumber, 0321 templateID: templateID, 0322 templateString: templateString, 0323 range: range) 0324 tokenConsumer.parser(self, shouldContinueAfterParsingToken: token) 0325 case .Tag(_, let startLineNumber): 0326 let error = MustacheError(kind: .ParseError, message: "Unclosed Mustache tag", templateID: templateID, lineNumber: startLineNumber) 0327 tokenConsumer.parser(self, didFailWithError: error) 0328 case .UnescapedTag(_, let startLineNumber): 0329 let error = MustacheError(kind: .ParseError, message: "Unclosed Mustache tag", templateID: templateID, lineNumber: startLineNumber) 0330 tokenConsumer.parser(self, didFailWithError: error) 0331 case .SetDelimitersTag(_, let startLineNumber): 0332 let error = MustacheError(kind: .ParseError, message: "Unclosed Mustache tag", templateID: templateID, lineNumber: startLineNumber) 0333 tokenConsumer.parser(self, didFailWithError: error) 0334 } 0335 } 0336 0337 0338 // MARK: - Private 0339 0340 private enum State
TemplateParser.swift:63
        var state: State = .Start
{ 0341 case Start
TemplateParser.swift:63
        var state: State = .Start
TemplateParser.swift:72
            case .Start:
TemplateParser.swift:255
                    state = .Start
TemplateParser.swift:274
                    state = .Start
TemplateParser.swift:300
                    state = .Start
TemplateParser.swift:314
        case .Start:
0342 case Text
TemplateParser.swift:74
                    state = .Text(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:86
                    state = .Text(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:88
            case .Text(let startIndex, let startLineNumber):
TemplateParser.swift:316
        case .Text(let startIndex, let startLineNumber):
(startIndex: String.Index, startLineNumber: Int) 0343 case Tag
TemplateParser.swift:83
                    state = .Tag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:134
                    state = .Tag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:137
            case .Tag(let startIndex, let startLineNumber):
TemplateParser.swift:325
        case .Tag(_, let startLineNumber):
(startIndex: String.Index, startLineNumber: Int) 0344 case UnescapedTag
TemplateParser.swift:77
                    state = .UnescapedTag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:104
                    state = .UnescapedTag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:259
            case .UnescapedTag(let startIndex, let startLineNumber):
TemplateParser.swift:328
        case .UnescapedTag(_, let startLineNumber):
(startIndex: String.Index, startLineNumber: Int) 0345 case SetDelimitersTag
TemplateParser.swift:80
                    state = .SetDelimitersTag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:119
                    state = .SetDelimitersTag(startIndex: i, startLineNumber: lineNumber)
TemplateParser.swift:277
            case .SetDelimitersTag(let startIndex, let startLineNumber):
TemplateParser.swift:331
        case .SetDelimitersTag(_, let startLineNumber):
(startIndex: String.Index, startLineNumber: Int) 0346 } 0347 0348 private struct ParserTagDelimiters
TemplateParser.swift:53
        var currentDelimiters = ParserTagDelimiters(tagDelimiterPair: tagDelimiterPair)
TemplateParser.swift:303
                    currentDelimiters = ParserTagDelimiters(tagDelimiterPair: (newDelimiters[0], newDelimiters[1]))
{ 0349 let tagDelimiterPair
TemplateParser.swift:82
                } else if atString(i, currentDelimiters.tagDelimiterPair.0) {
TemplateParser.swift:121
                } else if atString(i, currentDelimiters.tagDelimiterPair.0) {
TemplateParser.swift:140
                } else if atString(i, currentDelimiters.tagDelimiterPair.1) {
TemplateParser.swift:158
                            type: .Section(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair),
TemplateParser.swift:169
                            type: .InvertedSection(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair),
TemplateParser.swift:224
                            type: .UnescapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair),
TemplateParser.swift:246
                            type: .EscapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair),
TemplateParser.swift:266
                        type: .UnescapedVariable(content: content, tagDelimiterPair: currentDelimiters.tagDelimiterPair),
TemplateParser.swift:362
            self.tagDelimiterPair = tagDelimiterPair
: TagDelimiterPair 0350 let tagStartLength
TemplateParser.swift:84
                    i = i.advancedBy(currentDelimiters.tagStartLength).predecessor()
TemplateParser.swift:135
                    i = i.advancedBy(currentDelimiters.tagStartLength).predecessor()
TemplateParser.swift:141
                    let tagInitialIndex = startIndex.advancedBy(currentDelimiters.tagStartLength)
TemplateParser.swift:364
            tagStartLength = tagDelimiterPair.0.startIndex.distanceTo(tagDelimiterPair.0.endIndex)
: Int 0351 let tagEndLength
TemplateParser.swift:143
                    let tokenRange = startIndex..<i.advancedBy(currentDelimiters.tagEndLength)
TemplateParser.swift:256
                    i = i.advancedBy(currentDelimiters.tagEndLength).predecessor()
TemplateParser.swift:365
            tagEndLength = tagDelimiterPair.1.startIndex.distanceTo(tagDelimiterPair.1.endIndex)
: Int 0352 let unescapedTagStart
TemplateParser.swift:76
                } else if atString(i, currentDelimiters.unescapedTagStart) {
TemplateParser.swift:91
                } else if atString(i, currentDelimiters.unescapedTagStart) {
TemplateParser.swift:368
            unescapedTagStart = usesStandardDelimiters ? "{{{" : nil
TemplateParser.swift:369
            unescapedTagStartLength = unescapedTagStart != nil ? unescapedTagStart!.startIndex.distanceTo(unescapedTagStart!.endIndex) : 0
TemplateParser.swift:369
            unescapedTagStartLength = unescapedTagStart != nil ? unescapedTagStart!.startIndex.distanceTo(unescapedTagStart!.endIndex) : 0
TemplateParser.swift:369
            unescapedTagStartLength = unescapedTagStart != nil ? unescapedTagStart!.startIndex.distanceTo(unescapedTagStart!.endIndex) : 0
: String? 0353 let unescapedTagStartLength
TemplateParser.swift:78
                    i = i.advancedBy(currentDelimiters.unescapedTagStartLength).predecessor()
TemplateParser.swift:105
                    i = i.advancedBy(currentDelimiters.unescapedTagStartLength).predecessor()
TemplateParser.swift:263
                    let tagInitialIndex = startIndex.advancedBy(currentDelimiters.unescapedTagStartLength)
TemplateParser.swift:369
            unescapedTagStartLength = unescapedTagStart != nil ? unescapedTagStart!.startIndex.distanceTo(unescapedTagStart!.endIndex) : 0
: Int 0354 let unescapedTagEnd
TemplateParser.swift:262
                } else if atString(i, currentDelimiters.unescapedTagEnd) {
TemplateParser.swift:370
            unescapedTagEnd = usesStandardDelimiters ? "}}}" : nil
TemplateParser.swift:371
            unescapedTagEndLength = unescapedTagEnd != nil ? unescapedTagEnd!.startIndex.distanceTo(unescapedTagEnd!.endIndex) : 0
TemplateParser.swift:371
            unescapedTagEndLength = unescapedTagEnd != nil ? unescapedTagEnd!.startIndex.distanceTo(unescapedTagEnd!.endIndex) : 0
TemplateParser.swift:371
            unescapedTagEndLength = unescapedTagEnd != nil ? unescapedTagEnd!.startIndex.distanceTo(unescapedTagEnd!.endIndex) : 0
: String? 0355 let unescapedTagEndLength
TemplateParser.swift:270
                        range: startIndex..<i.advancedBy(currentDelimiters.unescapedTagEndLength))
TemplateParser.swift:275
                    i = i.advancedBy(currentDelimiters.unescapedTagEndLength).predecessor()
TemplateParser.swift:371
            unescapedTagEndLength = unescapedTagEnd != nil ? unescapedTagEnd!.startIndex.distanceTo(unescapedTagEnd!.endIndex) : 0
: Int 0356 let setDelimitersStart
TemplateParser.swift:79
                } else if atString(i, currentDelimiters.setDelimitersStart) {
TemplateParser.swift:106
                } else if atString(i, currentDelimiters.setDelimitersStart) {
TemplateParser.swift:373
            setDelimitersStart = "\(tagDelimiterPair.0)="
TemplateParser.swift:374
            setDelimitersStartLength = setDelimitersStart.startIndex.distanceTo(setDelimitersStart.endIndex)
TemplateParser.swift:374
            setDelimitersStartLength = setDelimitersStart.startIndex.distanceTo(setDelimitersStart.endIndex)
: String 0357 let setDelimitersStartLength
TemplateParser.swift:81
                    i = i.advancedBy(currentDelimiters.setDelimitersStartLength).predecessor()
TemplateParser.swift:120
                    i = i.advancedBy(currentDelimiters.setDelimitersStartLength).predecessor()
TemplateParser.swift:281
                    let tagInitialIndex = startIndex.advancedBy(currentDelimiters.setDelimitersStartLength)
TemplateParser.swift:374
            setDelimitersStartLength = setDelimitersStart.startIndex.distanceTo(setDelimitersStart.endIndex)
: Int 0358 let setDelimitersEnd
TemplateParser.swift:280
                } else if atString(i, currentDelimiters.setDelimitersEnd) {
TemplateParser.swift:375
            setDelimitersEnd = "=\(tagDelimiterPair.1)"
TemplateParser.swift:376
            setDelimitersEndLength = setDelimitersEnd.startIndex.distanceTo(setDelimitersEnd.endIndex)
TemplateParser.swift:376
            setDelimitersEndLength = setDelimitersEnd.startIndex.distanceTo(setDelimitersEnd.endIndex)
: String 0359 let setDelimitersEndLength
TemplateParser.swift:295
                        range: startIndex..<i.advancedBy(currentDelimiters.setDelimitersEndLength))
TemplateParser.swift:301
                    i = i.advancedBy(currentDelimiters.setDelimitersEndLength).predecessor()
TemplateParser.swift:376
            setDelimitersEndLength = setDelimitersEnd.startIndex.distanceTo(setDelimitersEnd.endIndex)
: Int 0360 0361 init
TemplateParser.swift:53
        var currentDelimiters = ParserTagDelimiters(tagDelimiterPair: tagDelimiterPair)
TemplateParser.swift:303
                    currentDelimiters = ParserTagDelimiters(tagDelimiterPair: (newDelimiters[0], newDelimiters[1]))
(tagDelimiterPair : TagDelimiterPair) { 0362 self.tagDelimiterPair = tagDelimiterPair 0363 0364 tagStartLength = tagDelimiterPair.0.startIndex.distanceTo(tagDelimiterPair.0.endIndex) 0365 tagEndLength = tagDelimiterPair.1.startIndex.distanceTo(tagDelimiterPair.1.endIndex) 0366 0367 let usesStandardDelimiters = (tagDelimiterPair.0 == "{{") && (tagDelimiterPair.1 == "}}") 0368 unescapedTagStart = usesStandardDelimiters ? "{{{" : nil 0369 unescapedTagStartLength = unescapedTagStart != nil ? unescapedTagStart!.startIndex.distanceTo(unescapedTagStart!.endIndex) : 0 0370 unescapedTagEnd = usesStandardDelimiters ? "}}}" : nil 0371 unescapedTagEndLength = unescapedTagEnd != nil ? unescapedTagEnd!.startIndex.distanceTo(unescapedTagEnd!.endIndex) : 0 0372 0373 setDelimitersStart = "\(tagDelimiterPair.0)=" 0374 setDelimitersStartLength = setDelimitersStart.startIndex.distanceTo(setDelimitersStart.endIndex) 0375 setDelimitersEnd = "=\(tagDelimiterPair.1)" 0376 setDelimitersEndLength = setDelimitersEnd.startIndex.distanceTo(setDelimitersEnd.endIndex) 0377 } 0378 } 0379 } 0380 0381 extension String { 0382 func componentsSeparatedByCharactersInSet
TemplateParser.swift:283
                    let newDelimiters = content.componentsSeparatedByCharactersInSet(CharacterSet.whitespaceAndNewline).filter { $0.characters.count > 0 }
(characterSet: Set<Character>) -> [String] { 0383 return characters.split { characterSet.contains($0) }.map { String($0) } 0384 } 0385 } 0386 0387 struct CharacterSet
TemplateCompiler.swift:78
                    let pragma = content.stringByTrimmingCharactersInSet(CharacterSet.whitespaceAndNewline)
TemplateCompiler.swift:393
        let whiteSpace = CharacterSet.whitespaceAndNewline
TemplateCompiler.swift:406
        let whiteSpace = CharacterSet.whitespaceAndNewline
TemplateParser.swift:283
                    let newDelimiters = content.componentsSeparatedByCharactersInSet(CharacterSet.whitespaceAndNewline).filter { $0.characters.count > 0 }
{ 0388 static var whitespaceAndNewline
TemplateCompiler.swift:78
                    let pragma = content.stringByTrimmingCharactersInSet(CharacterSet.whitespaceAndNewline)
TemplateCompiler.swift:393
        let whiteSpace = CharacterSet.whitespaceAndNewline
TemplateCompiler.swift:406
        let whiteSpace = CharacterSet.whitespaceAndNewline
TemplateParser.swift:283
                    let newDelimiters = content.componentsSeparatedByCharactersInSet(CharacterSet.whitespaceAndNewline).filter { $0.characters.count > 0 }
: Set<Character> { 0389 return [" ", "\n"] 0390 } 0391 }