From 66a9bc563aa17107679575ceb7d71dbbcd3ceaa0 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 1 Oct 2018 11:58:20 +0100 Subject: [PATCH 1/4] Feat: Add support for Swift 4.0 --- .travis.yml | 5 +++++ Package.swift | 2 +- Sources/Errors.swift | 9 +++++++++ Sources/IfTag.swift | 7 ++++++- Sources/Inheritence.swift | 8 +++++--- Sources/Lexer.swift | 16 +++++++++++----- Sources/Variable.swift | 24 ++++++++++++++++++++++++ 7 files changed, 61 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9240617..8639971 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,16 @@ matrix: include: + - os: osx + osx_image: xcode9.2 + env: SWIFT_VERSION=4.0.3 - os: osx osx_image: xcode9.4 env: SWIFT_VERSION=4.1 - os: osx osx_image: xcode10 env: SWIFT_VERSION=4.2 + - os: linux + env: SWIFT_VERSION=4.0.3 - os: linux env: SWIFT_VERSION=4.1 - os: linux diff --git a/Package.swift b/Package.swift index 2dd6977..b5fb304 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:4.1 +// swift-tools-version:4.0 import PackageDescription let package = Package( diff --git a/Sources/Errors.swift b/Sources/Errors.swift index a6191f9..e885ab3 100644 --- a/Sources/Errors.swift +++ b/Sources/Errors.swift @@ -37,6 +37,15 @@ public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible { public init(_ description: String) { 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 { diff --git a/Sources/IfTag.swift b/Sources/IfTag.swift index 125f55f..4fd6974 100644 --- a/Sources/IfTag.swift +++ b/Sources/IfTag.swift @@ -118,7 +118,12 @@ final class IfExpressionParser { private init(components: ArraySlice, tokenParser: TokenParser, token: Token) throws { var parsedComponents = Set() 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 } if component == "(" { diff --git a/Sources/Inheritence.swift b/Sources/Inheritence.swift index e512bfb..1507f1f 100644 --- a/Sources/Inheritence.swift +++ b/Sources/Inheritence.swift @@ -63,9 +63,11 @@ class ExtendsNode : NodeType { guard (parsedNodes.any { $0 is ExtendsNode }) == nil else { throw TemplateSyntaxError("'extends' cannot appear more than once in the same template") } - - let blockNodes = parsedNodes.compactMap { $0 as? BlockNode } - + #if swift(>=4.1) + 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 var dict = accumulator dict[node.name] = node diff --git a/Sources/Lexer.swift b/Sources/Lexer.swift index f6fc426..77e956a 100644 --- a/Sources/Lexer.swift +++ b/Sources/Lexer.swift @@ -22,11 +22,17 @@ struct Lexer { init(templateName: String? = nil, templateString: String) { self.templateName = templateName self.templateString = templateString - - self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap { - guard !$0.element.isEmpty else { return nil } - return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!) - } + #if swift(>=4.1) + self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap { + guard !$0.element.isEmpty else { return nil } + 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 diff --git a/Sources/Variable.swift b/Sources/Variable.swift index eb30060..203ecc8 100644 --- a/Sources/Variable.swift +++ b/Sources/Variable.swift @@ -116,9 +116,32 @@ public struct Variable : Equatable, Resolvable { return normalize(current) } + + public static func ==(lhs: Variable, rhs: Variable) -> Bool { + return lhs.variable == rhs.variable + } } +#if swift(>=4.1) private func resolveCollection(_ collection: T, bit: String) -> Any? { + 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 + } +} +#else +private func resolveCollection(_ 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)] @@ -135,6 +158,7 @@ private func resolveCollection(_ collection: T, bit: String) -> A return nil } } +#endif /// A structure used to represet range of two integer values expressed as `from...to`. /// Values should be numbers (they will be converted to integers). From 9bd86d9fd5dcb6af43b752d44011213c8f1ffebb Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 1 Oct 2018 14:54:10 +0100 Subject: [PATCH 2/4] Moved swift4.0 support into single file --- Sources/Errors.swift | 11 ++-------- Sources/IfTag.swift | 7 +------ Sources/Inheritence.swift | 6 +----- Sources/Lexer.swift | 15 ++++--------- Sources/Variable.swift | 23 -------------------- Sources/_SwiftSupport.swift | 42 +++++++++++++++++++++++++++++++++++++ 6 files changed, 50 insertions(+), 54 deletions(-) create mode 100644 Sources/_SwiftSupport.swift diff --git a/Sources/Errors.swift b/Sources/Errors.swift index e885ab3..91e617b 100644 --- a/Sources/Errors.swift +++ b/Sources/Errors.swift @@ -37,15 +37,8 @@ public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible { public init(_ description: String) { 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 { diff --git a/Sources/IfTag.swift b/Sources/IfTag.swift index 4fd6974..125f55f 100644 --- a/Sources/IfTag.swift +++ b/Sources/IfTag.swift @@ -118,12 +118,7 @@ final class IfExpressionParser { private init(components: ArraySlice, tokenParser: TokenParser, token: Token) throws { var parsedComponents = Set() var bracketsBalance = 0 - #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? { + self.tokens = try zip(components.indices, components).compactMap { (index, component) in guard !parsedComponents.contains(index) else { return nil } if component == "(" { diff --git a/Sources/Inheritence.swift b/Sources/Inheritence.swift index 1507f1f..f72f7ae 100644 --- a/Sources/Inheritence.swift +++ b/Sources/Inheritence.swift @@ -63,11 +63,7 @@ class ExtendsNode : NodeType { guard (parsedNodes.any { $0 is ExtendsNode }) == nil else { throw TemplateSyntaxError("'extends' cannot appear more than once in the same template") } - #if swift(>=4.1) - let blockNodes = parsedNodes.compactMap { $0 as? BlockNode } - #else - let blockNodes = parsedNodes.flatMap { $0 as? BlockNode } - #endif + let blockNodes = parsedNodes.compactMap { $0 as? BlockNode } let nodes = blockNodes.reduce([String: BlockNode]()) { (accumulator, node) -> [String: BlockNode] in var dict = accumulator dict[node.name] = node diff --git a/Sources/Lexer.swift b/Sources/Lexer.swift index 77e956a..a64b05c 100644 --- a/Sources/Lexer.swift +++ b/Sources/Lexer.swift @@ -22,17 +22,10 @@ struct Lexer { init(templateName: String? = nil, templateString: String) { self.templateName = templateName self.templateString = templateString - #if swift(>=4.1) - self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap { - guard !$0.element.isEmpty else { return nil } - 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 + self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap { + guard !$0.element.isEmpty else { return nil } + return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!) + } } /// Create a token that will be passed on to the parser, with the given diff --git a/Sources/Variable.swift b/Sources/Variable.swift index 203ecc8..797cd8a 100644 --- a/Sources/Variable.swift +++ b/Sources/Variable.swift @@ -117,12 +117,8 @@ public struct Variable : Equatable, Resolvable { return normalize(current) } - public static func ==(lhs: Variable, rhs: Variable) -> Bool { - return lhs.variable == rhs.variable - } } -#if swift(>=4.1) private func resolveCollection(_ collection: T, bit: String) -> Any? { if let index = Int(bit) { if index >= 0 && index < collection.count { @@ -140,25 +136,6 @@ private func resolveCollection(_ collection: T, bit: String) -> A return nil } } -#else -private func resolveCollection(_ 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`. /// Values should be numbers (they will be converted to integers). diff --git a/Sources/_SwiftSupport.swift b/Sources/_SwiftSupport.swift new file mode 100644 index 0000000..fcaa007 --- /dev/null +++ b/Sources/_SwiftSupport.swift @@ -0,0 +1,42 @@ +import Foundation + +#if swift(>=4.1) +#else + public extension Sequence { + func compactMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { + return try flatMap(transform) + } + } +#endif + +#if swift(>=4.1) +#else + public extension Collection { + func index(_ i: Self.Index, offsetBy n: Int) -> Self.Index { + let indexDistance = Self.IndexDistance(n) + return index(i, offsetBy: indexDistance) + } + } +#endif + +#if swift(>=4.1) +#else +public extension TemplateSyntaxError { + 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 + } +} +#endif + +#if swift(>=4.1) +#else +public extension Variable { + public static func ==(lhs: Variable, rhs: Variable) -> Bool { + return lhs.variable == rhs.variable + } +} +#endif From fd790450538137ec9685e455d86dd4e0e01e94ab Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 1 Oct 2018 14:56:09 +0100 Subject: [PATCH 3/4] removed whitespace changes --- Sources/Errors.swift | 2 -- Sources/Inheritence.swift | 2 ++ Sources/Lexer.swift | 1 + Sources/Variable.swift | 3 +-- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Errors.swift b/Sources/Errors.swift index 91e617b..a6191f9 100644 --- a/Sources/Errors.swift +++ b/Sources/Errors.swift @@ -37,8 +37,6 @@ public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible { public init(_ description: String) { self.init(reason: description) } - - } extension Error { diff --git a/Sources/Inheritence.swift b/Sources/Inheritence.swift index f72f7ae..e512bfb 100644 --- a/Sources/Inheritence.swift +++ b/Sources/Inheritence.swift @@ -63,7 +63,9 @@ class ExtendsNode : NodeType { guard (parsedNodes.any { $0 is ExtendsNode }) == nil else { throw TemplateSyntaxError("'extends' cannot appear more than once in the same template") } + let blockNodes = parsedNodes.compactMap { $0 as? BlockNode } + let nodes = blockNodes.reduce([String: BlockNode]()) { (accumulator, node) -> [String: BlockNode] in var dict = accumulator dict[node.name] = node diff --git a/Sources/Lexer.swift b/Sources/Lexer.swift index a64b05c..f6fc426 100644 --- a/Sources/Lexer.swift +++ b/Sources/Lexer.swift @@ -22,6 +22,7 @@ struct Lexer { init(templateName: String? = nil, templateString: String) { self.templateName = templateName self.templateString = templateString + self.lines = templateString.components(separatedBy: .newlines).enumerated().compactMap { guard !$0.element.isEmpty else { return nil } return (content: $0.element, number: UInt($0.offset + 1), templateString.range(of: $0.element)!) diff --git a/Sources/Variable.swift b/Sources/Variable.swift index 797cd8a..eb30060 100644 --- a/Sources/Variable.swift +++ b/Sources/Variable.swift @@ -116,13 +116,12 @@ public struct Variable : Equatable, Resolvable { return normalize(current) } - } private func resolveCollection(_ collection: T, bit: String) -> Any? { if let index = Int(bit) { if index >= 0 && index < collection.count { - return collection[collection.index(collection.startIndex, offsetBy: index)] + return collection[collection.index(collection.startIndex, offsetBy: index)] } else { return nil } From 4154cd31ff22aff229cd89b044a26803f8534337 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 1 Oct 2018 15:11:03 +0100 Subject: [PATCH 4/4] Changed to if swift package generate-xcodeproj(>=4.1) --- Sources/_SwiftSupport.swift | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Sources/_SwiftSupport.swift b/Sources/_SwiftSupport.swift index fcaa007..5333659 100644 --- a/Sources/_SwiftSupport.swift +++ b/Sources/_SwiftSupport.swift @@ -1,7 +1,6 @@ import Foundation -#if swift(>=4.1) -#else +#if !swift(>=4.1) public extension Sequence { func compactMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { return try flatMap(transform) @@ -9,8 +8,7 @@ import Foundation } #endif -#if swift(>=4.1) -#else +#if !swift(>=4.1) public extension Collection { func index(_ i: Self.Index, offsetBy n: Int) -> Self.Index { let indexDistance = Self.IndexDistance(n) @@ -19,8 +17,7 @@ import Foundation } #endif -#if swift(>=4.1) -#else +#if !swift(>=4.1) public extension TemplateSyntaxError { public static func ==(lhs: TemplateSyntaxError, rhs: TemplateSyntaxError) -> Bool { return lhs.reason == rhs.reason && @@ -32,8 +29,7 @@ public extension TemplateSyntaxError { } #endif -#if swift(>=4.1) -#else +#if !swift(>=4.1) public extension Variable { public static func ==(lhs: Variable, rhs: Variable) -> Bool { return lhs.variable == rhs.variable