@@ -16,10 +16,8 @@ module Language.PureScript.Sugar.Names (
1616 desugarImports
1717) where
1818
19−import Data.Data
2019import Data.Maybe (fromMaybe, isJust, mapMaybe)
2120import Data.Monoid ((<>))
22−import Data.Generics.Extras (mkS, extS, everywhereWithContextM')
2321
2422import Control.Applicative (Applicative(..), (<$>), (<*>))
2523import Control.Monad.Error
@@ -31,6 +29,7 @@ import Language.PureScript.Names
3129import Language.PureScript.Types
3230import Language.PureScript.Environment
3331import Language.PureScript.Errors
32+import Language.PureScript.Traversals
3433
3534-- |
3635-- The global export environment - every declaration exported from every module.
@@ -177,83 +176,67 @@ renameInModule :: ImportEnvironment -> ExportEnvironment -> Module -> Either Err
177176renameInModule imports exports (Module mn decls exps) =
178177 Module mn <$> mapM go decls <*> pure exps
179178 where
180− go :: Declaration -> Either ErrorStack Declaration
181− go (PositionedDeclaration pos d) = rethrowWithPosition pos $ PositionedDeclaration pos <$> go d
182− go (DataDeclaration name args dctors) =
183− rethrow (strMsg ("Error in data declaration " ++ show name) <>) $
184− DataDeclaration <$> pure name <*> pure args <*> updateAll dctors
185− go (DataBindingGroupDeclaration decls') =
186− DataBindingGroupDeclaration <$> mapM go decls'
187− go (TypeSynonymDeclaration name ps ty) =
188− rethrow (strMsg ("Error in type synonym " ++ show name) <>) $
189− TypeSynonymDeclaration <$> pure name <*> pure ps <*> updateType' ty
190− go (TypeClassDeclaration className args implies ds) =
191− TypeClassDeclaration className args <$> updateConstraints Nothing implies <*> mapM go ds
192− go (TypeInstanceDeclaration name cs cn ts ds) =
193− TypeInstanceDeclaration name <$> updateConstraints Nothing cs <*> updateClassName cn Nothing <*> updateType' ts <*> mapM go ds
194− go (ExternInstanceDeclaration name cs cn ts) =
195− ExternInstanceDeclaration name <$> updateConstraints Nothing cs <*> updateClassName cn Nothing <*> updateType' ts
196− go (ValueDeclaration name nameKind [] Nothing val) = do
197− val' <- everywhereWithContextM' (Nothing, []) (mkS bindFunctionArgs `extS` bindBinders) val
198− rethrow (strMsg ("Error in declaration " ++ show name) <>) $
199− ValueDeclaration name nameKind [] Nothing <$> updateAll val'
200− where
201− bindFunctionArgs :: (Maybe SourcePos, [Ident]) -> Value -> Either ErrorStack ((Maybe SourcePos, [Ident]), Value)
202− bindFunctionArgs (_, bound) v@(PositionedValue pos' _) = return ((Just pos', bound), v)
203− bindFunctionArgs (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
204− bindFunctionArgs (pos, bound) (Let ds val') =
179+ (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS
180+
181+ updateDecl :: (Maybe SourcePos, [Ident]) -> Declaration -> Either ErrorStack ((Maybe SourcePos, [Ident]), Declaration)
182+ updateDecl (_, bound) d@(PositionedDeclaration pos _) = return ((Just pos, bound), d)
183+ updateDecl (pos, bound) (DataDeclaration name args dctors) =
184+ (,) (pos, bound) <$> (DataDeclaration name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)
185+ updateDecl (pos, bound) (TypeSynonymDeclaration name ps ty) =
186+ (,) (pos, bound) <$> (TypeSynonymDeclaration name ps <$> updateTypesEverywhere pos ty)
187+ updateDecl (pos, bound) (TypeClassDeclaration className args implies ds) =
188+ (,) (pos, bound) <$> (TypeClassDeclaration className args <$> updateConstraints pos implies <*> pure ds)
189+ updateDecl (pos, bound) (TypeInstanceDeclaration name cs cn ts ds) =
190+ (,) (pos, bound) <$> (TypeInstanceDeclaration name <$> updateConstraints pos cs <*> updateClassName cn pos <*> mapM (updateTypesEverywhere pos) ts <*> pure ds)
191+ updateDecl (pos, bound) (ExternInstanceDeclaration name cs cn ts) =
192+ (,) (pos, bound) <$> (ExternInstanceDeclaration name <$> updateConstraints pos cs <*> updateClassName cn Nothing <*> mapM (updateTypesEverywhere pos) ts)
193+ updateDecl (pos, bound) (TypeDeclaration name ty) =
194+ (,) (pos, bound) <$> (TypeDeclaration name <$> updateTypesEverywhere pos ty)
195+ updateDecl (pos, bound) (ExternDeclaration fit name js ty) =
196+ (,) (pos, name : bound) <$> (ExternDeclaration fit name js <$> updateTypesEverywhere pos ty)
197+ updateDecl s d = return (s, d)
198+
199+ updateValue :: (Maybe SourcePos, [Ident]) -> Value -> Either ErrorStack ((Maybe SourcePos, [Ident]), Value)
200+ updateValue (_, bound) v@(PositionedValue pos' _) = return ((Just pos', bound), v)
201+ updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')
202+ updateValue (pos, bound) (Let ds val') =
205203 let args = mapMaybe letBoundVariable ds
206204 in return ((pos, args ++ bound), Let ds val')
207− bindFunctionArgs (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
208− (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
209− bindFunctionArgs (pos, bound) (Var name'@(Qualified (Just _) _)) =
210− (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
211− bindFunctionArgs (pos, bound) (BinaryNoParens name'@(Qualified Nothing ident) v1 v2) | ident `notElem` bound =
212− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
213− bindFunctionArgs (pos, bound) (BinaryNoParens name'@(Qualified (Just _) _) v1 v2) =
214− (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
215− bindFunctionArgs pb other = return (pb, other)
216−
217− bindBinders :: (Maybe SourcePos, [Ident]) -> CaseAlternative -> Either ErrorStack ((Maybe SourcePos, [Ident]), CaseAlternative)
218− bindBinders (pos, bound) c@(CaseAlternative bs _ _) = return ((pos, concatMap binderNames bs ++ bound), c)
219−
220− letBoundVariable :: Declaration -> Maybe Ident
221− letBoundVariable (ValueDeclaration ident _ _ _ _) = Just ident
222− letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d
223− letBoundVariable _ = Nothing
224− go (ValueDeclaration name _ _ _ _) = error $ "Binders should have been desugared in " ++ show name
225− go (ExternDeclaration fit name js ty) =
226− rethrow (strMsg ("Error in declaration " ++ show name) <>) $
227− ExternDeclaration <$> pure fit <*> pure name <*> pure js <*> updateType' ty
228− go (BindingGroupDeclaration decls') = BindingGroupDeclaration <$> mapM go' decls'
229− where
230− go' (name, nk, value) = rethrow (strMsg ("Error in declaration " ++ show name) <>) $
231− (,,) <$> pure name <*> pure nk <*> updateAll value
232− go d = updateAll d
233−
234− updateAll :: Data d => d -> Either ErrorStack d
235− updateAll = everywhereWithContextM' Nothing (mkS updateType `extS` updateValue `extS` updateBinder)
236−
237− updateValue :: Maybe SourcePos -> Value -> Either ErrorStack (Maybe SourcePos, Value)
238− updateValue _ v@(PositionedValue pos _) = return (Just pos, v)
239− updateValue pos (Constructor name) = (,) <$> pure pos <*> (Constructor <$> updateDataConstructorName name pos)
240− updateValue pos v = return (pos, v)
241−
242− updateBinder :: Maybe SourcePos -> Binder -> Either ErrorStack (Maybe SourcePos, Binder)
243− updateBinder _ v@(PositionedBinder pos _) = return (Just pos, v)
244− updateBinder pos (ConstructorBinder name b) = (,) <$> pure pos <*> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
245− updateBinder pos v = return (pos, v)
246−
247− updateType :: Maybe SourcePos -> Type -> Either ErrorStack (Maybe SourcePos, Type)
248− updateType pos (TypeConstructor name) = (,) <$> pure pos <*> (TypeConstructor <$> updateTypeName name pos)
249− updateType pos (SaturatedTypeSynonym name tys) = (,) <$> pure pos <*> (SaturatedTypeSynonym <$> updateTypeName name pos <*> updateType' tys)
250− updateType pos (ConstrainedType cs t) = (,) <$> pure pos <*> (ConstrainedType <$> updateConstraints pos cs <*> pure t)
251− updateType pos t = return (pos, t)
252−
253− updateType' :: Data d => d -> Either ErrorStack d
254− updateType' = everywhereWithContextM' Nothing (mkS updateType)
205+ updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =
206+ (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
207+ updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =
208+ (,) (pos, bound) <$> (Var <$> updateValueName name' pos)
209+ updateValue (pos, bound) (BinaryNoParens name'@(Qualified Nothing ident) v1 v2) | ident `notElem` bound =
210+ (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
211+ updateValue (pos, bound) (BinaryNoParens name'@(Qualified (Just _) _) v1 v2) =
212+ (,) (pos, bound) <$> (BinaryNoParens <$> updateValueName name' pos <*> pure v1 <*> pure v2)
213+ updateValue s@(pos, _) (Constructor name) = (,) s <$> (Constructor <$> updateDataConstructorName name pos)
214+ updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)
215+ updateValue s v = return (s, v)
216+
217+ updateBinder :: (Maybe SourcePos, [Ident]) -> Binder -> Either ErrorStack ((Maybe SourcePos, [Ident]), Binder)
218+ updateBinder (_, bound) v@(PositionedBinder pos _) = return ((Just pos, bound), v)
219+ updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)
220+ updateBinder s v = return (s, v)
221+
222+ updateCase :: (Maybe SourcePos, [Ident]) -> CaseAlternative -> Either ErrorStack ((Maybe SourcePos, [Ident]), CaseAlternative)
223+ updateCase (pos, bound) c@(CaseAlternative bs _ _) = return ((pos, concatMap binderNames bs ++ bound), c)
224+
225+ letBoundVariable :: Declaration -> Maybe Ident
226+ letBoundVariable (ValueDeclaration ident _ _ _ _) = Just ident
227+ letBoundVariable (PositionedDeclaration _ d) = letBoundVariable d
228+ letBoundVariable _ = Nothing
229+
230+ updateTypesEverywhere :: Maybe SourcePos -> Type -> Either ErrorStack Type
231+ updateTypesEverywhere pos0 = everywhereOnTypesM (updateType pos0)
232+ where
233+ updateType :: Maybe SourcePos -> Type -> Either ErrorStack Type
234+ updateType pos (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos
235+ updateType pos (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys
236+ updateType pos (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t
237+ updateType _ t = return t
255238
256− updateConstraints pos = mapM (\(name, ts) -> (,) <$> updateClassName name pos <*> pure ts)
239+ updateConstraints pos = mapM (\(name, ts) -> (,) <$> updateClassName name pos <*> mapM (updateTypesEverywhere pos) ts)
257240
258241 updateTypeName = update "type" importedTypes (\mes -> isJust . (`lookup` exportedTypes mes))
259242 updateClassName = update "type class" importedTypeClasses (flip elem . exportedTypeClasses)