diff options
Diffstat (limited to 'src/Main.hs')
| -rw-r--r-- | src/Main.hs | 54 | 
1 files changed, 47 insertions, 7 deletions
diff --git a/src/Main.hs b/src/Main.hs index 4d26bd3b..f26c473e 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -284,7 +284,8 @@ mkExportItems mod_map mod decl_map decls options maybe_exps      lookupExport (HsEVar x)   	| Just decl <- findDecl x -	= return [ ExportDecl x decl ] +	= return [ ExportDecl x (extractDecl (nameOfQName x) x_mod decl) ] +        where x_mod | Qual m _ <- x = m  	  -- ToDo: cope with record selectors here      lookupExport (HsEAbs t)  	| Just decl <- findDecl t @@ -342,6 +343,45 @@ keepDecl HsClassDecl{}   = True  keepDecl HsDocGroup{}	 = True  keepDecl _ = False +-- Sometimes the declaration we want to export is not the "main" declaration: +-- it might be an individual record selector or a class method.  In these +-- cases we have to extract the required declaration (and somehow cobble  +-- together a type signature for it...) + +extractDecl :: HsName -> Module -> HsDecl -> HsDecl +extractDecl name mod decl +  | Just n <- declMainBinder decl, n == name  =  decl +  | otherwise  =   +	case decl of +	    HsClassDecl loc ctxt n tvs fds decls mb_doc -> +		case [ d | d@HsTypeSig{} <- decls,  +			   declMainBinder d == Just name ] of +		  [decl] -> extractClassDecl n mod tvs decl +		  _ -> error "internal: extractDecl" + +	    HsDataDecl loc ctxt t tvs cons drvs mb_doc -> +		extractRecSel name mod t tvs cons + +extractClassDecl c mod tvs (HsTypeSig loc [n] ty doc) + = case ty of + 	HsForAllType tvs ctxt' ty' ->  +	  HsTypeSig loc [n] (HsForAllType tvs (ctxt ++ ctxt') ty') doc +	ty ->  +	  HsTypeSig loc [n] (HsForAllType Nothing ctxt ty) doc + where +  ctxt = [(Qual mod c, map HsTyVar tvs)] + +extractRecSel nm mod t tvs [] = error "extractRecSel: selector not found" +extractRecSel nm mod t tvs (HsRecDecl loc c _tvs ctxt fields _mb_doc : rest) +  | (HsFieldDecl ns ty mb_doc : _) <- matching_fields +	= HsTypeSig loc [nm] (HsTyFun data_ty (unbang ty)) mb_doc +  | otherwise = extractRecSel nm mod t tvs rest +  where +	matching_fields = [ f | f@(HsFieldDecl ns ty mb_doc) <- fields, +			        nm `elem` ns ] + +	data_ty = foldl HsTyApp (HsTyCon (Qual mod t)) (map HsTyVar tvs) +  -- -----------------------------------------------------------------------------  -- Pruning @@ -455,8 +495,8 @@ buildImportEnv mod_map this_mod exported_names imp_decls  expandDecl :: HsDecl -> [HsDecl]  expandDecl (HsTypeSig loc fs qt doc) = [ HsTypeSig loc [f] qt doc | f <- fs ] -expandDecl (HsClassDecl loc ty fds decls doc) -  = [ HsClassDecl loc ty fds (concat (map expandDecl decls)) doc ] +expandDecl (HsClassDecl loc ctxt n tvs fds decls doc) +  = [ HsClassDecl loc ctxt n tvs fds (concat (map expandDecl decls)) doc ]  expandDecl d = [ d ]  ----------------------------------------------------------------------------- @@ -495,16 +535,16 @@ finishedDoc d doc rest = d' : rest  		HsDataDecl loc ctxt n ns cons drv (Just doc)  	  HsNewTypeDecl loc ctxt n ns con drv _ ->   		HsNewTypeDecl loc ctxt n ns con drv (Just doc) -	  HsClassDecl loc ty fds meths _ ->  -		HsClassDecl loc ty fds meths (Just doc) +	  HsClassDecl loc ctxt n tvs fds meths _ ->  +		HsClassDecl loc ctxt n tvs fds meths (Just doc)  	  HsTypeSig loc ns ty _ ->   		HsTypeSig loc ns ty (Just doc)  	  HsForeignImport loc cc sf str n ty _ ->  		HsForeignImport loc cc sf str n ty (Just doc)  	  _other -> d -collectInDecl (HsClassDecl loc ty fds meths doc) -  = HsClassDecl loc ty fds (collect Nothing DocEmpty meths) doc +collectInDecl (HsClassDecl loc ctxt n tvs fds meths doc) +  = HsClassDecl loc ctxt n tvs fds (collect Nothing DocEmpty meths) doc  collectInDecl decl    = decl  | 
