Merge branch 'master' into release
This commit is contained in:
		
						commit
						180022502d
					
				| @ -11,6 +11,7 @@ install: | ||||
|   - cabal install -j --only-dependencies --enable-tests | ||||
| 
 | ||||
| script: | ||||
|   - touch ChangeLog # Create ChangeLog if we're not on the release branch | ||||
|   - cabal check | ||||
|   - cabal sdist | ||||
|   - export SRC_TGZ="$PWD/dist/$(cabal info . | awk '{print $2 ".tar.gz";exit}')" | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, CPP #-} | ||||
| {-# LANGUAGE CPP, MultiParamTypeClasses, FunctionalDependencies #-} | ||||
| {-# LANGUAGE FlexibleInstances #-} | ||||
| 
 | ||||
| module Language.Haskell.GhcMod.FillSig ( | ||||
|     sig | ||||
| @ -12,7 +13,8 @@ import Data.List (find, nub, sortBy) | ||||
| import qualified Data.Map as M | ||||
| import Data.Maybe (isJust, catMaybes) | ||||
| import Exception (ghandle, SomeException(..)) | ||||
| import GHC (GhcMonad, Id, ParsedModule(..), TypecheckedModule(..), DynFlags, SrcSpan, Type, GenLocated(L)) | ||||
| import GHC (GhcMonad, Id, ParsedModule(..), TypecheckedModule(..), DynFlags, | ||||
|             SrcSpan, Type, GenLocated(L)) | ||||
| import qualified GHC as G | ||||
| import qualified Name as G | ||||
| import qualified Language.Haskell.GhcMod.Gap as Gap | ||||
| @ -34,13 +36,19 @@ import Djinn.GHC | ||||
| ---------------------------------------------------------------- | ||||
| 
 | ||||
| -- Possible signatures we can find: function or instance | ||||
| data SigInfo = Signature SrcSpan [G.RdrName] (G.HsType G.RdrName) | ||||
|              | InstanceDecl SrcSpan G.Class | ||||
|              | TyFamDecl SrcSpan G.RdrName TyFamType {- True if closed -} [G.RdrName] | ||||
| data SigInfo | ||||
|     = Signature SrcSpan [G.RdrName] (G.HsType G.RdrName) | ||||
|     | InstanceDecl SrcSpan G.Class | ||||
|     | TyFamDecl SrcSpan G.RdrName TyFamType {- True if closed -} [G.RdrName] | ||||
| 
 | ||||
| -- Signature for fallback operation via haskell-src-exts | ||||
| data HESigInfo = HESignature HE.SrcSpan [HE.Name HE.SrcSpanInfo] (HE.Type HE.SrcSpanInfo) | ||||
|                | HEFamSignature HE.SrcSpan TyFamType (HE.Name HE.SrcSpanInfo) [HE.Name HE.SrcSpanInfo] | ||||
| data HESigInfo | ||||
|     = HESignature HE.SrcSpan [HE.Name HE.SrcSpanInfo] (HE.Type HE.SrcSpanInfo) | ||||
|     | HEFamSignature | ||||
|           HE.SrcSpan | ||||
|           TyFamType | ||||
|           (HE.Name HE.SrcSpanInfo) | ||||
|           [HE.Name HE.SrcSpanInfo] | ||||
| 
 | ||||
| data TyFamType = Closed | Open | Data | ||||
| initialTyFamString :: TyFamType -> (String, String) | ||||
| @ -143,34 +151,54 @@ getSignatureFromHE file lineNo colNo = do | ||||
|              HE.ParseOk (HE.Module _ _ _ _ mdecls) -> do | ||||
|                decl <- find (typeSigInRangeHE lineNo colNo) mdecls | ||||
|                case decl of | ||||
|                  HE.TypeSig (HE.SrcSpanInfo s _) names ty -> return $ HESignature s names ty | ||||
|                  HE.TypeFamDecl (HE.SrcSpanInfo s _) (HE.DHead _ name tys) _ -> | ||||
|                  HE.TypeSig (HE.SrcSpanInfo s _) names ty -> | ||||
|                      return $ HESignature s names ty | ||||
| 
 | ||||
|                  HE.TypeFamDecl (HE.SrcSpanInfo s _) declHead _ -> | ||||
|                    let (name, tys) = dHeadTyVars declHead in | ||||
|                    return $ HEFamSignature s Open name (map cleanTyVarBind tys) | ||||
|                  HE.DataFamDecl (HE.SrcSpanInfo s _) _ (HE.DHead _ name tys) _ -> | ||||
| 
 | ||||
|                  HE.DataFamDecl (HE.SrcSpanInfo s _) _ declHead _ -> | ||||
|                    let (name, tys) = dHeadTyVars declHead in | ||||
|                    return $ HEFamSignature s Open name (map cleanTyVarBind tys) | ||||
|                  _ -> fail "" | ||||
|              _ -> Nothing | ||||
|   where cleanTyVarBind (HE.KindedVar _ n _) = n | ||||
|         cleanTyVarBind (HE.UnkindedVar _ n) = n | ||||
| 
 | ||||
| #if MIN_VERSION_haskell_src_exts(1,16,0) | ||||
|         dHeadTyVars :: HE.DeclHead l -> (HE.Name l, [HE.TyVarBind l]) | ||||
|         dHeadTyVars (HE.DHead _ name) = (name, []) | ||||
|         dHeadTyVars (HE.DHApp _ r ty) = (++[ty]) `fmap` (dHeadTyVars r) | ||||
|         dHeadTyVars (HE.DHInfix _ ty name) = (name, [ty]) | ||||
|         dHeadTyVars (HE.DHParen _ r) = dHeadTyVars r | ||||
| #else | ||||
|         dHeadTyVars :: HE.DeclHead l -> (HE.Name l, [HE.TyVarBind l]) | ||||
|         dHeadTyVars (DHead _ n tys) = (n, tys) | ||||
| #endif | ||||
| 
 | ||||
| ---------------------------------------------------------------- | ||||
| -- b. Code for generating initial code | ||||
| 
 | ||||
| -- A list of function arguments, and whether they are functions or normal arguments | ||||
| -- is built from either a function signature or an instance signature | ||||
| -- A list of function arguments, and whether they are functions or normal | ||||
| -- arguments is built from either a function signature or an instance signature | ||||
| data FnArg = FnArgFunction | FnArgNormal | FnExplicitName String | ||||
| 
 | ||||
| initialBody :: FnArgsInfo ty name => DynFlags -> PprStyle -> ty -> name -> String | ||||
| initialBody dflag style ty name = initialBody' (getFnName dflag style name) (getFnArgs ty) | ||||
| initialBody dflag style ty name = | ||||
|     initialBody' (getFnName dflag style name) (getFnArgs ty) | ||||
| 
 | ||||
| initialBody' :: String -> [FnArg] -> String | ||||
| initialBody' fname args = initialHead fname args ++ " = " | ||||
|                           ++ (if isSymbolName fname then "" else '_':fname) ++ "_body" | ||||
| initialBody' fname args = | ||||
|     initialHead fname args ++ " = " ++ n ++ "_body" | ||||
|  where n = if isSymbolName fname then "" else '_':fname | ||||
| 
 | ||||
| initialFamBody :: FnArgsInfo ty name => DynFlags -> PprStyle -> name -> [name] -> String | ||||
| initialFamBody dflag style name args = initialHead (getFnName dflag style name) | ||||
|                                          (map (FnExplicitName . getFnName dflag style) args) | ||||
|                                          ++ " = ()" | ||||
| initialFamBody :: FnArgsInfo ty name | ||||
|                => DynFlags -> PprStyle -> name -> [name] -> String | ||||
| initialFamBody dflag style name args = | ||||
|     initialHead fnName fnArgs ++ " = ()" | ||||
|  where fnName = getFnName dflag style name | ||||
|        fnArgs = map (FnExplicitName . getFnName dflag style) args | ||||
| 
 | ||||
| initialHead :: String -> [FnArg] -> String | ||||
| initialHead fname args = | ||||
| @ -185,7 +213,8 @@ initialBodyArgs [] _ _ = [] | ||||
| initialBodyArgs (FnArgFunction:xs) vs (f:fs) = f : initialBodyArgs xs vs fs | ||||
| initialBodyArgs (FnArgNormal:xs)   (v:vs) fs = v : initialBodyArgs xs vs fs | ||||
| initialBodyArgs (FnExplicitName n:xs)  vs fs = n : initialBodyArgs xs vs fs | ||||
| initialBodyArgs _                  _      _  = error "This should never happen" -- Lists are infinite | ||||
| initialBodyArgs _                  _      _  = | ||||
|     error "initialBodyArgs: This should never happen" -- Lists are infinite | ||||
| 
 | ||||
| initialHead1 :: String -> [FnArg] -> [String] -> String | ||||
| initialHead1 fname args elts = | ||||
| @ -211,7 +240,8 @@ instance FnArgsInfo (G.HsType G.RdrName) (G.RdrName) where | ||||
|   getFnName dflag style name = showOccName dflag style $ Gap.occName name | ||||
|   getFnArgs (G.HsForAllTy _ _ _ (L _ iTy))  = getFnArgs iTy | ||||
|   getFnArgs (G.HsParTy (L _ iTy))           = getFnArgs iTy | ||||
|   getFnArgs (G.HsFunTy (L _ lTy) (L _ rTy)) = (if fnarg lTy then FnArgFunction else FnArgNormal):getFnArgs rTy | ||||
|   getFnArgs (G.HsFunTy (L _ lTy) (L _ rTy)) = | ||||
|       (if fnarg lTy then FnArgFunction else FnArgNormal):getFnArgs rTy | ||||
|     where fnarg ty = case ty of | ||||
|               (G.HsForAllTy _ _ _ (L _ iTy)) -> fnarg iTy | ||||
|               (G.HsParTy (L _ iTy))          -> fnarg iTy | ||||
| @ -224,7 +254,8 @@ instance FnArgsInfo (HE.Type HE.SrcSpanInfo) (HE.Name HE.SrcSpanInfo) where | ||||
|   getFnName _ _ (HE.Symbol _ s) = s | ||||
|   getFnArgs (HE.TyForall _ _ _ iTy) = getFnArgs iTy | ||||
|   getFnArgs (HE.TyParen _ iTy)      = getFnArgs iTy | ||||
|   getFnArgs (HE.TyFun _ lTy rTy)    = (if fnarg lTy then FnArgFunction else FnArgNormal):getFnArgs rTy | ||||
|   getFnArgs (HE.TyFun _ lTy rTy)    = | ||||
|       (if fnarg lTy then FnArgFunction else FnArgNormal):getFnArgs rTy | ||||
|     where fnarg ty = case ty of | ||||
|               (HE.TyForall _ _ _ iTy) -> fnarg iTy | ||||
|               (HE.TyParen _ iTy)      -> fnarg iTy | ||||
| @ -239,7 +270,10 @@ instance FnArgsInfo Type Id where | ||||
|             maybe (if Ty.isPredTy lTy then getFnArgs' rTy else FnArgNormal:getFnArgs' rTy) | ||||
|                   (\_ -> FnArgFunction:getFnArgs' rTy) | ||||
|                   $ Ty.splitFunTy_maybe lTy | ||||
|           getFnArgs' ty | Just (_,iTy) <- Ty.splitForAllTy_maybe ty = getFnArgs' iTy | ||||
| 
 | ||||
|           getFnArgs' ty | Just (_,iTy) <- Ty.splitForAllTy_maybe ty = | ||||
|               getFnArgs' iTy | ||||
| 
 | ||||
|           getFnArgs' _ = [] | ||||
| 
 | ||||
| -- Infinite supply of variable and function variable names | ||||
| @ -247,7 +281,9 @@ infiniteVars, infiniteFns :: [String] | ||||
| infiniteVars = infiniteSupply ["x","y","z","t","u","v","w"] | ||||
| infiniteFns  = infiniteSupply ["f","g","h"] | ||||
| infiniteSupply :: [String] -> [String] | ||||
| infiniteSupply initialSupply = initialSupply ++ concatMap (\n -> map (\v -> v ++ show n) initialSupply) ([1 .. ] :: [Integer]) | ||||
| infiniteSupply initialSupply = | ||||
|     initialSupply ++ concatMap (\n -> map (\v -> v ++ show n) initialSupply) | ||||
|                                ([1 .. ] :: [Integer]) | ||||
| 
 | ||||
| -- Check whether a String is a symbol name | ||||
| isSymbolName :: String -> Bool | ||||
| @ -273,14 +309,15 @@ refine file lineNo colNo expr = ghandle handler body | ||||
|         p <- G.parseModule modSum | ||||
|         tcm@TypecheckedModule{tm_typechecked_source = tcs} <- G.typecheckModule p | ||||
|         ety <- G.exprType expr | ||||
|         whenFound opt (findVar dflag style tcm tcs lineNo colNo) $ \(loc, name, rty, paren) -> | ||||
|           let eArgs = getFnArgs ety | ||||
|               rArgs = getFnArgs rty | ||||
|               diffArgs' = length eArgs - length rArgs | ||||
|               diffArgs  = if diffArgs' < 0 then 0 else diffArgs' | ||||
|               iArgs = take diffArgs eArgs | ||||
|               text = initialHead1 expr iArgs (infinitePrefixSupply name) | ||||
|            in (fourInts loc, doParen paren text) | ||||
|         whenFound opt (findVar dflag style tcm tcs lineNo colNo) $ | ||||
|           \(loc, name, rty, paren) -> | ||||
|               let eArgs = getFnArgs ety | ||||
|                   rArgs = getFnArgs rty | ||||
|                   diffArgs' = length eArgs - length rArgs | ||||
|                   diffArgs  = if diffArgs' < 0 then 0 else diffArgs' | ||||
|                   iArgs = take diffArgs eArgs | ||||
|                   text = initialHead1 expr iArgs (infinitePrefixSupply name) | ||||
|                in (fourInts loc, doParen paren text) | ||||
| 
 | ||||
|     handler (SomeException _) = emptyResult =<< options | ||||
| 
 | ||||
| @ -289,14 +326,16 @@ findVar :: GhcMonad m => DynFlags -> PprStyle | ||||
|                       -> G.TypecheckedModule -> G.TypecheckedSource | ||||
|                       -> Int -> Int -> m (Maybe (SrcSpan, String, Type, Bool)) | ||||
| findVar dflag style tcm tcs lineNo colNo = | ||||
|   let lst = sortBy (cmp `on` G.getLoc) $ listifySpans tcs (lineNo, colNo) :: [G.LHsExpr Id] | ||||
|   let lst = sortBy (cmp `on` G.getLoc) $ | ||||
|                 listifySpans tcs (lineNo, colNo) :: [G.LHsExpr Id] | ||||
|   in case lst of | ||||
|       e@(L _ (G.HsVar i)):others -> | ||||
|         do tyInfo <- Gap.getType tcm e | ||||
|            let name = getFnName dflag style i | ||||
|            if (name == "undefined" || head name == '_') && isJust tyInfo | ||||
|               then let Just (s,t) = tyInfo | ||||
|                        b = case others of  -- If inside an App, we need parenthesis | ||||
|                        b = case others of  -- If inside an App, we need | ||||
|                                            -- parenthesis | ||||
|                              [] -> False | ||||
|                              L _ (G.HsApp (L _ a1) (L _ a2)):_ -> | ||||
|                                isSearchedVar i a1 || isSearchedVar i a2 | ||||
| @ -333,24 +372,29 @@ auto file lineNo colNo = ghandle handler body | ||||
|         opt <- options | ||||
|         modSum <- Gap.fileModSummary file | ||||
|         p <- G.parseModule modSum | ||||
|         tcm@TypecheckedModule{tm_typechecked_source = tcs | ||||
|                              ,tm_checked_module_info = minfo} <- G.typecheckModule p | ||||
|         tcm@TypecheckedModule { | ||||
|                  tm_typechecked_source = tcs | ||||
|                , tm_checked_module_info = minfo | ||||
|                } <- G.typecheckModule p | ||||
|         whenFound' opt (findVar dflag style tcm tcs lineNo colNo) $ \(loc, _name, rty, paren) -> do | ||||
|           topLevel <- getEverythingInTopLevel minfo | ||||
|           let (f,pats) = getPatsForVariable tcs (lineNo,colNo) | ||||
|               -- Remove self function to prevent recursion, and id to trim cases | ||||
|               -- Remove self function to prevent recursion, and id to trim | ||||
|               -- cases | ||||
|               filterFn (n,_) = let funName = G.getOccString n | ||||
|                                    recName = G.getOccString (G.getName f) | ||||
|                                in funName `notElem` recName:notWantedFuns | ||||
|               -- Find without using other functions in top-level | ||||
|               localBnds = M.unions $ map (\(L _ pat) -> getBindingsForPat pat) pats | ||||
|               localBnds = M.unions $ | ||||
|                   map (\(L _ pat) -> getBindingsForPat pat) pats | ||||
|               lbn = filter filterFn (M.toList localBnds) | ||||
|           djinnsEmpty <- djinn True (Just minfo) lbn rty (Max 10) 100000 | ||||
|           let -- Find with the entire top-level | ||||
|               almostEnv = M.toList $ M.union localBnds topLevel | ||||
|               env = filter filterFn almostEnv | ||||
|           djinns <- djinn True (Just minfo) env rty (Max 10) 100000 | ||||
|           return (fourInts loc, map (doParen paren) $ nub (djinnsEmpty ++ djinns)) | ||||
|           return ( fourInts loc | ||||
|                  , map (doParen paren) $ nub (djinnsEmpty ++ djinns)) | ||||
| 
 | ||||
|     handler (SomeException _) = emptyResult =<< options | ||||
| 
 | ||||
| @ -372,7 +416,8 @@ getEverythingInTopLevel m = do | ||||
| 
 | ||||
| tyThingsToInfo :: [Ty.TyThing] -> M.Map G.Name Type | ||||
| tyThingsToInfo [] = M.empty | ||||
| tyThingsToInfo (G.AnId i : xs) = M.insert (G.getName i) (Ty.varType i) (tyThingsToInfo xs) | ||||
| tyThingsToInfo (G.AnId i : xs) = | ||||
|     M.insert (G.getName i) (Ty.varType i) (tyThingsToInfo xs) | ||||
| -- Getting information about constructors is not needed | ||||
| -- because they will be added by djinn-ghc when traversing types | ||||
| -- #if __GLASGOW_HASKELL__ >= 708 | ||||
| @ -385,7 +430,8 @@ tyThingsToInfo (_:xs) = tyThingsToInfo xs | ||||
| -- Find the Id of the function and the pattern where the hole is located | ||||
| getPatsForVariable :: G.TypecheckedSource -> (Int,Int) -> (Id, [Ty.LPat Id]) | ||||
| getPatsForVariable tcs (lineNo, colNo) = | ||||
|   let (L _ bnd:_) = sortBy (cmp `on` G.getLoc) $ listifySpans tcs (lineNo, colNo) :: [G.LHsBind Id] | ||||
|   let (L _ bnd:_) = sortBy (cmp `on` G.getLoc) $ | ||||
|                       listifySpans tcs (lineNo, colNo) :: [G.LHsBind Id] | ||||
|    in case bnd of | ||||
|         G.PatBind { Ty.pat_lhs = L ploc pat }  -> case pat of | ||||
|           Ty.ConPatIn (L _ i) _ -> (i, [L ploc pat]) | ||||
| @ -405,25 +451,34 @@ getBindingsForPat :: Ty.Pat Id -> M.Map G.Name Type | ||||
| getBindingsForPat (Ty.VarPat i) = M.singleton (G.getName i) (Ty.varType i) | ||||
| getBindingsForPat (Ty.LazyPat (L _ l)) = getBindingsForPat l | ||||
| getBindingsForPat (Ty.BangPat (L _ b)) = getBindingsForPat b | ||||
| getBindingsForPat (Ty.AsPat (L _ a) (L _ i)) = M.insert (G.getName a) (Ty.varType a) (getBindingsForPat i) | ||||
| getBindingsForPat (Ty.AsPat (L _ a) (L _ i)) = | ||||
|     M.insert (G.getName a) (Ty.varType a) (getBindingsForPat i) | ||||
| #if __GLASGOW_HASKELL__ >= 708 | ||||
| getBindingsForPat (Ty.ListPat  l _ _) = M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.ListPat  l _ _) = | ||||
|     M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| #else | ||||
| getBindingsForPat (Ty.ListPat  l _)   = M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.ListPat  l _)   = | ||||
|     M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| #endif | ||||
| getBindingsForPat (Ty.TuplePat l _ _) = M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.PArrPat  l _)   = M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.TuplePat l _ _) = | ||||
|     M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.PArrPat  l _)   = | ||||
|     M.unions $ map (\(L _ i) -> getBindingsForPat i) l | ||||
| getBindingsForPat (Ty.ViewPat _ (L _ i) _) = getBindingsForPat i | ||||
| getBindingsForPat (Ty.SigPatIn  (L _ i) _) = getBindingsForPat i | ||||
| getBindingsForPat (Ty.SigPatOut (L _ i) _) = getBindingsForPat i | ||||
| getBindingsForPat (Ty.ConPatIn (L _ i) d) = M.insert (G.getName i) (Ty.varType i) (getBindingsForRecPat d) | ||||
| getBindingsForPat (Ty.ConPatIn (L _ i) d) = | ||||
|     M.insert (G.getName i) (Ty.varType i) (getBindingsForRecPat d) | ||||
| getBindingsForPat (Ty.ConPatOut { Ty.pat_args = d }) = getBindingsForRecPat d | ||||
| getBindingsForPat _ = M.empty | ||||
| 
 | ||||
| getBindingsForRecPat :: Ty.HsConPatDetails Id -> M.Map G.Name Type | ||||
| getBindingsForRecPat (Ty.PrefixCon args) = M.unions $ map (\(L _ i) -> getBindingsForPat i) args | ||||
| getBindingsForRecPat (Ty.InfixCon (L _ a1) (L _ a2)) = M.union (getBindingsForPat a1) (getBindingsForPat a2) | ||||
| getBindingsForRecPat (Ty.RecCon (Ty.HsRecFields { Ty.rec_flds = fields })) = getBindingsForRecFields fields | ||||
|   where getBindingsForRecFields [] = M.empty | ||||
|         getBindingsForRecFields (Ty.HsRecField { Ty.hsRecFieldArg = (L _ a) } : fs) = | ||||
|           M.union (getBindingsForPat a) (getBindingsForRecFields fs) | ||||
| getBindingsForRecPat (Ty.PrefixCon args) = | ||||
|     M.unions $ map (\(L _ i) -> getBindingsForPat i) args | ||||
| getBindingsForRecPat (Ty.InfixCon (L _ a1) (L _ a2)) = | ||||
|     M.union (getBindingsForPat a1) (getBindingsForPat a2) | ||||
| getBindingsForRecPat (Ty.RecCon (Ty.HsRecFields { Ty.rec_flds = fields })) = | ||||
|     getBindingsForRecFields fields | ||||
|  where getBindingsForRecFields [] = M.empty | ||||
|        getBindingsForRecFields (Ty.HsRecField {Ty.hsRecFieldArg = (L _ a)}:fs) = | ||||
|          M.union (getBindingsForPat a) (getBindingsForRecFields fs) | ||||
|  | ||||
| @ -29,23 +29,23 @@ ghcOptHelp = " [-g GHC_opt1 -g GHC_opt2 ...] " | ||||
| usage :: String | ||||
| usage =    progVersion | ||||
|         ++ "Usage:\n" | ||||
|         ++ "\t ghc-mod list" ++ ghcOptHelp ++ "[-l] [-d]\n" | ||||
|         ++ "\t ghc-mod lang [-l]\n" | ||||
|         ++ "\t ghc-mod flag [-l]\n" | ||||
|         ++ "\t ghc-mod browse" ++ ghcOptHelp ++ "[-l] [-o] [-d] [-q] [<package>:]<module> [[<package>:]<module> ...]\n" | ||||
|         ++ "\t ghc-mod check" ++ ghcOptHelp ++ "<HaskellFiles...>\n" | ||||
|         ++ "\t ghc-mod expand" ++ ghcOptHelp ++ "<HaskellFiles...>\n" | ||||
|         ++ "\t ghc-mod debug" ++ ghcOptHelp ++ "\n" | ||||
|         ++ "\t ghc-mod info" ++ ghcOptHelp ++ "<HaskellFile> <module> <expression>\n" | ||||
|         ++ "\t ghc-mod type" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod split" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod sig" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod refine" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no> <expression>\n" | ||||
|         ++ "\t ghc-mod auto" ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod find <symbol>\n" | ||||
|         ++ "\t ghc-mod lint [-h opt] <HaskellFile>\n" | ||||
|         ++ "\t ghc-mod list   " ++ ghcOptHelp ++ "[-l] [-d]\n" | ||||
|         ++ "\t ghc-mod lang    [-l]\n" | ||||
|         ++ "\t ghc-mod flag    [-l]\n" | ||||
|         ++ "\t ghc-mod browse " ++ ghcOptHelp ++ "[-l] [-o] [-d] [-q] [<package>:]<module> [[<package>:]<module> ...]\n" | ||||
|         ++ "\t ghc-mod check  " ++ ghcOptHelp ++ "<HaskellFiles...>\n" | ||||
|         ++ "\t ghc-mod expand " ++ ghcOptHelp ++ "<HaskellFiles...>\n" | ||||
|         ++ "\t ghc-mod debug  " ++ ghcOptHelp ++ "\n" | ||||
|         ++ "\t ghc-mod info   " ++ ghcOptHelp ++ "<HaskellFile> <module> <expression>\n" | ||||
|         ++ "\t ghc-mod type   " ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod split  " ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod sig    " ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod refine " ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no> <expression>\n" | ||||
|         ++ "\t ghc-mod auto   " ++ ghcOptHelp ++ "<HaskellFile> <module> <line-no> <column-no>\n" | ||||
|         ++ "\t ghc-mod find    <symbol>\n" | ||||
|         ++ "\t ghc-mod lint    [-h opt] <HaskellFile>\n" | ||||
|         ++ "\t ghc-mod root\n" | ||||
|         ++ "\t ghc-mod doc <module>\n" | ||||
|         ++ "\t ghc-mod doc     <module>\n" | ||||
|         ++ "\t ghc-mod boot\n" | ||||
|         ++ "\t ghc-mod version\n" | ||||
|         ++ "\t ghc-mod help\n" | ||||
| @ -56,31 +56,35 @@ usage =    progVersion | ||||
| ---------------------------------------------------------------- | ||||
| 
 | ||||
| argspec :: [OptDescr (Options -> Options)] | ||||
| argspec = [ Option "l" ["tolisp"] | ||||
|             (NoArg (\opts -> opts { outputStyle = LispStyle })) | ||||
|             "print as a list of Lisp" | ||||
|           , Option "h" ["hlintOpt"] | ||||
|             (ReqArg (\h opts -> opts { hlintOpts = h : hlintOpts opts }) "hlintOpt") | ||||
|             "hlint options" | ||||
|           , Option "g" ["ghcOpt"] | ||||
|             (ReqArg (\g opts -> opts { ghcUserOptions = g : ghcUserOptions opts }) "ghcOpt") | ||||
|             "GHC options" | ||||
|           , Option "v" ["verbose"] | ||||
|             (NoArg (\opts -> opts { ghcUserOptions = "-v" : ghcUserOptions opts })) | ||||
|             "verbose" | ||||
|           , Option "o" ["operators"] | ||||
|             (NoArg (\opts -> opts { operators = True })) | ||||
|             "print operators, too" | ||||
|           , Option "d" ["detailed"] | ||||
|             (NoArg (\opts -> opts { detailed = True })) | ||||
|             "print detailed info" | ||||
|           , Option "q" ["qualified"] | ||||
|             (NoArg (\opts -> opts { qualified = True })) | ||||
|             "show qualified names" | ||||
|           , Option "b" ["boundary"] | ||||
|             (ReqArg (\s opts -> opts { lineSeparator = LineSeparator s }) "sep") | ||||
|             "specify line separator (default is Nul string)" | ||||
|           ] | ||||
| argspec = | ||||
|     let option s l udsc dsc = Option s l dsc udsc | ||||
|         reqArg udsc dsc = ReqArg dsc udsc | ||||
|     in | ||||
|       [ option "l" ["tolisp"] "print as a list of Lisp" $ | ||||
|                NoArg $ \o -> o { outputStyle = LispStyle } | ||||
| 
 | ||||
|       , option "h" ["hlintOpt"] "hlint options" $ | ||||
|                reqArg "hlintOpt" $ \h o -> o { hlintOpts = h : hlintOpts o } | ||||
| 
 | ||||
|       , option "g" ["ghcOpt"] "GHC options" $ | ||||
|                reqArg "ghcOpt" $ \g o -> | ||||
|                    o { ghcUserOptions = g : ghcUserOptions o } | ||||
| 
 | ||||
|       , option "v" ["verbose"] "verbose" $ | ||||
|                NoArg $ \o -> o { ghcUserOptions = "-v" : ghcUserOptions o } | ||||
| 
 | ||||
|       , option "o" ["operators"] "print operators, too" $ | ||||
|                NoArg $ \o -> o { operators = True } | ||||
| 
 | ||||
|       , option "d" ["detailed"] "print detailed info" $ | ||||
|                NoArg $ \o -> o { detailed = True } | ||||
| 
 | ||||
|       , option "q" ["qualified"] "show qualified names" $ | ||||
|                NoArg $ \o -> o { qualified = True } | ||||
| 
 | ||||
|       , option "b" ["boundary"] "specify line separator (default is Nul string)"$ | ||||
|                reqArg "sep" $ \s o -> o { lineSeparator = LineSeparator s } | ||||
|   ] | ||||
| 
 | ||||
| parseArgs :: [OptDescr (Options -> Options)] -> [String] -> (Options, [String]) | ||||
| parseArgs spec argv | ||||
| @ -102,9 +106,7 @@ instance Exception GHCModError | ||||
| 
 | ||||
| main :: IO () | ||||
| main = flip E.catches handlers $ do | ||||
| -- #if __GLASGOW_HASKELL__ >= 611 | ||||
|     hSetEncoding stdout utf8 | ||||
| -- #endif | ||||
|     args <- getArgs | ||||
|     let (opt,cmdArg) = parseArgs argspec args | ||||
|     let cmdArg0 = cmdArg !. 0 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Daniel Gröber
						Daniel Gröber