Skip to content

Commit

Permalink
Auto qualify types and values if they're used in the same file they'r…
Browse files Browse the repository at this point in the history
…e defined in
  • Loading branch information
mdgriffith committed May 27, 2024
1 parent a792ab4 commit 765b044
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 25 deletions.
16 changes: 10 additions & 6 deletions src/Elm.elm
Original file line number Diff line number Diff line change
Expand Up @@ -398,11 +398,15 @@ value :
value details =
Compiler.Expression <|
\index ->
let
importFrom =
Index.getImport index details.importFrom
in
{ expression =
-- This *must* be an un-protected name, where we only use
-- literally what the dev gives us, because we are trying
-- to refer to something that already exists.
Exp.FunctionOrValue details.importFrom
Exp.FunctionOrValue importFrom
(Format.sanitize details.name)
, annotation =
case details.annotation of
Expand All @@ -423,20 +427,20 @@ value details =
, imports =
case details.annotation of
Nothing ->
case details.importFrom of
case importFrom of
[] ->
[]

_ ->
[ details.importFrom ]
[ importFrom ]

Just ann ->
case details.importFrom of
case importFrom of
[] ->
Compiler.getAnnotationImports ann

_ ->
details.importFrom :: Compiler.getAnnotationImports ann
importFrom :: Compiler.getAnnotationImports ann
}


Expand Down Expand Up @@ -1890,7 +1894,7 @@ declaration nameStr (Compiler.Expression toBody) =
(Compiler.nodify
{ name = Compiler.nodify name
, typeAnnotation =
Compiler.nodify (Clean.clean finalType)
Compiler.nodify (Clean.clean index finalType)
}
)

Expand Down
14 changes: 10 additions & 4 deletions src/Elm/ToString.elm
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,12 @@ expressionWith :
}
expressionWith options (Compiler.Expression toExp) =
let
index =
Index.startIndex Nothing

expresh : Compiler.ExpressionDetails
expresh =
toExp (Index.startIndex Nothing)
toExp index
in
{ imports =
expresh
Expand All @@ -71,7 +74,7 @@ expressionWith options (Compiler.Expression toExp) =
Ok sig ->
case Compiler.resolve (Index.startIndex Nothing) sig.inferences sig.type_ of
Ok finalType ->
Internal.Write.writeAnnotationWith options.aliases (Clean.clean finalType)
Internal.Write.writeAnnotationWith options.aliases (Clean.clean index finalType)

Err errMsg ->
errMsg
Expand Down Expand Up @@ -116,13 +119,16 @@ declarationWith options decl =

Compiler.Declaration { imports, docs, toBody } ->
let
index =
Index.startIndex Nothing

rendered :
{ declaration : Declaration.Declaration
, additionalImports : List Compiler.Module
, warning : Maybe Compiler.Warning
}
rendered =
toBody (Index.startIndex Nothing)
toBody index
in
[ { imports =
imports
Expand All @@ -142,7 +148,7 @@ declarationWith options decl =
Just (Node _ sig) ->
Internal.Write.writeSignatureWith options.aliases
{ name = sig.name
, typeAnnotation = Node.map Clean.clean sig.typeAnnotation
, typeAnnotation = Node.map (Clean.clean index) sig.typeAnnotation
}

_ ->
Expand Down
71 changes: 59 additions & 12 deletions src/Internal/Clean.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,41 @@ module Internal.Clean exposing (clean)

{-| For cleaning up signatures that look like
Html msg_0_1_5
Html msg_0_1_5
to
Html msg
Html msg
Will also adjust qualification of the type based on if this is used in the module it's declared in or not.'
-}

import Dict exposing (Dict)
import Elm.Syntax.ModuleName as ModuleName
import Elm.Syntax.Node as Node
import Elm.Syntax.TypeAnnotation as Type
import Internal.Index as Index
import Set exposing (Set)


{-| -}
clean : Type.TypeAnnotation -> Type.TypeAnnotation
clean ann =
clean : Index.Index -> Type.TypeAnnotation -> Type.TypeAnnotation
clean index ann =
let
renames : Dict String String
renames =
prepareRename ann Set.empty
|> verify

renamed =
if Dict.isEmpty renames && not (Index.hasModuleName index) then
ann

else
doRename index renames ann
in
doRename renames ann
renamed


{-| -}
Expand Down Expand Up @@ -99,8 +110,21 @@ prepareRename ann dict =
|> prepareRename two


doRename : Dict String String -> Type.TypeAnnotation -> Type.TypeAnnotation
doRename dict ann =
{-| Adjust the qualification of this type based on if it's used in the module it's defiend in or not.
-}
adjustQualification :
Index.Index
-> Node.Node ( ModuleName.ModuleName, String )
-> Node.Node ( ModuleName.ModuleName, String )
adjustQualification index (Node.Node range ( modName, name )) =
Node.Node range
( Index.getImport index modName
, name
)


doRename : Index.Index -> Dict String String -> Type.TypeAnnotation -> Type.TypeAnnotation
doRename index dict ann =
case ann of
Type.GenericType generic ->
case Dict.get generic dict of
Expand All @@ -111,19 +135,42 @@ doRename dict ann =
Type.GenericType renamed

Type.Typed name nodedVars ->
Type.Typed name (List.map (Node.map (doRename dict)) nodedVars)
Type.Typed (adjustQualification index name)
(List.map (Node.map (doRename index dict)) nodedVars)

Type.Unit ->
ann

Type.Tupled nodedVars ->
Type.Tupled (List.map (Node.map (doRename dict)) nodedVars)
Type.Tupled (List.map (Node.map (doRename index dict)) nodedVars)

Type.Record record ->
Type.Record (List.map (Node.map (Tuple.mapSecond (Node.map (doRename dict)))) record)
Type.Record
(List.map
(Node.map
(Tuple.mapSecond
(Node.map (doRename index dict))
)
)
record
)

Type.GenericRecord name (Node.Node range record) ->
Type.GenericRecord name (Node.Node range (List.map (Node.map (Tuple.mapSecond (Node.map (doRename dict)))) record))
Type.GenericRecord name
(Node.Node range
(List.map
(Node.map
(Tuple.mapSecond
(Node.map
(doRename index dict)
)
)
)
record
)
)

Type.FunctionTypeAnnotation nodeOne nodeTwo ->
Type.FunctionTypeAnnotation (Node.map (doRename dict) nodeOne) (Node.map (doRename dict) nodeTwo)
Type.FunctionTypeAnnotation
(Node.map (doRename index dict) nodeOne)
(Node.map (doRename index dict) nodeTwo)
5 changes: 2 additions & 3 deletions src/Internal/Compiler.elm
Original file line number Diff line number Diff line change
Expand Up @@ -608,8 +608,6 @@ getInnerInference index (Annotation details) =
-- running protectAnnotation will cause the typechecking to fail :/
-- So, there's a bug to debug
|> protectAnnotation index

--details.annotation
, inferences = Dict.empty
, aliases = details.aliases
}
Expand Down Expand Up @@ -2523,7 +2521,8 @@ protectAnnotation index ann =
(str ++ Index.indexToString index)

Annotation.Typed modName anns ->
Annotation.Typed modName
Annotation.Typed
modName
(List.map (mapNode (protectAnnotation index))
anns
)
Expand Down
27 changes: 27 additions & 0 deletions src/Internal/Index.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module Internal.Index exposing
, next, dive
, getName, indexToString, protectTypeName
, typecheck
, getImport, hasModuleName
)

{-|
Expand All @@ -15,6 +16,8 @@ module Internal.Index exposing
@docs typecheck
@docs getImport, hasModuleName
-}

import Internal.Format as Format
Expand Down Expand Up @@ -42,6 +45,30 @@ type Index
= Index (Maybe ModuleName) Int (List Int) Scope Bool


hasModuleName : Index -> Bool
hasModuleName (Index maybeModName _ _ _ _) =
case maybeModName of
Just _ ->
True

Nothing ->
False


getImport : Index -> List String -> List String
getImport (Index maybeModName _ _ _ _) importedAs =
case maybeModName of
Just modName ->
if modName == importedAs then
[]

else
importedAs

Nothing ->
importedAs


type alias ModuleName =
List String

Expand Down

0 comments on commit 765b044

Please sign in to comment.