@@ -2,9 +2,6 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Reporting.Error.Canonicalize where
3module Reporting.Error.Canonicalize where
5−--import Data.Aeson ((.=))
6−import qualified Data.Aeson as Json
7−--import qualified Data.Aeson.Types as Json
8import Data.Function (on)
5import Data.Function (on)
9import qualified Data.List as List
6import qualified Data.List as List
10import qualified Text.EditDistance as Dist
7import qualified Text.EditDistance as Dist
@@ -15,7 +12,8 @@ import qualified AST.Type as Type
15import qualified AST.Variable as Var
12import qualified AST.Variable as Var
16import Elm.Utils ((|>))
13import Elm.Utils ((|>))
17import qualified Reporting.PrettyPrint as P
14import qualified Reporting.PrettyPrint as P
18−import qualified Reporting.Region as R
15+import qualified Reporting.Region as Region
16+import qualified Reporting.Report as Report
@@ -82,7 +80,7 @@ valueNotFound name value possibilities =
82data AliasError
80data AliasError
83 = ArgMismatch Var.Canonical Int Int
81 = ArgMismatch Var.Canonical Int Int
84 | SelfRecursive String [String] Type.Raw
82 | SelfRecursive String [String] Type.Raw
85− | MutuallyRecursive [(R.Region, String, [String], Type.Raw)]
83+ | MutuallyRecursive [(Region.Region, String, [String], Type.Raw)]
88alias :: Var.Canonical -> Int -> Int -> Error
86alias :: Var.Canonical -> Int -> Int -> Error
@@ -131,126 +129,126 @@ distance x y =
131 Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
129 Dist.restrictedDamerauLevenshteinDistance Dist.defaultEditCosts x y
134−-- TO STRING
132+-- TO REPORT
136−toString :: R.Region -> Error -> String
134+toReport :: Error -> Report.Report
137−toString region err =
135+toReport err =
139− _ -> error "Canonicalize.toString" region
144−toJson :: Error -> Json.Value
147− _ -> error "Canonicalize.toJson"
152−toHint :: Error -> String
154 case err of
136 case err of
155 Var (VarError kind name problem suggestions) ->
137 Var (VarError kind name problem suggestions) ->
156− let var = kind ++ "'" ++ name ++ "'"
138+ let var = kind ++ " '" ++ name ++ "'"
158 case problem of
140 case problem of
159 Ambiguous ->
141 Ambiguous ->
160− "This usage of " ++ var ++ " is ambiguous"
143+ ("This usage of " ++ var ++ " is ambiguous.")
161− ++ maybeYouWant "\n\n" suggestions
144+ (maybeYouWant suggestions)
163 UnknownQualifier qualifier ->
146 UnknownQualifier qualifier ->
164− "Cannot find " ++ var ++ "\n\n"
147+ Report.simple
165− ++ "The qualifier " ++ qualifier ++ " is not in scope."
148+ ("Cannot find " ++ var ++ ", qualifier '" ++ qualifier ++ "' is not in scope.")
166− ++ maybeYouWant "\n" suggestions
149+ (maybeYouWant suggestions)
168 QualifiedUnknown qualifier ->
151 QualifiedUnknown qualifier ->
169− "Cannot find " ++ var ++ "\n\n"
152+ Report.simple
170− ++ "The module called " ++ qualifier ++ " does not expose that value."
153+ ("Cannot find " ++ var ++ ", module '" ++ qualifier ++ "'' does not expose that value.")
171− ++ maybeYouWant "\n" suggestions
154+ (maybeYouWant suggestions)
173 ExposedUnknown ->
156 ExposedUnknown ->
174− "Cannot find " ++ var
158+ ("Cannot find " ++ var)
175− ++ maybeYouWant "\n\n" suggestions
159+ (maybeYouWant suggestions)
177 Pattern patternError ->
161 Pattern patternError ->
178 case patternError of
162 case patternError of
179 PatternArgMismatch var expected actual ->
163 PatternArgMismatch var expected actual ->
180− argMismatchHint "pattern" var expected actual
164+ argMismatchReport "Pattern" var expected actual
182 Alias aliasError ->
166 Alias aliasError ->
183 case aliasError of
167 case aliasError of
184 ArgMismatch var expected actual ->
168 ArgMismatch var expected actual ->
185− argMismatchHint "type" var expected actual
169+ argMismatchReport "Type" var expected actual
187 SelfRecursive name tvars tipe ->
171 SelfRecursive name tvars tipe ->
188− "This type alias is recursive, forming an infinite type!\n\n"
172+ Report.simple "This type alias is recursive, forming an infinite type!" $
189− ++ "Type aliases are just names for more fundamental types, so I go through\n"
173+ "Type aliases are just names for more fundamental types, so I go through\n"
190− ++ "and expand them all to know the real underlying type. The problem is that\n"
174+ ++ "and expand them all to know the real underlying type. The problem is that\n"
191− ++ "when I expand a recursive type alias, it keeps getting bigger and bigger.\n"
175+ ++ "when I expand a recursive type alias, it keeps getting bigger and bigger.\n"
192− ++ "Dealiasing results in an infinitely large type! Try this instead:\n\n"
176+ ++ "Dealiasing results in an infinitely large type! Try this instead:\n\n"
193− ++ " type " ++ name ++ concatMap (' ':) tvars ++ " ="
177+ ++ " type " ++ name ++ concatMap (' ':) tvars ++ " ="
194− ++ P.render (P.nest 8 (P.hang (P.text name) 2 (P.pretty True tipe)))
178+ ++ P.render (P.nest 8 (P.hang (P.text name) 2 (P.pretty True tipe)))
195− ++ "\n\nThis creates a brand new type that cannot be expanded. It is similar types\n"
179+ ++ "\n\nThis creates a brand new type that cannot be expanded. It is similar types\n"
196− ++ "like List which are recursive, but do not get expanded into infinite types."
180+ ++ "like List which are recursive, but do not get expanded into infinite types."
198 MutuallyRecursive aliases ->
182 MutuallyRecursive aliases ->
199− "This type alias is part of a mutually recursive set of type aliases.\n"
183+ Report.simple "This type alias is part of a mutually recursive set of type aliases." $
200− ++ "The following type aliases all depend on each other in some way:\n"
184+ "The following type aliases all depend on each other in some way:\n"
201− ++ concatMap showName aliases ++ "\n\n"
185+ ++ concatMap showName aliases ++ "\n\n"
202− ++ "The problem is that when you try to expand any of these type aliases, they\n"
186+ ++ "The problem is that when you try to expand any of these type aliases, they\n"
203− ++ "expand infinitely! To fix, first try to centralize them into one alias."
187+ ++ "expand infinitely! To fix, first try to centralize them into one alias."
205− showName (R.Region start _, name, _, _) =
189+ showName (Region.Region start _, name, _, _) =
206 "\n " ++ name ++ replicate (65 - length name) ' '
190 "\n " ++ name ++ replicate (65 - length name) ' '
207− ++ "line " ++ show (R.line start)
191+ ++ "line " ++ show (Region.line start)
209 Import name importError ->
193 Import name importError ->
194+ let moduleName = Module.nameToString name
210 case importError of
196 case importError of
211 ModuleNotFound suggestions ->
197 ModuleNotFound suggestions ->
212− "Could not find a module named '" ++ Module.nameToString name ++ "'"
199+ ("Could not find a module named '" ++ moduleName ++ "'")
213− ++ maybeYouWant "\n\n" (map Module.nameToString suggestions)
200+ (maybeYouWant (map Module.nameToString suggestions))
215 ValueNotFound value suggestions ->
202 ValueNotFound value suggestions ->
216− "Module '" ++ Module.nameToString name ++ "' does not expose '" ++ value ++ "'"
204+ ("Module '" ++ moduleName ++ "' does not expose '" ++ value ++ "'")
217− ++ maybeYouWant "\n\n" suggestions
205+ (maybeYouWant suggestions)
219 Export name suggestions ->
207 Export name suggestions ->
220− "Could not export '" ++ name ++ "'\n\n"
208+ Report.simple
221− ++ "It is not defined in this module."
209+ ("Could not export '" ++ name ++ "' which is not defined in this module.")
222− ++ maybeYouWant " " suggestions
210+ (maybeYouWant suggestions)
224 Port (PortError name isInbound _rootType localType maybeMessage) ->
212 Port (PortError name isInbound _rootType localType maybeMessage) ->
215+ if isInbound then "inbound port" else "outbound port"
218+ "Trying to send " ++ maybe "an unsupported type" id maybeMessage
225− "Cannot pass " ++ message ++ " through " ++ boundPort ++ " '" ++ name ++ "':\n\n"
219+ ++ " through " ++ boundPort ++ " '" ++ name ++ "'"
222+ "The specific unsupported type is:\n\n"
226− ++ P.render (P.nest 4 (P.pretty False localType)) ++ "\n\n"
223+ ++ P.render (P.nest 4 (P.pretty False localType)) ++ "\n\n"
227− ++ "The kinds of values that can flow through " ++ boundPort ++ "s include:\n"
224+ ++ "The types of values that can flow through " ++ boundPort ++ "s include:\n"
228− ++ "Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples,\n"
225+ ++ "Ints, Floats, Bools, Strings, Maybes, Lists, Arrays, Tuples,\n"
229− ++ "Json.Values, and concrete records."
226+ ++ "Json.Values, and concrete records."
231− boundPort =
228+ Report.simple preHint postHint
232− if isInbound then "inbound port" else "outbound port"
235− maybe "the following type" id maybeMessage
231+argMismatchReport :: String -> Var.Canonical -> Int -> Int -> Report.Report
232+argMismatchReport kind var expected actual =
235+ kind ++ " " ++ Var.toString var ++ " has too "
236+ ++ (if actual < expected then "few" else "many")
238−argMismatchHint :: String -> Var.Canonical -> Int -> Int -> String
239+ postHint =
239−argMismatchHint kind var expected actual =
240− "The " ++ kind ++ " " ++ Var.toString var ++ " has too "
241− ++ (if actual < expected then "few" else "many")
243− ++ "Expecting " ++ show expected ++ ", but got " ++ show actual
240+ "Expecting " ++ show expected ++ ", but got " ++ show actual ++ "."
242+ Report.Report Nothing preHint postHint
246−maybeYouWant :: String -> [String] -> String
245+maybeYouWant :: [String] -> String
247−maybeYouWant prefix suggestions =
246+maybeYouWant suggestions =
248 case suggestions of
247 case suggestions of
254− ++ "Maybe you want one of the following?\n"
252+ "Maybe you want one of the following?\n"
255 ++ concatMap ("\n "++) suggestions
253 ++ concatMap ("\n "++) suggestions