Skip to content

Commit

Permalink
Don't report a custom type if a constructor is used locally
Browse files Browse the repository at this point in the history
  • Loading branch information
jfmengels committed Apr 1, 2024
1 parent 170a5a7 commit 45566cc
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 7 deletions.
49 changes: 43 additions & 6 deletions src/NoUnused/Exports.elm
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ type alias ModuleContext =
, containsMainFunction : Bool
, projectType : ProjectType
, isExposingAll : Bool
, constructorNameToTypeName : Dict String String
}


Expand Down Expand Up @@ -569,6 +570,7 @@ fromProjectToModule =
, elementsNotToReport = Set.empty
, ignoredElementsNotToReport = Set.empty
, importedModules = Set.empty
, constructorNameToTypeName = createConstructorNameToTypeNameDict exposingList ast.declarations
, containsMainFunction = False
, projectType = projectContext.projectType
, isExposingAll = isExposingAll
Expand All @@ -579,6 +581,36 @@ fromProjectToModule =
|> Rule.withModuleDocumentation


createConstructorNameToTypeNameDict : Exposing -> List (Node Declaration) -> Dict String String
createConstructorNameToTypeNameDict exposingList declarations =
case exposingList of
Exposing.All _ ->
List.foldl
(\node acc ->
case Node.value node of
Declaration.CustomTypeDeclaration customType ->
let
typeName : String
typeName =
Node.value customType.name
in
List.foldl
(\(Node _ { name }) subAcc ->
Dict.insert (Node.value name) typeName subAcc
)
acc
customType.constructors

_ ->
acc
)
Dict.empty
declarations

Exposing.Explicit _ ->
Dict.empty


declarationToTopLevelExpose : Declaration -> Maybe (Node TopLevelExpose)
declarationToTopLevelExpose declaration =
case declaration of
Expand Down Expand Up @@ -1632,14 +1664,19 @@ registerLocalValue : Range -> String -> ModuleContext -> ModuleContext
registerLocalValue range name moduleContext =
case ModuleNameLookupTable.moduleNameAt moduleContext.lookupTable range of
Just [] ->
if moduleContext.isExposingAll then
{ moduleContext | exposed = Dict.remove name moduleContext.exposed }
case Dict.get name moduleContext.constructorNameToTypeName of
Just typeName ->
{ moduleContext | exposed = Dict.remove typeName moduleContext.exposed }

else if Dict.member name moduleContext.exposed then
{ moduleContext | ignoredElementsNotToReport = Set.insert name moduleContext.ignoredElementsNotToReport }
Nothing ->
if moduleContext.isExposingAll then
{ moduleContext | exposed = Dict.remove name moduleContext.exposed }

else
moduleContext
else if Dict.member name moduleContext.exposed then
{ moduleContext | ignoredElementsNotToReport = Set.insert name moduleContext.ignoredElementsNotToReport }

else
moduleContext

Just moduleName ->
registerAsUsed ( String.join "." moduleName, name ) moduleContext
Expand Down
31 changes: 30 additions & 1 deletion tests/NoUnused/ExportsTest.elm
Original file line number Diff line number Diff line change
Expand Up @@ -1750,7 +1750,36 @@ external = InternalC
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should not report a port that's used internally" <|
, test "should not report a custom type whose constructor is used" <|
\() ->
[ """
module Main exposing (main)
import NotReported
main = NotReported.Constructor
"""
, """
module NotReported exposing (..)
type Type = Constructor
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "should not report a custom type whose constructor is used internally" <|
\() ->
[ """
module Main exposing (main)
import NotReported
main = NotReported.external
"""
, """
module NotReported exposing (..)
external = Constructor
type Type = Constructor
"""
]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
, test "does not report a port that's used internally" <|
\() ->
[ """
module Main exposing (main)
Expand Down

0 comments on commit 45566cc

Please sign in to comment.