Skip to content

Commit

Permalink
NoUnused.Exports: Fixed types being incorrectly reported
Browse files Browse the repository at this point in the history
  • Loading branch information
jfmengels committed Apr 2, 2024
1 parent ff06235 commit e83096e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## [Unreleased]

Fixed issues in [`NoUnused.Exports`] where type aliases and custom types would incorrectly be reported. Thanks Eric from the Elm Slack for reporting!

## [1.2.1] - 2024-04-01

- [`NoUnused.Exports`] now reports (and removes using `--fix`) elements even if the module is exposing everything (`module X exposing (..)`) if the element is unused both locally and across the project. Thanks [@tfausak](https://github.com/tfausak).
Expand Down
33 changes: 25 additions & 8 deletions src/NoUnused/Exports.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,12 @@ expressionVisitor node moduleContext =
[]
declarations
in
{ moduleContext | used = List.foldl Set.insert moduleContext.used used }
List.foldl
(\( moduleName, name ) ctx ->
registerLocalValueWithRealModuleName moduleName name ctx
)
moduleContext
used

Expression.CaseExpression { cases } ->
let
Expand All @@ -1666,7 +1671,12 @@ expressionVisitor node moduleContext =
(List.map Tuple.first cases)
[]
in
{ moduleContext | used = List.foldl Set.insert moduleContext.used usedConstructors }
List.foldl
(\( moduleName, name ) ctx ->
registerLocalValueWithRealModuleName moduleName name ctx
)
moduleContext
usedConstructors

_ ->
moduleContext
Expand All @@ -1675,7 +1685,17 @@ expressionVisitor node moduleContext =
registerLocalValue : Range -> String -> ModuleContext -> ModuleContext
registerLocalValue range name moduleContext =
case ModuleNameLookupTable.moduleNameAt moduleContext.lookupTable range of
Just [] ->
Just moduleName ->
registerLocalValueWithRealModuleName (String.join "." moduleName) name moduleContext

Nothing ->
moduleContext


registerLocalValueWithRealModuleName : String -> String -> ModuleContext -> ModuleContext
registerLocalValueWithRealModuleName realModuleName name moduleContext =
case realModuleName of
"" ->
case Dict.get name moduleContext.constructorNameToTypeName of
Just typeName ->
{ moduleContext | exposed = Dict.remove typeName moduleContext.exposed }
Expand All @@ -1693,11 +1713,8 @@ registerLocalValue range name moduleContext =
else
moduleContext

Just moduleName ->
registerAsUsed ( String.join "." moduleName, name ) moduleContext

Nothing ->
moduleContext
moduleName ->
registerAsUsed ( moduleName, name ) moduleContext


findUsedConstructors : ModuleNameLookupTable -> List (Node Pattern) -> List ( ModuleNameStr, String ) -> List ( ModuleNameStr, String )
Expand Down
72 changes: 72 additions & 0 deletions tests/NoUnused/ExportsTest.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1877,6 +1877,78 @@ main = NotReported.used
, """
port module NotReported exposing (..)
port used : ()
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should not remove a type alias used in a local let binding type annotation" <|
\() ->
[ """
module Main exposing (main)
import Tertiary
main = Tertiary.func 1 2
"""
, """
module Tertiary exposing (..)
type alias Tertiary = {}
func : Int -> Int -> Int
func a b =
let
perhapsTertiary : Int -> Maybe Tertiary
perhapsTertiary a =
if a > 5 then
Just {}
else
Nothing
in
case perhapsTertiary 4 of
Just _ ->
a + b
Nothing ->
a - 4
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should not remove a type used in a local let destructuring" <|
\() ->
[ """
module Main exposing (main)
import Tertiary
main = Tertiary.func 1
"""
, """
module Tertiary exposing (..)
type Wrapper = WrapperConstructor Int
func foo =
let
(WrapperConstructor int) = foo
in
int
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should not custom type that is being pattern matched on locally" <|
\() ->
[ """
module Main exposing (main)
import Tertiary
main = Tertiary.func foo
"""
, """
module Tertiary exposing (..)
type Used = X
func foo =
case foo of
X -> 1
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
Expand Down

0 comments on commit e83096e

Please sign in to comment.