From 69cd8e4d3bf4682cb9a022adbb7b3322a1dea657 Mon Sep 17 00:00:00 2001 From: Ilya Puchka Date: Sat, 7 Oct 2017 20:54:42 +0200 Subject: [PATCH] replaced Token with Lexeme protocol on TemplateSyntaxError --- Sources/Errors.swift | 26 ++++++++++++++++++++++++++ Sources/Lexer.swift | 37 +++++++++++++++++++++---------------- Sources/Node.swift | 27 --------------------------- Sources/Parser.swift | 4 ++-- Sources/Template.swift | 13 ++----------- Sources/Tokenizer.swift | 14 +------------- 6 files changed, 52 insertions(+), 69 deletions(-) diff --git a/Sources/Errors.swift b/Sources/Errors.swift index 964eeae..1030d6d 100644 --- a/Sources/Errors.swift +++ b/Sources/Errors.swift @@ -17,3 +17,29 @@ public class TemplateDoesNotExist: Error, CustomStringConvertible { return "Template named `\(templates)` does not exist. No loaders found" } } + +public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible { + public let description:String + var lexeme: Lexeme? + + public init(_ description:String) { + self.description = description + } + + public static func ==(lhs:TemplateSyntaxError, rhs:TemplateSyntaxError) -> Bool { + return lhs.description == rhs.description + } + +} + +extension Range where Bound == String.Index { + internal static var unknown: Range { + return "".range + } +} + +extension String { + var range: Range { + return startIndex.. (content: String, number: Int, offset: String.IndexDistance) { + var lineNumber: Int = 0 + var offset = 0 + var lineContent = "" + + templateString.enumerateLines { (line, stop) in + lineNumber += 1 + lineContent = line + if let rangeOfLine = self.templateString.range(of: line), rangeOfLine.contains(lexeme.range.lowerBound) { + offset = self.templateString.distance(from: rangeOfLine.lowerBound, to: + lexeme.range.lowerBound) + stop = true + } + } + return (lineContent, lineNumber, offset) + } + } +protocol Lexeme { + var range: Range { get } +} class Scanner { let _content: String //stores original content @@ -163,20 +184,4 @@ extension String { return String(self[first..) -> (content: String, number: Int, offset: String.IndexDistance) { - var lineNumber: Int = 0 - var offset = 0 - var lineContent = "" - - enumerateLines { (line, stop) in - lineNumber += 1 - lineContent = line - if let rangeOfLine = self.range(of: line), rangeOfLine.contains(range.lowerBound) { - offset = self.distance(from: rangeOfLine.lowerBound, to: range.lowerBound) - stop = true - } - } - return (lineContent, lineNumber, offset) - } - } diff --git a/Sources/Node.swift b/Sources/Node.swift index 1c2eed4..1d2020d 100644 --- a/Sources/Node.swift +++ b/Sources/Node.swift @@ -1,32 +1,5 @@ import Foundation - -public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible { - public let description:String - public var token: Token? - - public init(_ description:String) { - self.description = description - } - - public func contextAwareError(templateName: String?, templateContent: String) -> TemplateSyntaxError? { - guard let token = token, token.range != .unknown else { return nil } - let templateName = templateName.map({ "\($0):" }) ?? "" - let (line, lineNumber, offset) = templateContent.lineAndPosition(at: token.range) - let tokenContent = templateContent.substring(with: token.range) - let highlight = "\(String(Array(repeating: " ", count: offset)))^\(String(Array(repeating: "~", count: max(tokenContent.count - 1, 0))))" - let description = "\(templateName)\(lineNumber):\(offset): error: " + self.description + "\n\(line)\n\(highlight)\n" - return TemplateSyntaxError(description) - } - -} - - -public func ==(lhs:TemplateSyntaxError, rhs:TemplateSyntaxError) -> Bool { - return lhs.description == rhs.description -} - - public protocol NodeType { /// Render the node in the given context func render(_ context:Context) throws -> String diff --git a/Sources/Parser.swift b/Sources/Parser.swift index 5c840bf..24fcdab 100644 --- a/Sources/Parser.swift +++ b/Sources/Parser.swift @@ -53,8 +53,8 @@ public class TokenParser { let node = try parser(self, token) nodes.append(node) } catch { - if var syntaxError = error as? TemplateSyntaxError, syntaxError.token == nil { - syntaxError.token = token + if var syntaxError = error as? TemplateSyntaxError, syntaxError.lexeme == nil { + syntaxError.lexeme = token throw syntaxError } else { throw error diff --git a/Sources/Template.swift b/Sources/Template.swift index 7a80ee8..db570e0 100644 --- a/Sources/Template.swift +++ b/Sources/Template.swift @@ -68,17 +68,8 @@ open class Template: ExpressibleByStringLiteral { func render(_ context: Context) throws -> String { let context = context let parser = TokenParser(tokens: tokens, environment: context.environment) - do { - let nodes = try parser.parse() - return try renderNodes(nodes, context) - } catch { - if let syntaxError = error as? TemplateSyntaxError, - let error = syntaxError.contextAwareError(templateName: name, templateContent: templateString) { - throw error - } else { - throw error - } - } + let nodes = try parser.parse() + return try renderNodes(nodes, context) } /// Render the given template diff --git a/Sources/Tokenizer.swift b/Sources/Tokenizer.swift index cae09cc..60f621b 100644 --- a/Sources/Tokenizer.swift +++ b/Sources/Tokenizer.swift @@ -40,19 +40,7 @@ extension String { } } -extension Range where Bound == String.Index { - internal static var unknown: Range { - return "".range - } -} - -extension String { - var range: Range { - return startIndex..)