This commit is contained in:
Jeroen Engels 2018-11-26 18:39:46 +01:00
parent 245b22455d
commit 7689d01304
2 changed files with 53 additions and 21 deletions

View File

@ -49,8 +49,15 @@ rule input =
lint input implementation
type Value
= Variable
| ImportedModule
| ModuleAlias
| Type
type alias Scope =
{ declared : Dict String Range
{ declared : Dict String ( Value, Range )
, used : Set String
}
@ -66,9 +73,28 @@ emptyScope =
Scope Dict.empty Set.empty
error : Range -> String -> Error
error range_ name =
Error "NoUnusedVariables" ("Variable `" ++ name ++ "` is not used") range_
error : Value -> Range -> String -> Error
error variableType range_ name =
Error
"NoUnusedVariables"
(variableTypeToString variableType ++ " `" ++ name ++ "` is not used")
range_
variableTypeToString : Value -> String
variableTypeToString value =
case value of
Variable ->
"Variable"
ImportedModule ->
"Imported module"
ModuleAlias ->
"Module alias"
Type ->
"Type"
initialContext : Context
@ -134,11 +160,17 @@ visitImport ctx node =
case Maybe.map value exposed of
Nothing ->
let
moduleName =
Maybe.withDefault (value node |> .moduleName) (value node |> .moduleAlias)
( variableType, moduleName ) =
case value node |> .moduleAlias of
Just moduleAlias ->
( ModuleAlias, moduleAlias )
Nothing ->
( ImportedModule, value node |> .moduleName )
in
( []
, register
variableType
(range moduleName)
(value moduleName |> getModuleName)
ctx
@ -147,7 +179,7 @@ visitImport ctx node =
Just declaredImports ->
( []
, List.foldl
(\( range, name ) context -> register range name context)
(\( range, name ) context -> register Variable range name context)
ctx
(collectFromExposing declaredImports)
)
@ -216,16 +248,16 @@ visitDeclaration ctx direction node =
newContext =
ctx
|> register (range declaration.name) (value declaration.name)
|> register Variable (range declaration.name) (value declaration.name)
|> markAllAsUsed namesUsedInSignature
in
( [], newContext )
( Enter, CustomTypeDeclaration { name } ) ->
( [], register (range name) (value name) ctx )
( [], register Type (range name) (value name) ctx )
( Enter, AliasDeclaration { name } ) ->
( [], register (range name) (value name) ctx )
( [], register Type (range name) (value name) ctx )
_ ->
( [], ctx )
@ -253,7 +285,7 @@ registerFunction function ctx =
declaration =
value function.declaration
in
register (range declaration.name) (value declaration.name) ctx
register Variable (range declaration.name) (value declaration.name) ctx
collectFromExposing : Exposing -> List ( Range, String )
@ -316,13 +348,13 @@ collectNamesFromTypeAnnotation node =
[]
register : Range -> String -> Context -> Context
register range name ctx =
register : Value -> Range -> String -> Context -> Context
register variableType range name ctx =
let
scopes =
mapNonemptyHead
(\scope ->
{ scope | declared = Dict.insert name range scope.declared }
{ scope | declared = Dict.insert name ( variableType, range ) scope.declared }
)
ctx.scopes
in
@ -362,7 +394,7 @@ makeReport { declared, used } =
errors =
Dict.filter (\key _ -> not <| Set.member key used) declared
|> Dict.toList
|> List.map (\( key, range ) -> error range key)
|> List.map (\( key, ( variableType, range ) ) -> error variableType range key)
in
( errors, nonUsedVars )

View File

@ -179,12 +179,12 @@ a = case thing of
\() ->
testRule """module A exposing (a)
type A = B | C"""
|> expectErrors [ error "Variable `A` is not used" (location 2 6 7) ]
|> expectErrors [ error "Type `A` is not used" (location 2 6 7) ]
, test "should report unused type aliases declarations" <|
\() ->
testRule """module A exposing (a)
type alias A = { a : B }"""
|> expectErrors [ error "Variable `A` is not used" (location 2 12 13) ]
|> expectErrors [ error "Type `A` is not used" (location 2 12 13) ]
, test "should not report type used in a signature" <|
\() ->
testRule """module A exposing (a)
@ -271,7 +271,7 @@ a = (</>) 2"""
\() ->
testRule """module A exposing (a)
type A = A Int"""
|> expectErrors [ error "Variable `A` is not used" (location 2 6 7) ]
|> expectErrors [ error "Type `A` is not used" (location 2 6 7) ]
, test "should not report used opaque types" <|
\() ->
testRule """module A exposing (a)
@ -283,12 +283,12 @@ a = 1"""
\() ->
testRule """module A exposing (a)
import Html"""
|> expectErrors [ error "Variable `Html` is not used" (location 2 8 12) ]
|> expectErrors [ error "Imported module `Html` is not used" (location 2 8 12) ]
, test "should report unused import (multiples segments)" <|
\() ->
testRule """module A exposing (a)
import Html.Styled.Attributes"""
|> expectErrors [ error "Variable `Html.Styled.Attributes` is not used" (location 2 8 30) ]
|> expectErrors [ error "Imported module `Html.Styled.Attributes` is not used" (location 2 8 30) ]
, test "should not report import if it exposes all (should be improved by detecting if any exposed value is used)" <|
\() ->
testRule """module A exposing (a)
@ -316,7 +316,7 @@ a = Html.href"""
\() ->
testRule """module A exposing (a)
import Html.Styled.Attributes as Html"""
|> expectErrors [ error "Variable `Html` is not used" (location 2 34 38) ]
|> expectErrors [ error "Module alias `Html` is not used" (location 2 34 38) ]
, test "should not report import that exposes a used exposed type" <|
\() ->
testRule """module A exposing (a)