Make lintSource always return a list, not a result

This commit is contained in:
Jeroen Engels 2019-07-28 21:16:01 +02:00
parent e1146c634f
commit a845cbd86d
3 changed files with 65 additions and 55 deletions

View File

@ -49,7 +49,7 @@ config model =
type alias Model =
{ sourceCode : String
, lintResult : Result (List String) (List LintError)
, lintErrors : List LintError
, noDebugEnabled : Bool
, noUnusedVariablesEnabled : Bool
, noImportingEverythingEnabled : Bool
@ -81,7 +81,7 @@ g n = n + 1
tmpModel : Model
tmpModel =
{ sourceCode = sourceCode
, lintResult = Result.Ok []
, lintErrors = []
, noDebugEnabled = True
, noUnusedVariablesEnabled = True
, noImportingEverythingEnabled = True
@ -91,7 +91,7 @@ g n = n + 1
, showConfigurationAsText = False
}
in
{ tmpModel | lintResult = lintSource (config tmpModel) sourceCode }
{ tmpModel | lintErrors = lintSource (config tmpModel) { fileName = "", source = sourceCode } }
@ -114,7 +114,7 @@ update action model =
UserEditedSourceCode sourceCode ->
{ model
| sourceCode = sourceCode
, lintResult = lintSource (config model) sourceCode
, lintErrors = lintSource (config model) { fileName = "Source code", source = model.sourceCode }
}
UserToggledNoDebugRule ->
@ -143,7 +143,11 @@ update action model =
rerunLinting : Model -> Model
rerunLinting model =
{ model | lintResult = lintSource (config model) model.sourceCode }
{ model
| lintErrors =
lintSource (config model)
{ fileName = "Source code", source = model.sourceCode }
}
@ -319,23 +323,17 @@ viewCheckbox onClick name checked =
lintErrors : Model -> List Text
lintErrors model =
case model.lintResult of
Err errors ->
errors
|> List.map Text.from
if List.isEmpty model.lintErrors then
[ Text.from "I found no linting errors.\nYou're all good!" ]
Ok errors ->
if List.isEmpty errors then
[ Text.from "I found no linting errors.\nYou're all good!" ]
else
Reporter.formatReport
[ ( { name = "IN SOURCE CODE"
, source = model.sourceCode
}
, errors
)
]
else
Reporter.formatReport
[ ( { name = "Source code"
, source = model.sourceCode
}
, model.lintErrors
)
]
main : Program () Model Msg

View File

@ -24,7 +24,7 @@ like the name of the rule that emitted it and the file name.
-}
type alias LintError =
{ file : Maybe String
{ file : String
, ruleName : String
, message : String
, details : List String
@ -40,26 +40,36 @@ type alias LintError =
, Lint.Rule.NoUnusedVariables.rule
]
result =
errors : List LintError
errors =
lintSource config sourceCode
-}
lintSource : List Rule -> String -> Result (List String) (List LintError)
lintSource config source =
source
|> parseSource
|> Result.map
(\statements ->
config
|> List.concatMap (lintSourceWithRule statements)
|> List.sortWith compareErrorPositions
)
lintSource : List Rule -> { fileName : String, source : String } -> List LintError
lintSource config { fileName, source } =
case parseSource source of
Ok file ->
config
|> List.concatMap (lintSourceWithRule fileName file)
|> List.sortWith compareErrorPositions
Err _ ->
[ { file = fileName
, ruleName = "ParsingError"
, message = fileName ++ " is not a correct Elm file"
, details =
[ "I could not understand the contents of this file, and this prevents me from analyzing it. It's highly likely that the contents of the file is not correct Elm code."
, "Hint: Try running `elm make`. The compiler should give you better hints on how to resolve the problem."
]
, range = { start = { row = 0, column = 0 }, end = { row = 0, column = 0 } }
}
]
lintSourceWithRule : File -> Rule -> List LintError
lintSourceWithRule file rule =
lintSourceWithRule : String -> File -> Rule -> List LintError
lintSourceWithRule fileName file rule =
Rule.analyzer rule file
|> List.map (errorToRuleError Nothing rule)
|> List.map (ruleErrorToLintError fileName rule)
compareErrorPositions : LintError -> LintError -> Order
@ -109,8 +119,8 @@ compareRange a b =
EQ
errorToRuleError : Maybe String -> Rule -> Rule.Error -> LintError
errorToRuleError file rule error =
ruleErrorToLintError : String -> Rule -> Rule.Error -> LintError
ruleErrorToLintError file rule error =
{ file = file
, ruleName = Rule.name rule
, message = Rule.errorMessage error
@ -121,11 +131,9 @@ errorToRuleError file rule error =
{-| Parse source code into a AST
-}
parseSource : String -> Result (List String) File
parseSource : String -> Result String File
parseSource source =
source
|> Parser.parse
-- TODO Improve parsing error handling
|> Result.mapError (\error -> [ "Parsing error" ])
-- TODO Add all files to have more context https://package.elm-lang.org/packages/stil4m/elm-syntax/latest/Elm-Processing
|> Result.mapError (\error -> "Parsing error")
|> Result.map (process init)

View File

@ -135,14 +135,19 @@ You can't just have an expression like `1 + 2`.
-}
run : Rule -> String -> LintResult
run rule sourceCode =
case lintSource [ rule ] sourceCode of
Ok errors ->
SuccessfulRun
{ getCodeAtLocation = getCodeAtLocationInSourceCode sourceCode
, checkIfLocationIsAmbiguous = checkIfLocationIsAmbiguousInSourceCode sourceCode
}
(List.map
run rule source =
let
errors : List Lint.LintError
errors =
lintSource [ rule ] { fileName = "TestContent.elm", source = source }
in
case List.head errors |> Maybe.map .message of
Just "TestContent.elm is not a correct Elm file" ->
ParseFailure
_ ->
errors
|> List.map
(\error_ ->
Rule.error
{ message = error_.message
@ -150,11 +155,10 @@ run rule sourceCode =
}
error_.range
)
errors
)
Err _ ->
ParseFailure
|> SuccessfulRun
{ getCodeAtLocation = getCodeAtLocationInSourceCode source
, checkIfLocationIsAmbiguous = checkIfLocationIsAmbiguousInSourceCode source
}
{-| Assert that the rule reported no errors. Note, this is equivalent to using [`expectErrors`](#expectErrors)