Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SwiftLint integration #249

Merged
merged 6 commits into from
Nov 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
opt_in_rules:
- anyobject_protocol
- array_init
- attributes
- closure_end_indentation
- closure_spacing
- contains_over_first_not_nil
- convenience_type
- discouraged_optional_boolean
- discouraged_optional_collection
- empty_count
- empty_string
- fallthrough
- fatal_error_message
- first_where
- force_unwrapping
- implicit_return
- implicitly_unwrapped_optional
- joined_default_parameter
- literal_expression_end_indentation
- lower_acl_than_parent
- modifier_order
- multiline_arguments
- multiline_function_chains
- multiline_parameters
- number_separator
- operator_usage_whitespace
- overridden_super_call
- override_in_extension
- private_action
- private_outlet
- prohibited_super_call
- redundant_nil_coalescing
- sorted_first_last
- sorted_imports
- trailing_closure
- unavailable_function
- unneeded_parentheses_in_closure_argument
- vertical_parameter_alignment_on_call
- yoda_condition

# Rules customization
line_length:
warning: 120
error: 200

nesting:
type_level:
warning: 2

# Exclude generated files
excluded:
- .build
- Tests/StencilTests/XCTestManifests.swift
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ sudo: required
dist: trusty
install:
- eval "$(curl -sL https://swiftenv.fuller.li/install.sh)"
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then wget --output-document /tmp/SwiftLint.pkg https://github.com/realm/SwiftLint/releases/download/0.27.0/SwiftLint.pkg &&
sudo installer -pkg /tmp/SwiftLint.pkg -target /; fi
script:
- swift test
- swift test
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then swiftlint; fi
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ _None_
- `Token` type converted to struct to allow computing token components only once.
[Ilya Puchka](https://github.com/ilyapuchka)
[#256](https://github.com/stencilproject/Stencil/pull/256)
- Added SwiftLint to the project.
[David Jennes](https://github.com/djbe)
[#249](https://github.com/stencilproject/Stencil/pull/249)


## 0.13.1
Expand Down
19 changes: 9 additions & 10 deletions Sources/Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ public class Context {
var dictionaries: [[String: Any?]]

public let environment: Environment
init(dictionary: [String: Any]? = nil, environment: Environment? = nil) {
if let dictionary = dictionary {

init(dictionary: [String: Any] = [:], environment: Environment? = nil) {
if !dictionary.isEmpty {
dictionaries = [dictionary]
} else {
dictionaries = []
Expand All @@ -28,17 +28,16 @@ public class Context {

/// Set a variable in the current context, deleting the variable if it's nil
set(value) {
if let dictionary = dictionaries.popLast() {
var mutable_dictionary = dictionary
mutable_dictionary[key] = value
dictionaries.append(mutable_dictionary)
if var dictionary = dictionaries.popLast() {
dictionary[key] = value
dictionaries.append(dictionary)
}
}
}

/// Push a new level into the Context
fileprivate func push(_ dictionary: [String: Any]? = nil) {
dictionaries.append(dictionary ?? [:])
fileprivate func push(_ dictionary: [String: Any] = [:]) {
dictionaries.append(dictionary)
}

/// Pop the last level off of the Context
Expand All @@ -47,7 +46,7 @@ public class Context {
}

/// Push a new level onto the context for the duration of the execution of the given closure
public func push<Result>(dictionary: [String: Any]? = nil, closure: (() throws -> Result)) rethrows -> Result {
public func push<Result>(dictionary: [String: Any] = [:], closure: (() throws -> Result)) rethrows -> Result {
push(dictionary)
defer { _ = pop() }
return try closure()
Expand Down
10 changes: 5 additions & 5 deletions Sources/Environment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ public struct Environment {
public var loader: Loader?

public init(loader: Loader? = nil,
extensions: [Extension]? = nil,
extensions: [Extension] = [],
templateClass: Template.Type = Template.self) {

self.templateClass = templateClass
self.loader = loader
self.extensions = (extensions ?? []) + [DefaultExtension()]
self.extensions = extensions + [DefaultExtension()]
}

public func loadTemplate(name: String) throws -> Template {
Expand All @@ -29,17 +29,17 @@ public struct Environment {
}
}

public func renderTemplate(name: String, context: [String: Any]? = nil) throws -> String {
public func renderTemplate(name: String, context: [String: Any] = [:]) throws -> String {
let template = try loadTemplate(name: name)
return try render(template: template, context: context)
}

public func renderTemplate(string: String, context: [String: Any]? = nil) throws -> String {
public func renderTemplate(string: String, context: [String: Any] = [:]) throws -> String {
let template = templateClass.init(templateString: string, environment: self)
return try render(template: template, context: context)
}

func render(template: Template, context: [String: Any]?) throws -> String {
func render(template: Template, context: [String: Any]) throws -> String {
// update template environment as it can be created from string literal with default environment
template.environment = self
return try template.render(context)
Expand Down
6 changes: 3 additions & 3 deletions Sources/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ public class TemplateDoesNotExist: Error, CustomStringConvertible {
}
}

public struct TemplateSyntaxError : Error, Equatable, CustomStringConvertible {
public struct TemplateSyntaxError: Error, Equatable, CustomStringConvertible {
public let reason: String
public var description: String { return reason }
public internal(set) var token: Token?
public internal(set) var stackTrace: [Token]
public var templateName: String? { return token?.sourceMap.filename }
var allTokens: [Token] {
return stackTrace + (token.map({ [$0] }) ?? [])
return stackTrace + (token.map { [$0] } ?? [])
}

public init(reason: String, token: Token? = nil, stackTrace: [Token] = []) {
Expand All @@ -50,7 +50,7 @@ extension Error {
}
}

public protocol ErrorReporter: class {
public protocol ErrorReporter: AnyObject {
func renderError(_ error: Error) -> String
}

Expand Down
29 changes: 8 additions & 21 deletions Sources/Expression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,14 @@ public protocol Expression: CustomStringConvertible {
func evaluate(context: Context) throws -> Bool
}


protocol InfixOperator: Expression {
init(lhs: Expression, rhs: Expression)
}


protocol PrefixOperator: Expression {
init(expression: Expression)
}


final class StaticExpression: Expression, CustomStringConvertible {
let value: Bool

Expand All @@ -29,7 +26,6 @@ final class StaticExpression: Expression, CustomStringConvertible {
}
}


final class VariableExpression: Expression, CustomStringConvertible {
let variable: Resolvable

Expand All @@ -48,7 +44,7 @@ final class VariableExpression: Expression, CustomStringConvertible {

if let result = result as? [Any] {
truthy = !result.isEmpty
} else if let result = result as? [String:Any] {
} else if let result = result as? [String: Any] {
truthy = !result.isEmpty
} else if let result = result as? Bool {
truthy = result
Expand All @@ -68,7 +64,6 @@ final class VariableExpression: Expression, CustomStringConvertible {
}
}


final class NotExpression: Expression, PrefixOperator, CustomStringConvertible {
let expression: Expression

Expand Down Expand Up @@ -144,7 +139,6 @@ final class OrExpression: Expression, InfixOperator, CustomStringConvertible {
}
}


final class AndExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression
let rhs: Expression
Expand All @@ -168,7 +162,6 @@ final class AndExpression: Expression, InfixOperator, CustomStringConvertible {
}
}


class EqualityExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression
let rhs: Expression
Expand Down Expand Up @@ -204,7 +197,6 @@ class EqualityExpression: Expression, InfixOperator, CustomStringConvertible {
}
}


class NumericExpression: Expression, InfixOperator, CustomStringConvertible {
let lhs: Expression
let rhs: Expression
Expand All @@ -215,7 +207,7 @@ class NumericExpression: Expression, InfixOperator, CustomStringConvertible {
}

var description: String {
return "(\(lhs) \(op) \(rhs))"
return "(\(lhs) \(symbol) \(rhs))"
}

func evaluate(context: Context) throws -> Bool {
Expand All @@ -233,7 +225,7 @@ class NumericExpression: Expression, InfixOperator, CustomStringConvertible {
return false
}

var op: String {
var symbol: String {
return ""
}

Expand All @@ -242,9 +234,8 @@ class NumericExpression: Expression, InfixOperator, CustomStringConvertible {
}
}


class MoreThanExpression: NumericExpression {
override var op: String {
override var symbol: String {
return ">"
}

Expand All @@ -253,9 +244,8 @@ class MoreThanExpression: NumericExpression {
}
}


class MoreThanEqualExpression: NumericExpression {
override var op: String {
override var symbol: String {
return ">="
}

Expand All @@ -264,9 +254,8 @@ class MoreThanEqualExpression: NumericExpression {
}
}


class LessThanExpression: NumericExpression {
override var op: String {
override var symbol: String {
return "<"
}

Expand All @@ -275,9 +264,8 @@ class LessThanExpression: NumericExpression {
}
}


class LessThanEqualExpression: NumericExpression {
override var op: String {
override var symbol: String {
return "<="
}

Expand All @@ -286,7 +274,6 @@ class LessThanEqualExpression: NumericExpression {
}
}


class InequalityExpression: EqualityExpression {
override var description: String {
return "(\(lhs) != \(rhs))"
Expand All @@ -297,7 +284,7 @@ class InequalityExpression: EqualityExpression {
}
}


// swiftlint:disable:next cyclomatic_complexity
func toNumber(value: Any) -> Number? {
if let value = value as? Float {
return Number(value)
Expand Down
11 changes: 5 additions & 6 deletions Sources/Extension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ open class Extension {

/// Registers a simple template tag with a name and a handler
public func registerSimpleTag(_ name: String, handler: @escaping (Context) throws -> String) {
registerTag(name, parser: { parser, token in
return SimpleNode(token: token, handler: handler)
})
registerTag(name) { _, token in
SimpleNode(token: token, handler: handler)
}
}

/// Registers boolean filter with it's negative counterpart
// swiftlint:disable:next discouraged_optional_boolean
public func registerFilter(name: String, negativeFilterName: String, filter: @escaping (Any?) throws -> Bool?) {
filters[name] = .simple(filter)
filters[negativeFilterName] = .simple {
Expand All @@ -44,7 +45,6 @@ open class Extension {
}
}


class DefaultExtension: Extension {
override init() {
super.init()
Expand Down Expand Up @@ -77,7 +77,6 @@ class DefaultExtension: Extension {
}
}


protocol FilterType {
func invoke(value: Any?, arguments: [Any?], context: Context) throws -> Any?
}
Expand Down
5 changes: 2 additions & 3 deletions Sources/FilterTag.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class FilterNode : NodeType {
class FilterNode: NodeType {
let resolvable: Resolvable
let nodes: [NodeType]
let token: Token?
Expand Down Expand Up @@ -30,8 +30,7 @@ class FilterNode : NodeType {
let value = try renderNodes(nodes, context)

return try context.push(dictionary: ["filter_value": value]) {
return try VariableNode(variable: resolvable, token: token).render(context)
try VariableNode(variable: resolvable, token: token).render(context)
}
}
}

Loading