@@ -1,7 +1,7 @@
1module Transform.Check (mistakes) where
1module Transform.Check (mistakes) where
3import Transform.SortDefinitions (boundVars)
3import Transform.SortDefinitions (boundVars)
4−import SourceSyntax.Declaration (Declaration(..))
4+import qualified SourceSyntax.Declaration as D
5import SourceSyntax.Expression
5import SourceSyntax.Expression
6import SourceSyntax.Pattern
6import SourceSyntax.Pattern
7import SourceSyntax.Location
7import SourceSyntax.Location
@@ -14,19 +14,20 @@ import qualified Data.Set as Set
14import Text.PrettyPrint as P
14import Text.PrettyPrint as P
17−mistakes :: [Declaration t v] -> [Doc]
17+mistakes :: [D.Declaration t v] -> [Doc]
18mistakes decls =
18mistakes decls =
19 concat [ infiniteTypeAliases decls
19 concat [ infiniteTypeAliases decls
20 , illFormedTypes decls
20 , illFormedTypes decls
21 , map P.text (duplicateConstructors decls)
21 , map P.text (duplicateConstructors decls)
22− , map P.text (concatMap findErrors (getLets decls)) ]
22+ , map P.text (concatMap findErrors (getLets decls))
23+ , badDerivations decls ]
24 findErrors defs = duplicates defs ++ badOrder defs
25 findErrors defs = duplicates defs ++ badOrder defs
26−getLets :: [Declaration t v] -> [[Def t v]]
27+getLets :: [D.Declaration t v] -> [[Def t v]]
27getLets decls = defs : concatMap defLets defs
28getLets decls = defs : concatMap defLets defs
29− defs = [ d | Definition d <- decls ]
30+ defs = [ d | D.Definition d <- decls ]
31 defLets def =
32 defLets def =
32 case def of
33 case def of
@@ -69,13 +70,13 @@ duplicates defs =
69 defMsg = dupErr "definition of"
70 defMsg = dupErr "definition of"
70 annMsg = dupErr "type annotation for"
71 annMsg = dupErr "type annotation for"
72−duplicateConstructors :: [Declaration t v] -> [String]
73+duplicateConstructors :: [D.Declaration t v] -> [String]
73duplicateConstructors decls =
74duplicateConstructors decls =
74 map typeMsg (dups typeCtors) ++ map dataMsg (dups dataCtors)
75 map typeMsg (dups typeCtors) ++ map dataMsg (dups dataCtors)
76− typeCtors = List.sort [ name | Datatype name _ _ <- decls ]
77+ typeCtors = List.sort [ name | D.Datatype name _ _ _ <- decls ]
77 dataCtors = List.sort . concat $
78 dataCtors = List.sort . concat $
78− [ map fst patterns | Datatype _ _ patterns <- decls ]
79+ [ map fst patterns | D.Datatype _ _ patterns _ <- decls ]
79 dataMsg = dupErr "definition of data constructor"
80 dataMsg = dupErr "definition of data constructor"
80 typeMsg = dupErr "definition of type constructor"
81 typeMsg = dupErr "definition of type constructor"
@@ -96,11 +97,32 @@ badOrder defs = go defs
100+badDerivations :: [D.Declaration t v] -> [Doc]
101+badDerivations decls = concatMap badDerivation derivations
104+ [ (decl, tvars, derives) | decl@(D.TypeAlias name tvars _ derives) <- decls ] ++
105+ [ (decl, tvars, derives) | decl@(D.Datatype name tvars _ derives) <- decls ]
107+ badDerivation (decl, tvars, derives) =
108+ case (tvars, derives) of
110+ | D.Json `elem` derives -> [report decl D.Json]
111+ | D.Binary `elem` derives -> [report decl D.Binary]
114+ report decl derive =
115+ P.vcat [ P.text $ "Error: cannot derive '" ++ show derive ++ "' from this type alias."
116+ , P.text "Make sure all type variables are replaced with concrete types:"
118+ , nest 4 (pretty decl)
99−illFormedTypes :: [Declaration t v] -> [Doc]
121+illFormedTypes :: [D.Declaration t v] -> [Doc]
100illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
122illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
102− aliases = [ (decl, tvars, [tipe]) | decl@(TypeAlias _ tvars tipe) <- decls ]
124+ aliases = [ (decl, tvars, [tipe]) | decl@(D.TypeAlias _ tvars tipe _) <- decls ]
103− adts = [ (decl, tvars, concatMap snd ctors) | decl@(Datatype _ tvars ctors) <- decls ]
125+ adts = [ (decl, tvars, concatMap snd ctors) | decl@(D.Datatype _ tvars ctors _) <- decls ]
105 freeVars tipe =
127 freeVars tipe =
106 case tipe of
128 case tipe of
@@ -141,9 +163,9 @@ illFormedTypes decls = map report (Maybe.mapMaybe isIllFormed (aliases ++ adts))
141 quote tvar = "'" ++ tvar ++ "'"
163 quote tvar = "'" ++ tvar ++ "'"
144−infiniteTypeAliases :: [Declaration t v] -> [Doc]
166+infiniteTypeAliases :: [D.Declaration t v] -> [Doc]
145infiniteTypeAliases decls =
167infiniteTypeAliases decls =
146− [ report decl | decl@(TypeAlias name _ tipe) <- decls, isInfinite name tipe ]
168+ [ report decl | decl@(D.TypeAlias name _ tipe _) <- decls, isInfinite name tipe ]
148 isInfinite name tipe =
170 isInfinite name tipe =
149 let infinite = isInfinite name in
171 let infinite = isInfinite name in
@@ -154,11 +176,11 @@ infiniteTypeAliases decls =
154 T.EmptyRecord -> False
176 T.EmptyRecord -> False
155 T.Record fields ext -> infinite ext || any (infinite . snd) fields
177 T.Record fields ext -> infinite ext || any (infinite . snd) fields
157− report decl@(TypeAlias name args tipe) =
179+ report decl@(D.TypeAlias name args tipe derivations) =
158 P.vcat [ P.text $ eightyCharLines 0 msg1
180 P.vcat [ P.text $ eightyCharLines 0 msg1
159 , indented decl
181 , indented decl
160 , P.text $ eightyCharLines 0 msg2
182 , P.text $ eightyCharLines 0 msg2
161− , indented (Datatype name args [(name,[tipe])])
183+ , indented (D.Datatype name args [(name,[tipe])] derivations)
162 , P.text $ eightyCharLines 0 msg3 ++ "\n"
184 , P.text $ eightyCharLines 0 msg3 ++ "\n"