Feat: Add support for Swift 4.0
This commit is contained in:
@@ -1,11 +1,16 @@
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- os: osx
|
||||||
|
osx_image: xcode9.2
|
||||||
|
env: SWIFT_VERSION=4.0.3
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode9.4
|
osx_image: xcode9.4
|
||||||
env: SWIFT_VERSION=4.1
|
env: SWIFT_VERSION=4.1
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode10
|
osx_image: xcode10
|
||||||
env: SWIFT_VERSION=4.2
|
env: SWIFT_VERSION=4.2
|
||||||
|
- os: linux
|
||||||
|
env: SWIFT_VERSION=4.0.3
|
||||||
- os: linux
|
- os: linux
|
||||||
env: SWIFT_VERSION=4.1
|
env: SWIFT_VERSION=4.1
|
||||||
- os: linux
|
- os: linux
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// swift-tools-version:4.1
|
// swift-tools-version:4.0
|
||||||
import PackageDescription
|
import PackageDescription
|
||||||
|
|
||||||
let package = Package(
|
let package = Package(
|
||||||
|
|||||||
@@ -37,6 +37,15 @@ public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible {
|
|||||||
public init(_ description: String) {
|
public init(_ description: String) {
|
||||||
self.init(reason: description)
|
self.init(reason: description)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: TemplateSyntaxError, rhs: TemplateSyntaxError) -> Bool {
|
||||||
|
return lhs.reason == rhs.reason &&
|
||||||
|
lhs.description == rhs.description &&
|
||||||
|
lhs.token == rhs.token &&
|
||||||
|
lhs.stackTrace == rhs.stackTrace &&
|
||||||
|
lhs.templateName == rhs.templateName &&
|
||||||
|
lhs.allTokens == rhs.allTokens
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Error {
|
extension Error {
|
||||||
|
|||||||
@@ -118,7 +118,12 @@ final class IfExpressionParser {
|
|||||||
private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws {
|
private init(components: ArraySlice<String>, tokenParser: TokenParser, token: Token) throws {
|
||||||
var parsedComponents = Set<Int>()
|
var parsedComponents = Set<Int>()
|
||||||
var bracketsBalance = 0
|
var bracketsBalance = 0
|
||||||
self.tokens = try zip(components.indices, components).compactMap { (index, component) in
|
#if swift(>=4.1)
|
||||||
|
self.tokens = try zip(components.indices, components).compactMap { try parseComponent(index: $0.0, component: $0.1) }
|
||||||
|
#else
|
||||||
|
self.tokens = try zip(components.indices, components).flatMap { try parseComponent(index: $0.0, component: $0.1) }
|
||||||
|
#endif
|
||||||
|
func parseComponent(index: Int, component: String) throws -> IfToken? {
|
||||||
guard !parsedComponents.contains(index) else { return nil }
|
guard !parsedComponents.contains(index) else { return nil }
|
||||||
|
|
||||||
if component == "(" {
|
if component == "(" {
|
||||||
|
|||||||
@@ -63,9 +63,11 @@ class ExtendsNode : NodeType {
|
|||||||
guard (parsedNodes.any { $0 is ExtendsNode }) == nil else {
|
guard (parsedNodes.any { $0 is ExtendsNode }) == nil else {
|
||||||
throw TemplateSyntaxError("'extends' cannot appear more than once in the same template")
|
throw TemplateSyntaxError("'extends' cannot appear more than once in the same template")
|
||||||
}
|
}
|
||||||
|
#if swift(>=4.1)
|
||||||
let blockNodes = parsedNodes.compactMap { $0 as? BlockNode }
|
let blockNodes = parsedNodes.compactMap { $0 as? BlockNode }
|
||||||
|
#else
|
||||||
|
let blockNodes = parsedNodes.flatMap { $0 as? BlockNode }
|
||||||
|
#endif
|
||||||
let nodes = blockNodes.reduce([String: BlockNode]()) { (accumulator, node) -> [String: BlockNode] in
|
let nodes = blockNodes.reduce([String: BlockNode]()) { (accumulator, node) -> [String: BlockNode] in
|
||||||
var dict = accumulator
|
var dict = accumulator
|
||||||
dict[node.name] = node
|
dict[node.name] = node
|
||||||
|
|||||||
@@ -22,11 +22,17 @@ struct Lexer {
|
|||||||
init(templateName: String? = nil, templateString: String) {
|
init(templateName: String? = nil, templateString: String) {
|
||||||
self.templateName = templateName
|
self.templateName = templateName
|
||||||
self.templateString = templateString
|
self.templateString = templateString
|
||||||
|
#if swift(>=4.1)
|
||||||
self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap {
|
self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap {
|
||||||
guard !$0.element.isEmpty else { return nil }
|
guard !$0.element.isEmpty else { return nil }
|
||||||
return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!)
|
return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!)
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
self.lines = templateString.components(separatedBy: .newlines).enumerated().flatMap {
|
||||||
|
guard !$0.element.isEmpty else { return nil }
|
||||||
|
return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a token that will be passed on to the parser, with the given
|
/// Create a token that will be passed on to the parser, with the given
|
||||||
|
|||||||
@@ -116,8 +116,13 @@ public struct Variable : Equatable, Resolvable {
|
|||||||
|
|
||||||
return normalize(current)
|
return normalize(current)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func ==(lhs: Variable, rhs: Variable) -> Bool {
|
||||||
|
return lhs.variable == rhs.variable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if swift(>=4.1)
|
||||||
private func resolveCollection<T: Collection>(_ collection: T, bit: String) -> Any? {
|
private func resolveCollection<T: Collection>(_ collection: T, bit: String) -> Any? {
|
||||||
if let index = Int(bit) {
|
if let index = Int(bit) {
|
||||||
if index >= 0 && index < collection.count {
|
if index >= 0 && index < collection.count {
|
||||||
@@ -135,6 +140,25 @@ private func resolveCollection<T: Collection>(_ collection: T, bit: String) -> A
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
private func resolveCollection<T: Collection>(_ collection: T, bit: String) -> Any? where T.IndexDistance == Int {
|
||||||
|
if let index = Int(bit) {
|
||||||
|
if index >= 0 && index < collection.count {
|
||||||
|
return collection[collection.index(collection.startIndex, offsetBy: index)]
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else if bit == "first" {
|
||||||
|
return collection.first
|
||||||
|
} else if bit == "last" {
|
||||||
|
return collection[collection.index(collection.endIndex, offsetBy: -1)]
|
||||||
|
} else if bit == "count" {
|
||||||
|
return collection.count
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/// A structure used to represet range of two integer values expressed as `from...to`.
|
/// A structure used to represet range of two integer values expressed as `from...to`.
|
||||||
/// Values should be numbers (they will be converted to integers).
|
/// Values should be numbers (they will be converted to integers).
|
||||||
|
|||||||
Reference in New Issue
Block a user