Failure to parse now returns an error

This commit is contained in:
Jeroen Engels 2017-06-12 20:04:02 +02:00
parent 5eee6e50e1
commit c4974111fb
34 changed files with 167 additions and 103 deletions

View File

@ -27,6 +27,7 @@
"dependencies": {
"Bogdanp/elm-ast": "8.0.3 <= v < 9.0.0",
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
"elm-community/parser-combinators": "1.1.0 <= v < 2.0.0",
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0"
},

View File

@ -1,16 +1,31 @@
module Main exposing (main)
import Result
import Ast
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
import Html exposing (Html, p, div, li, ul, pre, textarea, text)
import Html.Attributes exposing (id, class)
import Combine
import Html exposing (..)
import Html.Attributes exposing (class, id)
import Html.Events exposing (..)
import Json.Decode as JD
import Lint exposing (lintSource)
import Lint.Rules.DefaultPatternPosition
import Lint.Rules.NoConstantCondition
import Lint.Rules.NoDebug
import Lint.Rules.NoDuplicateImports
import Lint.Rules.NoExposingEverything
import Lint.Rules.NoImportingEverything
import Lint.Rules.NoNestedLet
import Lint.Rules.NoUnannotatedFunction
import Lint.Rules.NoUnusedVariables
import Lint.Rules.NoUselessIf
import Lint.Rules.NoUselessPatternMatching
import Lint.Rules.NoWarningComments
import Lint.Rules.SimplifyPiping
import Lint.Rules.SimplifyPropertyAccess
import Lint.Types
import Regex exposing (regex, escape)
import Regex exposing (escape, regex)
import Result
-- Rules
@ -35,7 +50,7 @@ type Msg
= Replace String
rules : List (String -> List Lint.Types.Error)
rules : List Lint.Types.LintRule
rules =
[ Lint.Rules.DefaultPatternPosition.rule { position = Lint.Rules.DefaultPatternPosition.Last }
, Lint.Rules.NoConstantCondition.rule
@ -165,27 +180,32 @@ statement s =
defaultDisplay
tree : Result a ( b, c, List Statement ) -> Html Msg
tree : Result (Combine.ParseErr ()) ( b, c, List Statement ) -> Html Msg
tree ast =
case ast of
Ok ( _, _, statements ) ->
ul [] (List.map statement statements)
err ->
div [] [ text "Sorry, I could not parse your code. This may be my fault though :/" ]
Err ( _, _, errors ) ->
div [] (List.map text errors)
lint : String -> Html Msg
lint source =
let
errors =
lintResult =
lintSource rules source
messages =
if List.isEmpty errors then
[ "No errors." ]
else
errors
case lintResult of
Err errors ->
errors
Ok errors ->
if List.isEmpty errors then
[ "No errors." ]
else
errors
in
div []
(List.map

View File

@ -10,6 +10,7 @@
"exposed-modules": [],
"dependencies": {
"elm-community/list-extra": "5.0.1 <= v < 6.0.0",
"elm-community/parser-combinators": "1.1.0 <= v < 2.0.0",
"elm-lang/core": "5.0.0 <= v < 6.0.0",
"elm-lang/html": "2.0.0 <= v < 3.0.0",
"jfmengels/elm-ast": "1.0.0 <= v < 2.0.0"

View File

@ -32,7 +32,9 @@ To run the rules on a source code and get a list of errors:
import Ast
import Ast.Expression exposing (Expression)
import Lint.Types exposing (Error, LintImplementation, LintRule, Direction, Visitor)
import Ast.Statement
import Combine
import Lint.Types exposing (LintRule, LintResult, Error, LintImplementation, LintRuleImplementation, Direction, Visitor)
import Lint.Visitor exposing (transformStatementsIntoVisitors, expressionToVisitors)
import Regex
@ -42,11 +44,37 @@ import Regex
errors =
lintSource rules source
-}
lintSource : List (String -> List Error) -> String -> List String
lintSource : List LintRule -> String -> Result (List String) (List String)
lintSource rules source =
rules
|> List.concatMap (\rule -> rule source)
|> List.map (\err -> err.rule ++ ": " ++ err.message)
let
sourceParsingResult =
parseSource source
in
case sourceParsingResult of
Err err ->
Err err
Ok parsedSource ->
rules
|> List.concatMap
(\rule -> rule source |> Result.withDefault [])
|> List.map (\err -> err.rule ++ ": " ++ err.message)
|> Ok
parseSource : String -> Result (List String) (Combine.ParseOk () (List Ast.Statement.Statement))
parseSource source =
source
|> removeComments
|> Ast.parse
|> (\sourceParsingResult ->
case sourceParsingResult of
Err ( _, _, errors ) ->
Err errors
Ok parsedSource ->
Ok parsedSource
)
removeComments : String -> String
@ -57,11 +85,11 @@ removeComments =
{-| Lints source code using a given rule implementation, and gives back a list of errors that were found.
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
@ -70,15 +98,16 @@ removeComments =
, initialContext = Context
}
-}
lint : String -> LintRule context -> List Error
lint source =
lint : String -> LintRuleImplementation context -> LintResult
lint source rule =
source
|> removeComments
|> Ast.parse
|> Result.map (\( _, _, statements ) -> statements)
|> Result.withDefault []
|> transformStatementsIntoVisitors
|> lintWithVisitors
|> parseSource
|> Result.map
(\( _, _, statements ) ->
statements
|> transformStatementsIntoVisitors
|> lintWithVisitors rule
)
{-| Visit an expression using a sub rule implementation. The use of this function is not encouraged, but it can make
@ -92,7 +121,7 @@ part of the implementation of complex rules much easier. It gives back a list of
_ ->
( [], ctx )
subimplementation : LintRule Subcontext
subimplementation : LintRuleImplementation Subcontext
subimplementation =
{ statementFn = doNothing
, typeFn = doNothing
@ -101,20 +130,20 @@ part of the implementation of complex rules much easier. It gives back a list of
, initialContext = Subcontext
}
-}
visitExpression : LintRule context -> Expression -> ( List Error, context )
visitExpression : LintRuleImplementation context -> Expression -> ( List Error, context )
visitExpression rule expression =
expressionToVisitors expression
|> List.foldl (visitAndAccumulate rule) ( [], rule.initialContext )
visitAndAccumulate : LintRule context -> Visitor context -> ( List Error, context ) -> ( List Error, context )
visitAndAccumulate : LintRuleImplementation context -> Visitor context -> ( List Error, context ) -> ( List Error, context )
visitAndAccumulate rule visitor ( errors, ctx ) =
visitor rule ctx
|> Tuple.mapFirst (\errors_ -> errors ++ errors_)
lintWithVisitors : List (Visitor context) -> LintRule context -> List Error
lintWithVisitors visitors rule =
lintWithVisitors : LintRuleImplementation context -> List (Visitor context) -> List Error
lintWithVisitors rule visitors =
visitors
|> List.foldl (visitAndAccumulate rule) ( [], rule.initialContext )
|> Tuple.first
@ -123,7 +152,7 @@ lintWithVisitors visitors rule =
{-| Basic implementation of a visitor function that does nothing, i.e. return an empty list of errors and an untouched
context. This is used to avoid a bit of boilerplate for visitor functions whose node types we are not interested in.
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -53,7 +53,7 @@ module Lint.Rules.DefaultPatternPosition exposing (rule, PatternPosition(..))
import Ast.Expression exposing (..)
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), Error, LintRule)
import Lint.Types exposing (LintRule, Direction(..), Error, LintRuleImplementation)
import List.Extra exposing (findIndex)
import Regex
@ -76,12 +76,12 @@ type alias Configuration =
{-| Enforce the default pattern to always appear first or last.
-}
rule : Configuration -> String -> List Error
rule : Configuration -> LintRule
rule config input =
lint input (implementation config)
implementation : Configuration -> LintRule Context
implementation : Configuration -> LintRuleImplementation Context
implementation configuration =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -16,7 +16,7 @@ module Lint.Rules.NoConstantCondition exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
import Set exposing (Set)
@ -30,12 +30,12 @@ type alias Context =
[ NoConstantCondition.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -21,7 +21,7 @@ module Lint.Rules.NoDebug exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -34,12 +34,12 @@ type alias Context =
[ NoDebug.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -15,7 +15,7 @@ module Lint.Rules.NoDuplicateImports exposing (rule)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
import Set exposing (Set)
@ -31,12 +31,12 @@ type alias Context =
[ NoDuplicateImports.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -14,7 +14,7 @@ module Lint.Rules.NoExposingEverything exposing (rule)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -27,12 +27,12 @@ type alias Context =
[ NoExposingEverything.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -14,7 +14,7 @@ module Lint.Rules.NoImportingEverything exposing (rule)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -28,12 +28,12 @@ functions and types are unknown to them.
[ NoImportingEverything.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -20,7 +20,7 @@ module Lint.Rules.NoNestedLet exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -33,12 +33,12 @@ type alias Context =
[ NoNestedLet.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -17,7 +17,7 @@ module Lint.Rules.NoUnannotatedFunction exposing (rule)
import Ast.Statement exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
import Set exposing (Set)
@ -32,12 +32,12 @@ type alias Context =
[ NoUnannotatedFunction.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -20,7 +20,7 @@ module Lint.Rules.NoUnusedVariables exposing (rule)
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), Error, LintRule)
import Lint.Types exposing (LintRule, Direction(..), Error, LintRuleImplementation)
import Set exposing (Set)
@ -47,12 +47,12 @@ emptyScope =
[ NoUnusedVariables.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -20,7 +20,7 @@ module Lint.Rules.NoUselessIf exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -33,12 +33,12 @@ type alias Context =
[ NoUselessIf.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -31,7 +31,7 @@ module Lint.Rules.NoUselessPatternMatching exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, visitExpression, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
import Regex
import Set exposing (Set)
@ -47,12 +47,12 @@ pattern will lead to the same value as the default pattern.
[ NoUselessPatternMatching.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
@ -62,7 +62,7 @@ implementation =
}
variableFinder : LintRule (Set String)
variableFinder : LintRuleImplementation (Set String)
variableFinder =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -16,7 +16,7 @@ module Lint.Rules.NoWarningComments exposing (rule)
import Ast.Statement exposing (..)
import Lint exposing (doNothing, lint)
import Lint.Types exposing (Direction(..), Error, LintRule)
import Lint.Types exposing (LintRule, Direction(..), Error, LintRuleImplementation)
import Regex exposing (Regex)
@ -30,12 +30,12 @@ type alias Context =
[ NoWarningComments.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -17,7 +17,7 @@ module Lint.Rules.SimplifyPiping exposing (rule)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
import Set exposing (Set)
@ -31,12 +31,12 @@ type alias Context =
[ SimplifyPiping.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing

View File

@ -15,7 +15,7 @@ module Lint.Rules.SimplifyPropertyAccess exposing (rule)
import Ast.Statement exposing (..)
import Ast.Expression exposing (..)
import Lint exposing (lint, doNothing)
import Lint.Types exposing (LintRule, Error, Direction(..))
import Lint.Types exposing (LintRule, LintRuleImplementation, Error, Direction(..))
type alias Context =
@ -28,12 +28,12 @@ type alias Context =
[ SimplifyPropertyAccess.rule
]
-}
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = statementFn
, typeFn = doNothing

View File

@ -1,4 +1,4 @@
module Lint.Types exposing (Error, LintImplementation, Direction(..), LintRule, Visitor)
module Lint.Types exposing (Error, LintImplementation, Direction(..), LintRule, LintRuleImplementation, LintResult, Visitor)
{-| This module contains types that are used for writing rules.
@ -6,14 +6,15 @@ module Lint.Types exposing (Error, LintImplementation, Direction(..), LintRule,
@docs Error, Direction
# Writing rules
@docs LintRule, LintImplementation
@docs LintRuleImplementation, LintImplementation, LintRule
# Internal types
@docs Visitor
@docs Visitor, LintResult
-}
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
import Combine
{-| Value that describes an error found by a given rule, that contains the name of the rule that raised the error, and
@ -38,11 +39,11 @@ the LintImplementation functions of your rule.
It must return a list of errors which will be reported to the user, that are violations of the thing the rule wants to
enforce.
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
@ -78,7 +79,7 @@ type Direction node
| Exit node
{-| A LintRule is the implementation of a rule. It is a record that contains:
{-| A LintRuleImplementation is the implementation of a rule. It is a record that contains:
- initialContext: An initial context
- statementFn: A LintImplementation for Statement nodes
- typeFn: A LintImplementation for Type nodes
@ -86,11 +87,11 @@ type Direction node
- moduleEndFn: A function that takes a context and returns a list of error. Similar to a LintImplementation, but will
be called after visiting the whole AST.
rule : String -> List Error
rule : LintRule
rule input =
lint input implementation
implementation : LintRule Context
implementation : LintRuleImplementation Context
implementation =
{ statementFn = doNothing
, typeFn = doNothing
@ -99,7 +100,7 @@ be called after visiting the whole AST.
, initialContext = Context
}
-}
type alias LintRule context =
type alias LintRuleImplementation context =
{ statementFn : LintImplementation Statement context
, typeFn : LintImplementation Type context
, expressionFn : LintImplementation Expression context
@ -108,10 +109,22 @@ type alias LintRule context =
}
{-| Shortcut to the result of a lint rule
-}
type alias LintResult =
Result (List String) (List Error)
{-| Shortcut to a lint rule
-}
type alias LintRule =
String -> LintResult
{-| Shorthand for a function that takes a rule's implementation, a context and returns ( List Error, context ).
A Visitor represents a node and calls the appropriate function for the given node type.
Note: this is internal API, and will be removed in a future version.
-}
type alias Visitor context =
LintRule context -> context -> ( List Error, context )
LintRuleImplementation context -> context -> ( List Error, context )

View File

@ -2,7 +2,7 @@ module Lint.Visitor exposing (transformStatementsIntoVisitors, expressionToVisit
import Ast.Expression exposing (..)
import Ast.Statement exposing (..)
import Lint.Types exposing (Direction(..), Visitor)
import Lint.Types exposing (LintRule, Direction(..), Visitor)
createExitAndEnterWithChildren : (Direction nodeType -> Visitor context) -> nodeType -> List (Visitor context) -> List (Visitor context)

View File

@ -3,7 +3,7 @@ port module DefaultPatternPositionTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.DefaultPatternPosition exposing (rule, PatternPosition(First, Last))
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module NoConstantConditionTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoConstantCondition exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : Error

View File

@ -3,7 +3,7 @@ port module NoDebugTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoDebug exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module NoDuplicateImportsTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoDuplicateImports exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module NoImportingEverythingTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoImportingEverything exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module NoNestedLetTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoNestedLet exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : Error

View File

@ -4,7 +4,7 @@ import Expect
import Test exposing (describe, test, Test)
import TestUtil exposing (ruleTester)
import Lint.Rules.NoUnannotatedFunction exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -4,7 +4,7 @@ import Expect
import Test exposing (describe, test, Test)
import TestUtil exposing (ruleTester)
import Lint.Rules.NoUnusedVariables exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module NoUselessIfTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoUselessIf exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : Error

View File

@ -3,7 +3,7 @@ port module NoUselessPatternMatchingTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoUselessPatternMatching exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
uselessError : Error

View File

@ -3,7 +3,7 @@ port module NoWarningCommentsTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.NoWarningComments exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -3,7 +3,7 @@ port module SimplifyPipingTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.SimplifyPiping exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> String -> Error

View File

@ -3,7 +3,7 @@ port module SimplifyPropertyAccessTest exposing (all)
import Expect
import Test exposing (describe, test, Test)
import Lint.Rules.SimplifyPropertyAccess exposing (rule)
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
error : String -> Error

View File

@ -1,7 +1,7 @@
module TestUtil exposing (ruleTester)
import Regex
import Lint.Types exposing (Error)
import Lint.Types exposing (LintRule, Error)
spacesRegex : Regex.Regex
@ -9,7 +9,7 @@ spacesRegex =
Regex.regex "\n "
ruleTester : (String -> List Error) -> String -> List Error
ruleTester : (LintRule) -> LintRule
ruleTester rule str =
Regex.replace Regex.All spacesRegex (\_ -> "\n") str
|> rule