diff --git a/counter/src/Frontend.elm b/counter/src/Frontend.elm index df38157..c2da1ff 100644 --- a/counter/src/Frontend.elm +++ b/counter/src/Frontend.elm @@ -1,5 +1,6 @@ module Frontend exposing (Model, app) +import Foo.Bar as FB exposing (a, b, c) import Html exposing (Html, text) import Html.Attributes exposing (style) import Html.Events exposing (onClick) diff --git a/preview/src/ReviewConfig.elm b/preview/src/ReviewConfig.elm index 18379b1..ead3195 100644 --- a/preview/src/ReviewConfig.elm +++ b/preview/src/ReviewConfig.elm @@ -31,7 +31,10 @@ config = -- |> Install.ClauseInCase.makeRule --, Install.Function.init [ "Frontend" ] "view" viewFunction |> Install.Function.makeRule -- - Install.Import.makeRule "Frontend" "Foo.Bar" "add: import module Foo." + Install.Import.init "Frontend" "Foo.Bar" + |> Install.Import.withAlias "FB" + |> Install.Import.withExposedValues ["a", "b", "c"] + |> Install.Import.makeRule ] diff --git a/src/Install/Import.elm b/src/Install/Import.elm index 16d65b3..3660982 100644 --- a/src/Install/Import.elm +++ b/src/Install/Import.elm @@ -9,29 +9,53 @@ import Review.Rule as Rule exposing (Error, Rule) import Set exposing (Set) +type alias Config = + { hostModuleName : List String + , importedModuleName : List String + , customErrorMessage : CustomError + , importedModuleAlias : Maybe String + , exposedValues : Maybe (List String) + } + + {-| Custom error message to be displayed when running `elm-review --fix` or `elm-review --fix-all` -} type CustomError = CustomError { message : String, details : List String } +{-| Initialize the configuration for the rule. +-} +init : String -> String -> Config +init hostModuleName_ importedModuleName_ = + { hostModuleName = String.split "." hostModuleName_ + , importedModuleName = String.split "." importedModuleName_ + , customErrorMessage = CustomError { message = "Install module " ++ importedModuleName_ ++ " in " ++ importedModuleName_, details = [ "" ] } + , importedModuleAlias = Nothing + , exposedValues = Nothing + } + + +withAlias : String -> Config -> Config +withAlias alias config = + { config | importedModuleAlias = Just alias } + + +withExposedValues : List String -> Config -> Config +withExposedValues exposedValues config = + { config | exposedValues = Just exposedValues } + + {-| Create a rule that adds an import for a given module in a given module. For example: Install.Import.makeRule "Frontend" "Foo.Bar" "add: import module Foo." -} -makeRule : String -> String -> String -> Rule -makeRule hostModuleName importedModuleName customErrorMessage = - let - hostModuleNameList = - String.split "." hostModuleName - - importedModuleNameList = - String.split "." importedModuleName - in +makeRule : Config -> Rule +makeRule config = Rule.newModuleRuleSchemaUsingContextCreator "Install.Import" initialContext - |> Rule.withImportVisitor (importVisitor hostModuleNameList importedModuleNameList) - |> Rule.withFinalModuleEvaluation (finalEvaluation hostModuleNameList importedModuleNameList) + |> Rule.withImportVisitor (importVisitor config) + |> Rule.withFinalModuleEvaluation (finalEvaluation config) |> Rule.providesFixesForModuleRule |> Rule.fromModuleRuleSchema @@ -50,34 +74,57 @@ initialContext = |> Rule.withModuleName -importVisitor : List String -> List String -> Node Import -> Context -> ( List (Error {}), Context ) -importVisitor hostModuleNameList importedModuleNameList node context = +importVisitor : Config -> Node Import -> Context -> ( List (Error {}), Context ) +importVisitor config node context = case Node.value node |> .moduleName |> Node.value of currentModuleName -> - if currentModuleName == importedModuleNameList && hostModuleNameList == context.moduleName then + if currentModuleName == config.importedModuleName && config.hostModuleName == context.moduleName then ( [], { context | moduleWasImported = True, lastNodeRange = Node.range node } ) else ( [], { context | lastNodeRange = Node.range node } ) -finalEvaluation : List String -> List String -> Context -> List (Rule.Error {}) -finalEvaluation hostModuleNameList moduleToImport context = - let - _ = - Debug.log "CONTEXT" context - in - if context.moduleWasImported == False && hostModuleNameList == context.moduleName then - fixError moduleToImport context +finalEvaluation : Config -> Context -> List (Rule.Error {}) +finalEvaluation config context = + if context.moduleWasImported == False && config.hostModuleName == context.moduleName then + fixError config context else [] -fixError : List String -> Context -> List (Error {}) -fixError moduleToImport context = +fixError : Config -> Context -> List (Error {}) +fixError config context = + let + importText = + "import " + ++ String.join "." config.importedModuleName + ++ " " + |> addAlias config.importedModuleAlias + |> addExposing config.exposedValues + |> Debug.log "importText" + + addAlias : Maybe String -> String -> String + addAlias mAlias str = + case mAlias of + Nothing -> + str + + Just alias -> + str ++ " as " ++ alias + + addExposing : Maybe (List String) -> String -> String + addExposing mExposedValues str = + case mExposedValues of + Nothing -> + str + + Just exposedValues -> + str ++ " exposing (" ++ String.join ", " exposedValues ++ ")" + in [ Rule.errorWithFix - { message = "moduleToImport: \"" ++ String.join "." moduleToImport ++ "\"", details = [ "" ] } + { message = "moduleToImport: \"" ++ String.join "." config.importedModuleName ++ "\"", details = [ "" ] } context.lastNodeRange - [ Fix.insertAt { row = context.lastNodeRange.end.row + 1, column = context.lastNodeRange.end.column } ("import " ++ String.join "." moduleToImport) ] + [ Fix.insertAt { row = context.lastNodeRange.end.row + 1, column = context.lastNodeRange.end.column } importText ] ]