Backport work from review packages and elm-review-scope

This commit is contained in:
Jeroen Engels 2020-04-21 23:01:47 +02:00
parent 9ceb964adf
commit 33c85462ed
3 changed files with 106 additions and 6 deletions

View File

@ -95,6 +95,7 @@ all =
[ functionsAndValuesTests [ functionsAndValuesTests
, typesTests , typesTests
, typeAliasesTests , typeAliasesTests
, duplicateModuleNameTests
-- TODO Add tests that report exposing the type's variants if they are never used. -- TODO Add tests that report exposing the type's variants if they are never used.
] ]
@ -592,3 +593,22 @@ type alias B = A.OtherType
) )
] ]
] ]
duplicateModuleNameTests : Test
duplicateModuleNameTests =
describe "Duplicate module names"
[ test "should not report a used export even if it is imported through a module whose name appears twice" <|
\() ->
[ """module Main exposing (main)
import A as X
import B as X
main = X.a X.b
""", """module A exposing (a)
a = 1
""", """module B exposing (b)
b = 2
""" ]
|> Review.Test.runOnModulesWithProjectData application rule
|> Review.Test.expectNoErrors
]

View File

@ -86,7 +86,7 @@ type ModuleContext
type alias InnerModuleContext = type alias InnerModuleContext =
{ scopes : Nonempty Scope { scopes : Nonempty Scope
, importAliases : Dict String (List String) , importAliases : Dict String (List ModuleName)
, importedFunctionOrTypes : Dict String (List String) , importedFunctionOrTypes : Dict String (List String)
, dependenciesModules : Dict String Elm.Docs.Module , dependenciesModules : Dict String Elm.Docs.Module
, modules : Dict ModuleName Elm.Docs.Module , modules : Dict ModuleName Elm.Docs.Module
@ -813,9 +813,9 @@ registerImportAlias import_ innerContext =
Just alias_ -> Just alias_ ->
{ innerContext { innerContext
| importAliases = | importAliases =
Dict.insert Dict.update
(Node.value alias_ |> getModuleName) (Node.value alias_ |> getModuleName)
(Node.value import_.moduleName) (\previousValue -> Just <| Node.value import_.moduleName :: Maybe.withDefault [] previousValue)
innerContext.importAliases innerContext.importAliases
} }
@ -1173,13 +1173,49 @@ realModuleName (ModuleContext context) functionOrType moduleName =
|> Maybe.withDefault [] |> Maybe.withDefault []
else if List.length moduleName == 1 then else if List.length moduleName == 1 then
Dict.get (getModuleName moduleName) context.importAliases case Dict.get (getModuleName moduleName) context.importAliases of
Just [ aliasedModuleName ] ->
aliasedModuleName
Just aliases ->
case
findInList
(\aliasedModuleName ->
case Dict.get aliasedModuleName context.modules of
Just module_ ->
isDeclaredInModule functionOrType module_
Nothing ->
False
)
aliases
of
Just aliasedModuleName ->
aliasedModuleName
Nothing ->
List.head aliases
|> Maybe.withDefault moduleName |> Maybe.withDefault moduleName
Nothing ->
moduleName
else else
moduleName moduleName
isDeclaredInModule : String -> Elm.Docs.Module -> Bool
isDeclaredInModule functionOrType module_ =
List.any (.name >> (==) functionOrType) module_.values
|| List.any (.name >> (==) functionOrType) module_.aliases
|| List.any
(\union ->
(union.name == functionOrType)
|| List.any (Tuple.first >> (==) functionOrType) union.tags
)
module_.unions
isInScope : String -> Nonempty Scope -> Bool isInScope : String -> Nonempty Scope -> Bool
isInScope name scopes = isInScope name scopes =
nonemptyList_any (.names >> Dict.member name) scopes nonemptyList_any (.names >> Dict.member name) scopes

View File

@ -7,8 +7,8 @@ import Elm.Syntax.TypeAnnotation as TypeAnnotation exposing (TypeAnnotation)
import Fixtures.Dependencies as Dependencies import Fixtures.Dependencies as Dependencies
import Review.Project as Project exposing (Project) import Review.Project as Project exposing (Project)
import Review.Rule as Rule exposing (Error, Rule) import Review.Rule as Rule exposing (Error, Rule)
import Review.Scope as Scope
import Review.Test import Review.Test
import Scope
import Test exposing (Test, test) import Test exposing (Test, test)
@ -96,11 +96,23 @@ import ExposesEverything exposing (..)
import Foo.Bar import Foo.Bar
import Html exposing (..) import Html exposing (..)
import Http exposing (get) import Http exposing (get)
import Something.B as Something
import Something.C as Something
localValue = 1 localValue = 1
localValueValueToBeShadowed = 1
type Msg = SomeMsgToBeShadowed
a : SomeCustomType -> SomeTypeAlias -> SomeOtherTypeAlias -> NonExposedCustomType a : SomeCustomType -> SomeTypeAlias -> SomeOtherTypeAlias -> NonExposedCustomType
a = localValue a = localValue
localValueValueToBeShadowed
SomeMsgToBeShadowed
SomeOtherMsg
Something.b
Something.c
Something.BAlias
Something.Foo
Something.Bar
unknownValue unknownValue
exposedElement exposedElement
nonExposedElement nonExposedElement
@ -124,7 +136,15 @@ nonExposedElement = 2
""", """module ExposesEverything exposing (..) """, """module ExposesEverything exposing (..)
type SomeCustomType = VariantA | VariantB type SomeCustomType = VariantA | VariantB
type alias SomeTypeAlias = {} type alias SomeTypeAlias = {}
type Msg = SomeMsgToBeShadowed | SomeOtherMsg
elementFromExposesEverything = 1 elementFromExposesEverything = 1
localValueValueToBeShadowed = 1
""", """module Something.B exposing (..)
b = 1
type Foo = Bar
type alias BAlias = {}
""", """module Something.C exposing (..)
c = 1
""" ] """ ]
|> Review.Test.runOnModulesWithProjectData project projectRule |> Review.Test.runOnModulesWithProjectData project projectRule
|> Review.Test.expectErrorsForModules |> Review.Test.expectErrorsForModules
@ -136,6 +156,14 @@ elementFromExposesEverything = 1
<nothing>.SomeOtherTypeAlias -> ExposesSomeThings.SomeOtherTypeAlias <nothing>.SomeOtherTypeAlias -> ExposesSomeThings.SomeOtherTypeAlias
<nothing>.NonExposedCustomType -> <nothing>.NonExposedCustomType <nothing>.NonExposedCustomType -> <nothing>.NonExposedCustomType
<nothing>.localValue -> <nothing>.localValue <nothing>.localValue -> <nothing>.localValue
<nothing>.localValueValueToBeShadowed -> <nothing>.localValueValueToBeShadowed
<nothing>.SomeMsgToBeShadowed -> <nothing>.SomeMsgToBeShadowed
<nothing>.SomeOtherMsg -> ExposesEverything.SomeOtherMsg
Something.b -> Something.B.b
Something.c -> Something.C.c
Something.BAlias -> Something.B.BAlias
Something.Foo -> Something.B.Foo
Something.Bar -> Something.B.Bar
<nothing>.unknownValue -> <nothing>.unknownValue <nothing>.unknownValue -> <nothing>.unknownValue
<nothing>.exposedElement -> ExposesSomeThings.exposedElement <nothing>.exposedElement -> ExposesSomeThings.exposedElement
<nothing>.nonExposedElement -> <nothing>.nonExposedElement <nothing>.nonExposedElement -> <nothing>.nonExposedElement
@ -172,6 +200,22 @@ Http.get -> Http.get
} }
] ]
) )
, ( "Something.B"
, [ Review.Test.error
{ message = ""
, details = [ "details" ]
, under = "module"
}
]
)
, ( "Something.C"
, [ Review.Test.error
{ message = ""
, details = [ "details" ]
, under = "module"
}
]
)
] ]
] ]