solve merge conflict issues
This commit is contained in:
@@ -38,6 +38,7 @@ open class Extension {
|
||||
filters[name] = .arguments({ value, args, _ in try filter(value, args) })
|
||||
}
|
||||
|
||||
/// Registers a template filter with the given name
|
||||
public func registerFilter(_ name: String, filter: @escaping (Any?, [Any?], Context) throws -> Any?) {
|
||||
filters[name] = .arguments(filter)
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class ForNode : NodeType {
|
||||
let resolvable = try parser.compileResolvable(components[3], containedIn: token)
|
||||
|
||||
let `where` = hasToken("where", at: 4)
|
||||
? try parseExpression(components: Array(components.suffix(from: 5)), tokenParser: parser, token: token)
|
||||
? try parser.compileExpression(components: Array(components.suffix(from: 5)), token: token)
|
||||
: nil
|
||||
|
||||
let forNodes = try parser.parse(until(["endfor", "empty"]))
|
||||
|
||||
@@ -111,11 +111,11 @@ final class IfExpressionParser {
|
||||
self.tokens = tokens
|
||||
}
|
||||
|
||||
static func parser(components: [String], tokenParser: TokenParser, token: Token) throws -> IfExpressionParser {
|
||||
return try IfExpressionParser(components: ArraySlice(components), tokenParser: tokenParser, token: token)
|
||||
static func parser(components: [String], environment: Environment, token: Token) throws -> IfExpressionParser {
|
||||
return try IfExpressionParser(components: ArraySlice(components), environment: environment, token: token)
|
||||
}
|
||||
|
||||
private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws {
|
||||
private init(components: ArraySlice<String>, environment: Environment, token: Token) throws {
|
||||
var parsedComponents = Set<Int>()
|
||||
var bracketsBalance = 0
|
||||
self.tokens = try zip(components.indices, components).compactMap { (index, component) in
|
||||
@@ -125,7 +125,7 @@ final class IfExpressionParser {
|
||||
bracketsBalance += 1
|
||||
let (expression, parsedCount) = try IfExpressionParser.subExpression(
|
||||
from: components.suffix(from: index + 1),
|
||||
tokenParser: tokenParser,
|
||||
environment: environment,
|
||||
token: token
|
||||
)
|
||||
parsedComponents.formUnion(Set(index...(index + parsedCount)))
|
||||
@@ -147,12 +147,12 @@ final class IfExpressionParser {
|
||||
return .prefix(name: name, bindingPower: bindingPower, operatorType: operatorType)
|
||||
}
|
||||
}
|
||||
return .variable(try tokenParser.compileResolvable(component, containedIn: token))
|
||||
return .variable(try environment.compileResolvable(component, containedIn: token))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func subExpression(from components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws -> (Expression, Int) {
|
||||
private static func subExpression(from components: ArraySlice<String>, environment: Environment, token: Token) throws -> (Expression, Int) {
|
||||
var bracketsBalance = 1
|
||||
let subComponents = components
|
||||
.prefix(while: {
|
||||
@@ -167,7 +167,7 @@ final class IfExpressionParser {
|
||||
throw TemplateSyntaxError("'if' expression error: missing closing bracket")
|
||||
}
|
||||
|
||||
let expressionParser = try IfExpressionParser(components: subComponents, tokenParser: tokenParser, token: token)
|
||||
let expressionParser = try IfExpressionParser(components: subComponents, environment: environment, token: token)
|
||||
let expression = try expressionParser.parse()
|
||||
return (expression, subComponents.count)
|
||||
}
|
||||
@@ -239,7 +239,7 @@ class IfNode : NodeType {
|
||||
var components = token.components()
|
||||
components.removeFirst()
|
||||
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: token)
|
||||
let expression = try parser.compileExpression(components: components, token: token)
|
||||
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||
var conditions: [IfCondition] = [
|
||||
IfCondition(expression: expression, nodes: nodes)
|
||||
@@ -249,7 +249,7 @@ class IfNode : NodeType {
|
||||
while let current = nextToken, current.contents.hasPrefix("elif") {
|
||||
var components = current.components()
|
||||
components.removeFirst()
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: current)
|
||||
let expression = try parser.compileExpression(components: components, token: current)
|
||||
|
||||
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||
nextToken = parser.nextToken()
|
||||
@@ -277,7 +277,7 @@ class IfNode : NodeType {
|
||||
var trueNodes = [NodeType]()
|
||||
var falseNodes = [NodeType]()
|
||||
|
||||
let expression = try parseExpression(components: components, tokenParser: parser, token: token)
|
||||
let expression = try parser.compileExpression(components: components, token: token)
|
||||
falseNodes = try parser.parse(until(["endif", "else"]))
|
||||
|
||||
guard let token = parser.nextToken() else {
|
||||
|
||||
@@ -74,11 +74,11 @@ public class VariableNode : NodeType {
|
||||
if hasToken("if", at: 1) {
|
||||
let components = components.suffix(from: 2)
|
||||
if let elseIndex = components.index(of: "else") {
|
||||
condition = try parseExpression(components: Array(components.prefix(upTo: elseIndex)), tokenParser: parser, token: token)
|
||||
condition = try parser.compileExpression(components: Array(components.prefix(upTo: elseIndex)), token: token)
|
||||
let elseToken = components.suffix(from: elseIndex.advanced(by: 1)).joined(separator: " ")
|
||||
elseExpression = try parser.compileResolvable(elseToken, containedIn: token)
|
||||
} else {
|
||||
condition = try parseExpression(components: Array(components), tokenParser: parser, token: token)
|
||||
condition = try parser.compileExpression(components: Array(components), token: token)
|
||||
elseExpression = nil
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -49,7 +49,7 @@ public class TokenParser {
|
||||
|
||||
if let tag = token.components().first {
|
||||
do {
|
||||
let parser = try findTag(name: tag)
|
||||
let parser = try environment.findTag(name: tag)
|
||||
let node = try parser(self, token)
|
||||
nodes.append(node)
|
||||
} catch {
|
||||
@@ -76,16 +76,16 @@ public class TokenParser {
|
||||
tokens.insert(token, at: 0)
|
||||
}
|
||||
|
||||
public func compileFilter(_ token: String) throws -> Resolvable {
|
||||
return try environment.compileFilter(token)
|
||||
public func compileFilter(_ filterToken: String, containedIn token: Token) throws -> Resolvable {
|
||||
return try environment.compileFilter(filterToken, containedIn: token)
|
||||
}
|
||||
|
||||
public func compileExpression(components: [String]) throws -> Expression {
|
||||
return try environment.compileExpression(components: components)
|
||||
public func compileExpression(components: [String], token: Token) throws -> Expression {
|
||||
return try environment.compileExpression(components: components, containedIn: token)
|
||||
}
|
||||
|
||||
public func compileResolvable(_ token: String) throws -> Resolvable {
|
||||
return try environment.compileResolvable(token)
|
||||
public func compileResolvable(_ token: String, containedIn containingToken: Token) throws -> Resolvable {
|
||||
return try environment.compileResolvable(token, containedIn: containingToken)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,9 +134,13 @@ extension Environment {
|
||||
return filtersWithDistance.filter({ $0.distance == minDistance }).map({ $0.filterName })
|
||||
}
|
||||
|
||||
public func compileFilter(_ token: String) throws -> Resolvable {
|
||||
return try FilterExpression(token: token, environment: self)
|
||||
}
|
||||
|
||||
public func compileFilter(_ filterToken: String, containedIn containingToken: Token) throws -> Resolvable {
|
||||
do {
|
||||
return try FilterExpression(token: filterToken, parser: self)
|
||||
return try FilterExpression(token: filterToken, environment: self)
|
||||
} catch {
|
||||
guard var syntaxError = error as? TemplateSyntaxError, syntaxError.token == nil else {
|
||||
throw error
|
||||
@@ -153,26 +157,20 @@ extension Environment {
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use compileFilter(_:containedIn:)")
|
||||
public func compileFilter(_ token: String) throws -> Resolvable {
|
||||
return try FilterExpression(token: token, environment: self)
|
||||
}
|
||||
|
||||
public func compileExpression(components: [String]) throws -> Expression {
|
||||
return try IfExpressionParser(components: components, environment: self).parse()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use compileResolvable(_:containedIn:)")
|
||||
public func compileResolvable(_ token: String) throws -> Resolvable {
|
||||
return try RangeVariable(token, environment: self)
|
||||
?? compileFilter(token)
|
||||
}
|
||||
|
||||
public func compileResolvable(_ token: String, containedIn containingToken: Token) throws -> Resolvable {
|
||||
return try RangeVariable(token, parser: self, containedIn: containingToken)
|
||||
return try RangeVariable(token, environment: self, containedIn: containingToken)
|
||||
?? compileFilter(token, containedIn: containingToken)
|
||||
}
|
||||
|
||||
public func compileExpression(components: [String], containedIn token: Token) throws -> Expression {
|
||||
return try IfExpressionParser.parser(components: components, environment: self, token: token).parse()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_two_matrix_rows
|
||||
|
||||
@@ -8,8 +8,8 @@ class FilterExpression : Resolvable {
|
||||
let filters: [(FilterType, [Variable])]
|
||||
let variable: Variable
|
||||
|
||||
init(token: String, parser: TokenParser) throws {
|
||||
let bits = token.split(separator: "|").map({ String($0).trim(character: " ") })
|
||||
init(token: String, environment: Environment) throws {
|
||||
let bits = token.smartSplit(separator: "|").map({ String($0).trim(character: " ") })
|
||||
if bits.isEmpty {
|
||||
throw TemplateSyntaxError("Variable tags must include at least 1 argument")
|
||||
}
|
||||
@@ -144,8 +144,7 @@ public struct RangeVariable: Resolvable {
|
||||
public let from: Resolvable
|
||||
public let to: Resolvable
|
||||
|
||||
@available(*, deprecated, message: "Use init?(_:parser:containedIn:)")
|
||||
public init?(_ token: String, parser: TokenParser) throws {
|
||||
public init?(_ token: String, environment: Environment) throws {
|
||||
let components = token.components(separatedBy: "...")
|
||||
guard components.count == 2 else {
|
||||
return nil
|
||||
@@ -155,14 +154,14 @@ public struct RangeVariable: Resolvable {
|
||||
self.to = try environment.compileFilter(components[1])
|
||||
}
|
||||
|
||||
public init?(_ token: String, parser: TokenParser, containedIn containingToken: Token) throws {
|
||||
public init?(_ token: String, environment: Environment, containedIn containingToken: Token) throws {
|
||||
let components = token.components(separatedBy: "...")
|
||||
guard components.count == 2 else {
|
||||
return nil
|
||||
}
|
||||
|
||||
self.from = try parser.compileFilter(components[0], containedIn: containingToken)
|
||||
self.to = try parser.compileFilter(components[1], containedIn: containingToken)
|
||||
self.from = try environment.compileFilter(components[0], containedIn: containingToken)
|
||||
self.to = try environment.compileFilter(components[1], containedIn: containingToken)
|
||||
}
|
||||
|
||||
public func resolve(_ context: Context) throws -> Any? {
|
||||
|
||||
@@ -5,10 +5,9 @@ import Spectre
|
||||
class ExpressionsTests: XCTestCase {
|
||||
func testExpressions() {
|
||||
describe("Expression") {
|
||||
let parser = TokenParser(tokens: [], environment: Environment())
|
||||
|
||||
func parseExpression(components: [String]) throws -> Expression {
|
||||
let parser = try IfExpressionParser.parser(components: components, tokenParser: parser, token: .text(value: "", at: .unknown))
|
||||
let parser = try IfExpressionParser.parser(components: components, environment: Environment(), token: .text(value: "", at: .unknown))
|
||||
return try parser.parse()
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +386,6 @@ class FilterTests: XCTestCase {
|
||||
"""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("dynamic filter") {
|
||||
|
||||
@@ -410,4 +409,5 @@ class FilterTests: XCTestCase {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,8 @@ class ForNodeTests: XCTestCase {
|
||||
|
||||
$0.it("renders the given nodes while filtering items using where expression") {
|
||||
let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.counter")]
|
||||
let `where` = try parseExpression(components: ["item", ">", "1"], tokenParser: TokenParser(tokens: [], environment: Environment()), token: .text(value: "", at: .unknown))
|
||||
let parser = TokenParser(tokens: [], environment: Environment())
|
||||
let `where` = try parser.compileExpression(components: ["item", ">", "1"], token: .text(value: "", at: .unknown))
|
||||
let node = ForNode(resolvable: Variable("items"), loopVariables: ["item"], nodes: nodes, emptyNodes: [], where: `where`)
|
||||
try expect(try node.render(context)) == "2132"
|
||||
}
|
||||
@@ -107,7 +108,8 @@ class ForNodeTests: XCTestCase {
|
||||
$0.it("renders the given empty nodes when all items filtered out with where expression") {
|
||||
let nodes: [NodeType] = [VariableNode(variable: "item")]
|
||||
let emptyNodes: [NodeType] = [TextNode(text: "empty")]
|
||||
let `where` = try parseExpression(components: ["item", "==", "0"], tokenParser: TokenParser(tokens: [], environment: Environment()), token: .text(value: "", at: .unknown))
|
||||
let parser = TokenParser(tokens: [], environment: Environment())
|
||||
let `where` = try parser.compileExpression(components: ["item", "==", "0"], token: .text(value: "", at: .unknown))
|
||||
let node = ForNode(resolvable: Variable("emptyItems"), loopVariables: ["item"], nodes: nodes, emptyNodes: emptyNodes, where: `where`)
|
||||
try expect(try node.render(context)) == "empty"
|
||||
}
|
||||
|
||||
@@ -351,8 +351,7 @@ class VariableTests: XCTestCase {
|
||||
|
||||
func makeVariable(_ token: String) throws -> RangeVariable? {
|
||||
let token = Token.variable(value: token, at: .unknown)
|
||||
let parser = TokenParser(tokens: [token], environment: context.environment)
|
||||
return try RangeVariable(token.contents, parser: parser, containedIn: token)
|
||||
return try RangeVariable(token.contents, environment: context.environment, containedIn: token)
|
||||
}
|
||||
|
||||
$0.it("can resolve closed range as array") {
|
||||
|
||||
Reference in New Issue
Block a user