handling unknown filter errors
This commit is contained in:
@@ -51,4 +51,9 @@ public struct Environment {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
var template: Template? {
|
||||
return errorReporter.context?.template
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class FilterNode : NodeType {
|
||||
throw TemplateSyntaxError("`endfilter` was not found.")
|
||||
}
|
||||
|
||||
let resolvable = try parser.compileFilter("filter_value|\(bits[1])")
|
||||
let resolvable = try parser.compileFilter("filter_value|\(bits[1])", containedIn: token)
|
||||
return FilterNode(nodes: blocks, resolvable: resolvable)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,24 +21,24 @@ class ForNode : NodeType {
|
||||
.map { $0.trimmingCharacters(in: CharacterSet.whitespaces) }
|
||||
|
||||
let variable = components[3]
|
||||
let filter = try parser.compileFilter(variable, containedIn: token)
|
||||
|
||||
var emptyNodes = [NodeType]()
|
||||
|
||||
let forNodes = try parser.parse(until(["endfor", "empty"]))
|
||||
|
||||
guard let token = parser.nextToken() else {
|
||||
if let token = parser.nextToken() {
|
||||
if token.contents == "empty" {
|
||||
emptyNodes = try parser.parse(until(["endfor"]))
|
||||
_ = parser.nextToken()
|
||||
}
|
||||
} else {
|
||||
throw TemplateSyntaxError("`endfor` was not found.")
|
||||
}
|
||||
|
||||
if token.contents == "empty" {
|
||||
emptyNodes = try parser.parse(until(["endfor"]))
|
||||
_ = parser.nextToken()
|
||||
}
|
||||
|
||||
let filter = try parser.compileFilter(variable)
|
||||
let `where`: Expression?
|
||||
if components.count >= 6 {
|
||||
`where` = try parseExpression(components: Array(components.suffix(from: 5)), tokenParser: parser)
|
||||
`where` = try parseExpression(components: Array(components.suffix(from: 5)), tokenParser: parser, token: token)
|
||||
} else {
|
||||
`where` = nil
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ final class IfExpressionParser {
|
||||
let tokens: [IfToken]
|
||||
var position: Int = 0
|
||||
|
||||
init(components: [String], tokenParser: TokenParser) throws {
|
||||
init(components: [String], tokenParser: TokenParser, token: Token) throws {
|
||||
self.tokens = try components.map { component in
|
||||
if let op = findOperator(name: component) {
|
||||
switch op {
|
||||
@@ -111,7 +111,7 @@ final class IfExpressionParser {
|
||||
}
|
||||
}
|
||||
|
||||
return .variable(try tokenParser.compileFilter(component))
|
||||
return .variable(try tokenParser.compileFilter(component, containedIn: token))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,8 +155,8 @@ final class IfExpressionParser {
|
||||
}
|
||||
|
||||
|
||||
func parseExpression(components: [String], tokenParser: TokenParser) throws -> Expression {
|
||||
let parser = try IfExpressionParser(components: components, tokenParser: tokenParser)
|
||||
func parseExpression(components: [String], tokenParser: TokenParser, token: Token) throws -> Expression {
|
||||
let parser = try IfExpressionParser(components: components, tokenParser: tokenParser, token: token)
|
||||
return try parser.parse()
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ class IfNode : NodeType {
|
||||
var components = token.components()
|
||||
components.removeFirst()
|
||||
|
||||
let expression = try parseExpression(components: components, tokenParser: parser)
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: token)
|
||||
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||
var conditions: [IfCondition] = [
|
||||
IfCondition(expression: expression, nodes: nodes)
|
||||
@@ -197,7 +197,7 @@ class IfNode : NodeType {
|
||||
while let current = token, current.contents.hasPrefix("elif") {
|
||||
var components = current.components()
|
||||
components.removeFirst()
|
||||
let expression = try parseExpression(components: components, tokenParser: parser)
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: current)
|
||||
|
||||
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||
token = parser.nextToken()
|
||||
@@ -227,16 +227,16 @@ class IfNode : NodeType {
|
||||
|
||||
falseNodes = try parser.parse(until(["endif", "else"]))
|
||||
|
||||
guard let token = parser.nextToken() else {
|
||||
if let token = parser.nextToken() {
|
||||
if token.contents == "else" {
|
||||
trueNodes = try parser.parse(until(["endif"]))
|
||||
_ = parser.nextToken()
|
||||
}
|
||||
} else {
|
||||
throw TemplateSyntaxError("`endif` was not found.")
|
||||
}
|
||||
|
||||
if token.contents == "else" {
|
||||
trueNodes = try parser.parse(until(["endif"]))
|
||||
_ = parser.nextToken()
|
||||
}
|
||||
|
||||
let expression = try parseExpression(components: components, tokenParser: parser)
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: token)
|
||||
return IfNode(conditions: [
|
||||
IfCondition(expression: expression, nodes: trueNodes),
|
||||
IfCondition(expression: nil, nodes: falseNodes),
|
||||
|
||||
@@ -40,7 +40,7 @@ public class TokenParser {
|
||||
case .text(let text, _):
|
||||
nodes.append(TextNode(text: text))
|
||||
case .variable:
|
||||
nodes.append(VariableNode(variable: try compileFilter(token.contents)))
|
||||
nodes.append(VariableNode(variable: try compileFilter(token.contents, containedIn: token)))
|
||||
case .block:
|
||||
if let parse_until = parse_until , parse_until(self, token) {
|
||||
prependToken(token)
|
||||
@@ -100,7 +100,23 @@ public class TokenParser {
|
||||
|
||||
throw TemplateSyntaxError("Unknown filter '\(name)'")
|
||||
}
|
||||
|
||||
|
||||
public func compileFilter(_ filterToken: String, containedIn containingToken: Token) throws -> Resolvable {
|
||||
do {
|
||||
return try FilterExpression(token: filterToken, parser: self)
|
||||
} catch {
|
||||
if var syntaxError = error as? TemplateSyntaxError, syntaxError.lexeme == nil,
|
||||
let filterTokenRange = environment.template?.templateString.range(of: filterToken, range: containingToken.range) {
|
||||
|
||||
syntaxError.lexeme = Token.block(value: filterToken, at: filterTokenRange)
|
||||
throw syntaxError
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use compileFilter(_:containedIn:)")
|
||||
public func compileFilter(_ token: String) throws -> Resolvable {
|
||||
return try FilterExpression(token: token, parser: self)
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ class FilterExpression : Resolvable {
|
||||
init(token: String, parser: TokenParser) throws {
|
||||
let bits = token.characters.split(separator: "|").map({ String($0).trim(character: " ") })
|
||||
if bits.isEmpty {
|
||||
filters = []
|
||||
variable = Variable("")
|
||||
throw TemplateSyntaxError("Variable tags must include at least 1 argument")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user