1{-# OPTIONS_GHC -Wall #-}
2module Reporting.Error.Syntax where
4import qualified Data.Aeson as Json
5import qualified Data.List as List
6import qualified Text.Parsec.Error as Parsec
7import qualified Text.PrettyPrint as P
8import Text.PrettyPrint ((<+>))
10import qualified AST.Helpers as Help
11import qualified AST.Type as Type
12import Elm.Utils ((|>))
13import qualified Reporting.PrettyPrint as P
17 = Parse [Parsec.Message]
18 | InfixDuplicate String
19 | TypeWithoutDefinition String
20 | PortWithoutAnnotation String
21 | DuplicateValueDeclaration String
22 | DuplicateTypeDeclaration String
23 | DuplicateDefinition String
24 | UnboundTypeVarsInAlias String [String] String [String] Type.Raw
25 | UnboundTypeVarsInUnion String [String] String [String] [(String, [Type.Raw])]
30toJson :: Error -> Json.Value
33 _ -> error "Syntax.toJson"
38toHint :: Error -> String
44 InfixDuplicate opName ->
45 "The infix declarations for " ++ operator ++ " must be removed.\n\n"
46 ++ "The precedence and associativity can only be set in one place, and\n"
47 ++ "this information has already been set somewhere else."
51 then "(" ++ opName ++ ")"
52 else "`" ++ opName ++ "`"
54 TypeWithoutDefinition valueName ->
55 "There is a type annotation for '" ++ valueName ++ "' but there"
56 ++ "is no corresponding definition! I need something like this:\n\n"
57 ++ " " ++ valueName ++ " = 42\n\n"
58 ++ "And be sure to put the definition directly below the type annotation."
60 PortWithoutAnnotation portName ->
61 "There is a port named '" ++ portName ++ "' but it does not have"
62 ++ "a type annotation! I need something like this:\n\n"
63 ++ indent ("port " ++ portName ++ " : Signal Int") ++ "\n\n"
64 ++ "And be sure to put this annotation directly above the port definition."
66 DuplicateValueDeclaration name ->
67 "Multiple top-level declarations define '" ++ name ++ "',\n"
68 ++ "but the name overlap makes all uses of '" ++ name ++ "' ambiguous.\n"
69 ++ "How can we know which you want?!\n\n"
70 ++ "Find all the top-level variables named '" ++ name ++ "' and\n"
71 ++ "do some renaming. Make sure the names are distinct!"
73 DuplicateTypeDeclaration tipeName ->
74 "Multiple declarations define a type '" ++ tipeName ++ "',\n"
75 ++ "but the name overlap makes all uses of '" ++ tipeName ++ "' ambiguous.\n"
76 ++ "How can we know which you want?!\n\n"
77 ++ "Find all the types named '" ++ tipeName ++ "' and\n"
78 ++ "do some renaming. Make sure the names are distinct!"
80 DuplicateDefinition name ->
81 "This let-expression defines multiple variables named '" ++ name ++ "',\n"
82 ++ "but the name overlap makes all uses of '" ++ name ++ "' ambiguous.\n"
83 ++ "How can we know which you want?!\n\n"
84 ++ "Find the variables named '" ++ name ++ "' in this let-expression and\n"
85 ++ "do some renaming. Make sure the names are distinct!"
87 UnboundTypeVarsInAlias typeName givenVars tvar tvars tipe ->
88 unboundTypeVars typeName tvar tvars $ P.render $
90 (P.text "type alias" <+> P.text typeName <+> P.hsep vars <+> P.equals)
94 vars = map P.text (givenVars ++ tvar : tvars)
97 UnboundTypeVarsInUnion typeName givenVars tvar tvars ctors ->
98 unboundTypeVars typeName tvar tvars $ P.render $
100 [ P.text "type" <+> P.text typeName <+> P.hsep vars
102 |> zipWith (<+>) (P.text "=" : repeat (P.text "|"))
107 vars = map P.text (givenVars ++ tvar : tvars)
109 P.text ctor <+> P.hsep (map (P.pretty True) args)
112unboundTypeVars :: String -> String -> [String] -> String -> String
113unboundTypeVars typeName tvar tvars revisedDeclaration =
114 "In the definition of type '" ++ typeName ++ "' you use the following\n"
115 ++ "unbound type variable" ++ s ++ ": " ++ List.intercalate ", " (tvar:tvars) ++ "\n\n"
116 ++ "All type variables must be listed to avoid sneaky type errors.\n"
117 ++ "Imagine one '" ++ typeName ++ "' where '" ++ tvar ++ "' is an Int and\n"
118 ++ "another where it is a Bool. They both look like a '" ++ typeName ++ "'\n"
119 ++ "to the type checker, but they are actually different types!\n\n"
120 ++ "Maybe you want a definition like this?\n\n"
121 ++ indent revisedDeclaration ++ "\n\n"
123 s = if null tvars then "" else "s"
126indent :: String -> String
128 List.intercalate "\n" (map (" " ++ ) (lines string))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list