@@ -1,4 +1,3 @@
1−{-# LANGUAGE Rank2Types #-}
2{-# LANGUAGE FlexibleContexts #-}
1{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
@@ -11,11 +10,11 @@
11-- The value parser ignores fixity data when parsing binary operator applications, so
10-- The value parser ignores fixity data when parsing binary operator applications, so
12-- it is necessary to reorder them here.
11-- it is necessary to reorder them here.
14−module Language.PureScript.Sugar.Operators (
13+module Language.PureScript.Sugar.Operators
15− rebracket,
14+ ( rebracket
16− removeSignedLiterals,
15+ , removeSignedLiterals
17− desugarOperatorSections
16+ , desugarOperatorSections
20import Prelude ()
19import Prelude ()
21import Prelude.Compat
20import Prelude.Compat
@@ -27,30 +26,29 @@ import Language.PureScript.Externs
27import Language.PureScript.Names
26import Language.PureScript.Names
28import Language.PureScript.Sugar.Operators.Binders
27import Language.PureScript.Sugar.Operators.Binders
29import Language.PureScript.Sugar.Operators.Expr
28import Language.PureScript.Sugar.Operators.Expr
30−import Language.PureScript.Traversals (defS)
29+import Language.PureScript.Sugar.Operators.Types
30+import Language.PureScript.Traversals (defS, sndM)
31+import Language.PureScript.Types
33+import Control.Monad ((<=<))
32import Control.Monad.Error.Class (MonadError(..))
34import Control.Monad.Error.Class (MonadError(..))
33import Control.Monad.Supply.Class
35import Control.Monad.Supply.Class
35import Data.Function (on)
37import Data.Function (on)
38+import Data.Functor.Identity
36−import Data.List (groupBy, sortBy)
39+import Data.List (partition, groupBy, sortBy)
37import Data.Maybe (mapMaybe)
40import Data.Maybe (mapMaybe)
38import qualified Data.Map as M
41import qualified Data.Map as M
40import qualified Language.PureScript.Constants as C
43import qualified Language.PureScript.Constants as C
42−-- TODO: in 0.9 operators names can have their own type rather than being in a sum with `Ident`, and `AliasName` no longer needs to be optional
45+-- TODO: in 0.9 operators names can have their own type rather than being in a sum with `Ident`, and `FixityAlias` no longer needs to be optional
45-- An operator associated with its declaration position, fixity, and the name
48-- An operator associated with its declaration position, fixity, and the name
46-- of the function or data constructor it is an alias for.
49-- of the function or data constructor it is an alias for.
48−type FixityRecord = (Qualified Ident, SourceSpan, Fixity, Maybe AliasName)
51+type FixityRecord = (Qualified Ident, SourceSpan, Fixity, Maybe (Qualified FixityAlias))
51−-- An operator can be an alias for a function or a data constructor.
53−type AliasName = Either (Qualified Ident) (Qualified (ProperName 'ConstructorName))
56-- Remove explicit parentheses and reorder binary operator applications
54-- Remove explicit parentheses and reorder binary operator applications
@@ -62,23 +60,57 @@ rebracket
62 -> [Module]
60 -> [Module]
63 -> m [Module]
61 -> m [Module]
64rebracket externs ms = do
62rebracket externs ms = do
63+ let (typeFixities, valueFixities) = partition isTypeFixity $
65− let fixities = concatMap externsFixities externs ++ concatMap collectFixities ms
64+ concatMap externsFixities externs ++ concatMap collectFixities ms
66− ensureNoDuplicates $ map (\(i, pos, _, _) -> (i, pos)) fixities
66+ ensureNoDuplicates' $ valueFixities
67+ ensureNoDuplicates' $ typeFixities
67− let opTable = customOperatorTable $ map (\(i, _, f, _) -> (i, f)) fixities
69+ let valueOpTable = customOperatorTable' valueFixities
70+ typeOpTable = customOperatorTable' typeFixities
68− ms' <- traverse (rebracketModule opTable) ms
71+ ms' <- traverse (rebracketModule valueOpTable typeOpTable) ms
73+ let valueAliased = M.fromList (mapMaybe makeLookupEntry valueFixities)
69− let aliased = M.fromList (mapMaybe makeLookupEntry fixities)
74+ typeAliased = M.fromList (mapMaybe makeLookupEntry typeFixities)
70− mapM (renameAliasedOperators aliased) ms'
75+ mapM (renameAliasedOperators valueAliased typeAliased) ms'
79+ isTypeFixity :: FixityRecord -> Bool
80+ -- Nothing case for FixityAlias can only ever be a value fixity, as it's not
81+ -- possible to define types with operator names aside through aliasing.
82+ -- TODO: This comment is redundant after 0.9.
83+ isTypeFixity (_, _, _, Just (Qualified _ (AliasType _))) = True
84+ isTypeFixity _ = False
86+ ensureNoDuplicates' :: [FixityRecord] -> m ()
87+ ensureNoDuplicates' =
88+ ensureNoDuplicates . map (\(i, pos, _, _) -> (i, pos))
90+ customOperatorTable' :: [FixityRecord] -> [[(Qualified Ident, Associativity)]]
91+ customOperatorTable' =
92+ customOperatorTable . map (\(i, _, f, _) -> (i, f))
74− makeLookupEntry :: FixityRecord -> Maybe (Qualified Ident, AliasName)
94+ makeLookupEntry :: FixityRecord -> Maybe (Qualified Ident, Qualified FixityAlias)
75 makeLookupEntry (qname, _, _, alias) = (qname, ) <$> alias
95 makeLookupEntry (qname, _, _, alias) = (qname, ) <$> alias
77− renameAliasedOperators :: M.Map (Qualified Ident) AliasName -> Module -> m Module
97+ renameAliasedOperators
98+ :: M.Map (Qualified Ident) (Qualified FixityAlias)
99+ -> M.Map (Qualified Ident) (Qualified FixityAlias)
78− renameAliasedOperators aliased (Module ss coms mn ds exts) =
102+ renameAliasedOperators valueAliased typeAliased (Module ss coms mn ds exts) =
79 Module ss coms mn <$> mapM f' ds <*> pure exts
103 Module ss coms mn <$> mapM f' ds <*> pure exts
105+ (goDecl', goExpr') = updateTypes goType
81− (f', _, _, _, _) = everywhereWithContextOnValuesM Nothing goDecl goExpr goBinder defS defS
107+ everywhereWithContextOnValuesM
109+ (\pos -> uncurry goDecl <=< goDecl' pos)
110+ (\pos -> uncurry goExpr <=< goExpr' pos)
83 goDecl :: Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
115 goDecl :: Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
84 goDecl _ d@(PositionedDeclaration pos _ _) = return (Just pos, d)
116 goDecl _ d@(PositionedDeclaration pos _ _) = return (Just pos, d)
@@ -86,27 +118,39 @@ rebracket externs ms = do
87 goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
119 goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
88 goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
120 goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
89− goExpr pos (Var name) = return (pos, case name `M.lookup` aliased of
121+ goExpr pos (Var name) = return (pos, case name `M.lookup` valueAliased of
90− Just (Left alias) -> Var alias
122+ Just (Qualified mn' (AliasValue alias)) -> Var (Qualified mn' alias)
91− Just (Right alias) -> Constructor alias
123+ Just (Qualified mn' (AliasConstructor alias)) -> Constructor (Qualified mn' alias)
92− Nothing -> Var name)
124+ _ -> Var name)
93 goExpr pos other = return (pos, other)
125 goExpr pos other = return (pos, other)
95 goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
127 goBinder :: Maybe SourceSpan -> Binder -> m (Maybe SourceSpan, Binder)
96 goBinder _ b@(PositionedBinder pos _ _) = return (Just pos, b)
128 goBinder _ b@(PositionedBinder pos _ _) = return (Just pos, b)
97− goBinder pos (BinaryNoParensBinder (OpBinder name) lhs rhs) = case name `M.lookup` aliased of
129+ goBinder pos (BinaryNoParensBinder (OpBinder name) lhs rhs) = case name `M.lookup` valueAliased of
98− Just (Left alias) ->
130+ Just (Qualified _ (AliasValue alias)) ->
99 maybe id rethrowWithPosition pos $
131 maybe id rethrowWithPosition pos $
100− throwError . errorMessage $ InvalidOperatorInBinder (disqualify name) (disqualify alias)
132+ throwError . errorMessage $ InvalidOperatorInBinder (disqualify name) alias
101− Just (Right alias) ->
133+ Just (Qualified mn' (AliasConstructor alias)) ->
102− return (pos, ConstructorBinder alias [lhs, rhs])
134+ return (pos, ConstructorBinder (Qualified mn' alias) [lhs, rhs])
104 maybe id rethrowWithPosition pos $
136 maybe id rethrowWithPosition pos $
105 throwError . errorMessage $ UnknownValue name
137 throwError . errorMessage $ UnknownValue name
106 goBinder _ (BinaryNoParensBinder {}) =
138 goBinder _ (BinaryNoParensBinder {}) =
107 internalError "BinaryNoParensBinder has no OpBinder"
139 internalError "BinaryNoParensBinder has no OpBinder"
108 goBinder pos other = return (pos, other)
140 goBinder pos other = return (pos, other)
142+ goType :: Maybe SourceSpan -> Type -> m Type
143+ goType pos = everywhereOnTypesM go
145+ go :: Type -> m Type
146+ go (BinaryNoParensType (TypeOp name) lhs rhs) = case name `M.lookup` typeAliased of
147+ Just (Qualified mn' (AliasType alias)) ->
148+ return $ TypeApp (TypeApp (TypeConstructor (Qualified mn' alias)) lhs) rhs
150+ maybe id rethrowWithPosition pos $
151+ throwError . errorMessage $ UnknownTypeOp name
152+ go other = return other
110removeSignedLiterals :: Module -> Module
154removeSignedLiterals :: Module -> Module
111removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds) exts
155removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds) exts
@@ -116,24 +160,64 @@ removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds)
116 go other = other
160 go other = other
118rebracketModule
162rebracketModule
119− :: (MonadError MultipleErrors m)
164+ . (MonadError MultipleErrors m)
120 => [[(Qualified Ident, Associativity)]]
165 => [[(Qualified Ident, Associativity)]]
166+ -> [[(Qualified Ident, Associativity)]]
121 -> Module
167 -> Module
122 -> m Module
168 -> m Module
123−rebracketModule opTable (Module ss coms mn ds exts) =
169+rebracketModule valueOpTable typeOpTable (Module ss coms mn ds exts) =
124− let (f, _, _) = everywhereOnValuesTopDownM return (matchExprOperators opTable) (matchBinderOperators opTable)
125− in Module ss coms mn <$> (map removeParens <$> parU ds f) <*> pure exts
170+ Module ss coms mn <$> (map removeParens <$> parU ds f) <*> pure exts
173+ everywhereOnValuesTopDownM
174+ (decontextify goDecl)
175+ (goExpr <=< decontextify goExpr')
178+ (goDecl, goExpr') = updateTypes (\_ -> goType)
180+ goExpr :: Expr -> m Expr
181+ goExpr = return . matchExprOperators valueOpTable
183+ goBinder :: Binder -> m Binder
184+ goBinder = return . matchBinderOperators valueOpTable
186+ goType :: Type -> m Type
187+ goType = return . matchTypeOperators typeOpTable
189+ decontextify :: (Maybe SourceSpan -> a -> m (Maybe SourceSpan, a)) -> a -> m a
190+ decontextify ctxf = fmap snd . ctxf Nothing
127removeParens :: Declaration -> Declaration
192removeParens :: Declaration -> Declaration
128−removeParens =
193+removeParens = f
129− let (f, _, _) = everywhereOnValues id goExpr goBinder
197+ (decontextify goDecl)
198+ (goExpr . decontextify goExpr')
201+ (goDecl, goExpr') = updateTypes (\_ -> return . goType)
203+ goExpr :: Expr -> Expr
132 goExpr (Parens val) = val
204 goExpr (Parens val) = val
133 goExpr val = val
205 goExpr val = val
207+ goBinder :: Binder -> Binder
134 goBinder (ParensInBinder b) = b
208 goBinder (ParensInBinder b) = b
135 goBinder b = b
209 goBinder b = b
211+ goType :: Type -> Type
212+ goType (ParensInType t) = t
216+ :: (Maybe SourceSpan -> a -> Identity (Maybe SourceSpan, a))
219+ decontextify ctxf = snd . runIdentity . ctxf Nothing
137externsFixities
221externsFixities
138 :: ExternsFile
222 :: ExternsFile
139 -> [FixityRecord]
223 -> [FixityRecord]
@@ -197,3 +281,52 @@ desugarOperatorSections (Module ss coms mn ds exts) =
197 Left val -> f2 val var
281 Left val -> f2 val var
198 Right val -> f2 var val
282 Right val -> f2 var val
199 goExpr other = return other
283 goExpr other = return other
288+ => (Maybe SourceSpan -> Type -> m Type)
289+ -> ( Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
290+ , Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
292+updateTypes goType = (goDecl, goExpr)
295+ goType' :: Maybe SourceSpan -> Type -> m Type
296+ goType' = everywhereOnTypesM . goType
298+ goDecl :: Maybe SourceSpan -> Declaration -> m (Maybe SourceSpan, Declaration)
299+ goDecl _ d@(PositionedDeclaration pos _ _) = return (Just pos, d)
300+ goDecl pos (DataDeclaration ddt name args dctors) = do
301+ dctors' <- traverse (sndM (traverse (goType' pos))) dctors
302+ return (pos, DataDeclaration ddt name args dctors')
303+ goDecl pos (ExternDeclaration name ty) = do
304+ ty' <- goType' pos ty
305+ return (pos, ExternDeclaration name ty')
306+ goDecl pos (TypeClassDeclaration name args implies decls) = do
307+ implies' <- traverse (sndM (traverse (goType' pos))) implies
308+ return (pos, TypeClassDeclaration name args implies' decls)
309+ goDecl pos (TypeInstanceDeclaration name cs className tys impls) = do
310+ cs' <- traverse (sndM (traverse (goType' pos))) cs
311+ tys' <- traverse (goType' pos) tys
312+ return (pos, TypeInstanceDeclaration name cs' className tys' impls)
313+ goDecl pos (TypeSynonymDeclaration name args ty) = do
314+ ty' <- goType' pos ty
315+ return (pos, TypeSynonymDeclaration name args ty')
316+ goDecl pos (TypeDeclaration expr ty) = do
317+ ty' <- goType' pos ty
318+ return (pos, TypeDeclaration expr ty')
319+ goDecl pos other = return (pos, other)
321+ goExpr :: Maybe SourceSpan -> Expr -> m (Maybe SourceSpan, Expr)
322+ goExpr _ e@(PositionedValue pos _ _) = return (Just pos, e)
323+ goExpr pos (TypeClassDictionary (name, tys) dicts) = do
324+ tys' <- traverse (goType' pos) tys
325+ return (pos, TypeClassDictionary (name, tys') dicts)
326+ goExpr pos (SuperClassDictionary cls tys) = do
327+ tys' <- traverse (goType' pos) tys
328+ return (pos, SuperClassDictionary cls tys')
329+ goExpr pos (TypedValue check v ty) = do
330+ ty' <- goType' pos ty
331+ return (pos, TypedValue check v ty')
332+ goExpr pos other = return (pos, other)