@@ -7,6 +7,7 @@ module Reporting.Error.Import
77 where
88
99
10+import qualified Data.Map as Map
1011import qualified Data.Set as Set
1112
1213import qualified Elm.ModuleName as ModuleName
@@ -14,6 +15,7 @@ import qualified Elm.Package as Pkg
1415import qualified Reporting.Doc as D
1516import qualified Reporting.Render.Code as Code
1617import qualified Reporting.Report as Report
18+import qualified Reporting.Suggest as Suggest
1719import qualified Reporting.Annotation as A
1820
1921
@@ -22,7 +24,12 @@ import qualified Reporting.Annotation as A
2224
2325
2426data Error =
25− Error A.Region ModuleName.Raw (Set.Set ModuleName.Raw) Problem
27+ Error
28+ { _region :: A.Region
29+ , _import :: ModuleName.Raw
30+ , _unimported :: Set.Set ModuleName.Raw
31+ , _problem :: Problem
32+ }
2633
2734
2835data Problem
@@ -37,22 +44,119 @@ data Problem
3744
3845
3946toReport :: Code.Source -> Error -> Report.Report
40−toReport source (Error region name knownModules problem) =
47+toReport source (Error region name unimportedModules problem) =
4148 case problem of
4249 NotFound ->
4350 Report.Report "MODULE NOT FOUND" region [] $
4451 Report.toCodeSnippet source region Nothing
4552 (
46− "You are trying to import a `" <> D.fromName name <> "` module:"
53+ D.reflow $
54+ "You are trying to import a `" ++ ModuleName.toChars name ++ "` module:"
4755 ,
48− error "TODO But I cannot find `Whatever` in your project or packages." knownModules
56+ D.stack
57+ [
58+ D.reflow $
59+ "But I cannot find it! I checked the \"dependencies\" and \"source-directories\"\
60+ \ listend in your elm.json, but the closest module names I could find were:"
61+ ,
62+ D.dullyellow $ D.indent 4 $ D.vcat $
63+ map D.fromName (toSuggestions name unimportedModules)
64+ ,
65+ case Map.lookup name Pkg.suggestions of
66+ Nothing ->
67+ D.toSimpleHint $
68+ "If it is not a typo, check the \"dependencies\" and \"source-directories\"\
69+ \ of your elm.json to make sure all the packages you need are listed there!"
70+
71+ Just dependency ->
72+ D.toFancyHint
73+ ["Maybe","you","want","the"
74+ ,"`" <> D.fromName name <> "`"
75+ ,"module","defined","in","the"
76+ ,D.fromChars (Pkg.toChars dependency)
77+ ,"package?","Running"
78+ ,D.green (D.fromChars ("elm install " ++ Pkg.toChars dependency))
79+ ,"should","make","it","available!"
80+ ]
81+ ]
4982 )
5083
51− Ambiguous path paths pkg pkgs ->
52− error "TODO Ambiguous" path paths pkg pkgs
84+ Ambiguous path _ pkg _ ->
85+ Report.Report "AMBIGUOUS IMPORT" region [] $
86+ Report.toCodeSnippet source region Nothing
87+ (
88+ D.reflow $
89+ "You are trying to import a `" ++ ModuleName.toChars name ++ "` module:"
90+ ,
91+ D.stack
92+ [
93+ D.fillSep $
94+ ["But","I","found","multiple","modules","with","that","name.","One","in","the"
95+ ,D.dullyellow (D.fromChars (Pkg.toChars pkg))
96+ ,"package,","and","another","defined","locally","in","the"
97+ ,D.dullyellow (D.fromChars path)
98+ ,"file.","I","do","not","have","a","way","to","choose","between","them."
99+ ]
100+ ,
101+ D.reflow $
102+ "Try changing the name of the locally defined module to clear up the ambiguity?"
103+ ]
104+ )
53105
54106 AmbiguousLocal path1 path2 paths ->
55− error "TODO AmbiguousLocal" path1 path2 paths
107+ Report.Report "AMBIGUOUS IMPORT" region [] $
108+ Report.toCodeSnippet source region Nothing
109+ (
110+ D.reflow $
111+ "You are trying to import a `" ++ ModuleName.toChars name ++ "` module:"
112+ ,
113+ D.stack
114+ [
115+ D.reflow $
116+ "But I found multiple files in your \"source-directories\" with that name:"
117+ ,
118+ D.dullyellow $ D.indent 4 $ D.vcat $
119+ map D.fromChars (path1:path2:paths)
120+ ,
121+ D.reflow $
122+ "Change the module names to be distinct!"
123+ ]
124+ )
56125
57126 AmbiguousForeign pkg1 pkg2 pkgs ->
58− error "TODO AmbiguousForeign" pkg1 pkg2 pkgs
127+ Report.Report "AMBIGUOUS IMPORT" region [] $
128+ Report.toCodeSnippet source region Nothing
129+ (
130+ D.reflow $
131+ "You are trying to import a `" ++ ModuleName.toChars name ++ "` module:"
132+ ,
133+ D.stack
134+ [
135+ D.reflow $
136+ "But multiple packages in your \"dependencies\" that expose a module that name:"
137+ ,
138+ D.dullyellow $ D.indent 4 $ D.vcat $
139+ map (D.fromChars . Pkg.toChars) (pkg1:pkg2:pkgs)
140+ ,
141+ D.reflow $
142+ "There is no way to disambiguate in cases like this right now. Of the known name\
143+ \ clashes, they are usually for packages with similar purposes, so the current\
144+ \ recommendation is to pick just one of them."
145+ , D.toSimpleNote $
146+ "It seems possible to resolve this with new syntax in imports, but that is\
147+ \ more complicated than it sounds. Right now, our module names are tied to GitHub\
148+ \ repos, but we may want to get rid of that dependency for a variety of reasons.\
149+ \ That would in turn have implications for our package infrastructure, hosting\
150+ \ costs, and possibly on how package names are specified. The particular syntax\
151+ \ chosen seems like it would interact with all these factors in ways that are\
152+ \ difficult to predict, potentially leading to harder problems later on. So more\
153+ \ design work and planning is needed on these topics."
154+ ]
155+ )
156+
157+
158+
159+toSuggestions :: ModuleName.Raw -> Set.Set ModuleName.Raw -> [ModuleName.Raw]
160+toSuggestions name unimportedModules =
161+ take 4 $
162+ Suggest.sort (ModuleName.toChars name) ModuleName.toChars (Set.toList unimportedModules)