hlint 1.6.4 → 1.6.5
raw patch · 10 files changed
+101/−38 lines, 10 files
Files
- data/hlint.1 +47/−0
- hlint.cabal +2/−1
- hlint.htm +6/−0
- src/HSE/All.hs +6/−6
- src/Hint/Match.hs +1/−1
- src/Main.hs +1/−1
- src/Report.hs +14/−2
- src/Settings.hs +4/−4
- src/Test.hs +1/−1
- src/Type.hs +19/−22
+ data/hlint.1 view
@@ -0,0 +1,47 @@+.TH HLINT "1" "July 2009" "HLint (C) Neil Mitchell 2006-2009" "User Commands"+.SH NAME+HLint \- haskell source code suggestions+.SH SYNOPSIS+.B hlint+[\fIfiles/directories\fR] [\fIoptions\fR]++.SH DESCRIPTION+\fIHLint\fR is a tool for suggesting possible improvements to Haskell code. These suggestions include ideas such as using alternative functions, simplifying code and spotting redundancies.++.SH OPTIONS+.TP+\fB\-?\fR \fB\-\-help\fR+Display help message+.TP+\fB\-v\fR \fB\-\-version\fR+Display version information+.TP+\fB\-r[file]\fR \fB\-\-report\fR[=\fIfile\fR]+Generate a report in HTML+.TP+\fB\-h\fR \fIfile\fR \fB\-\-hint\fR=\fIfile\fR+Hint/ignore file to use+.TP+\fB\-c\fR \fB\-\-color\fR, \fB\-\-colour\fR+Color the output (requires ANSI terminal)+.TP+\fB\-i\fR \fImessage\fR \fB\-\-ignore\fR=\fImessage\fR+Ignore a particular hint+.TP+\fB\-s\fR \fB\-\-show\fR+Show all ignored ideas+.TP+\fB\-t\fR \fB\-\-test\fR+Run in test mode+.SH EXAMPLE+"To check all Haskell files in 'src' and generate a report type:"+.IP+hlint src \fB\-\-report\fR+.SH "SEE ALSO"+The full documentation for+.B HLint+is available in \fI/usr/share/doc/hlint/hlint.html\fI.+.SH AUTHOR+This manual page was written by Joachim Breitner <nomeata@debian.org>+for the Debian system (but may be used by others).+
hlint.cabal view
@@ -1,7 +1,7 @@ cabal-version: >= 1.6 build-type: Simple name: hlint-version: 1.6.4+version: 1.6.5 license: GPL license-file: LICENSE category: Development@@ -22,6 +22,7 @@ Test.hs report.html hs-lint.el+ hlint.1 Extra-Source-Files: hlint.htm
hlint.htm view
@@ -189,6 +189,12 @@ If someone wanted to write such a feature, trying to work round some of the issues above, it would be happily accepted. </p> +<h3>Why doesn't the compiler automatically apply the optimisations?</h3>++<p>+ HLint doesn't suggest optimisations, it suggests code improvements - the intention is to make the code simpler, rather than making the code perform faster. The <a href="http://haskell.org/ghc/">GHC compiler</a> automatically applies many of the rules suggested by HLint, so HLint suggestions will rarely improve performance.+</p>+ <h2>Customizing the hints</h2> <p>
src/HSE/All.hs view
@@ -23,8 +23,8 @@ -- | Parse a Haskell module-parseString :: FilePath -> String -> ParseResult Module-parseString file = parseFileContentsWithMode mode . unlines . map f . lines+parseString :: Bool -> FilePath -> String -> ParseResult Module+parseString implies file = parseFileContentsWithMode mode . unlines . map f . lines where f x | "#" `isPrefixOf` dropWhile isSpace x = "" | otherwise = x@@ -32,15 +32,15 @@ mode = defaultParseMode {parseFilename = file ,extensions = extension- ,fixities = infix_ (-1) ["==>"] ++ baseFixities+ ,fixities = concat [infix_ (-1) ["==>"] | implies] ++ baseFixities } -- | On failure returns an empty module and prints to the console-parseFile :: FilePath -> IO (ParseResult Module)-parseFile file = do+parseFile :: Bool -> FilePath -> IO (ParseResult Module)+parseFile implies file = do src <- readFile file- return $ parseString file src+ return $ parseString implies file src -- | TODO: Use the fromParseResult in HSE once it gives source location
src/Hint/Match.hs view
@@ -28,7 +28,7 @@ findIdeas :: [Setting] -> NameMatch -> Decl -> [Idea] findIdeas matches nm decl =- [ idea (rank m) (hint m) loc x y+ [ idea (rankS m) (hintS m) loc x y | (loc, x) <- universeExp nullSrcLoc decl, not $ isParen x , m <- matches, Just y <- [matchIdea nm m x]]
src/Main.hs view
@@ -22,7 +22,7 @@ Cmd{..} <- getCmd if cmdTest then test else do settings <- readSettings cmdHintFiles- let extra = [Classify ("","") Ignore x | x <- cmdIgnore]+ let extra = [Classify Ignore x ("","") | x <- cmdIgnore] let apply :: FilePath -> IO [Idea] apply = fmap (fmap $ classify $ settings ++ extra) . applyHint (allHints settings) ideas <- liftM concat $ parallel [listM' =<< apply x | x <- cmdFiles]
src/Report.hs view
@@ -46,6 +46,9 @@ where id = mode ++ show i +code = hscolour False True ""++ writeIdea :: String -> Idea -> [String] writeIdea cls Idea{..} = ["<div class=" ++ show cls ++ ">"@@ -56,8 +59,17 @@ ,code to ,"</div>" ,""]- where- code = hscolour False True ""+++writeIdea cls ParseError{..} =+ ["<div class=" ++ show cls ++ ">"+ ,escapeHTML (showSrcLoc loc ++ " " ++ show rank ++ ": " ++ hint) ++ "<br/>"+ ,"Error message<br/>"+ ,"<pre>" ++ escapeHTML msg ++ "</pre>"+ ,"Code<br/>"+ ,code from+ ,"</div>"+ ,""] escapeHTML :: String -> String
src/Settings.hs view
@@ -25,7 +25,7 @@ -- currently it doesn't readHints :: FilePath -> IO [Module] readHints file = do- y <- fromParseResult `fmap` parseFile file+ y <- fromParseResult `fmap` parseFile True file ys <- concatMapM (f . fromNamed . importModule) $ moduleImports y return $ y:ys where@@ -37,8 +37,8 @@ -- Eta bound variable lifted so the filter only happens once per classify classify :: [Setting] -> Idea -> Idea-classify xs = \i -> i{rank=foldl'- (\r c -> if matchHint (hint c) (hint i) && matchFunc (func c) (func i) then rank c else r)+classify xs = \i -> if isParseError i then i else i{rank = foldl'+ (\r c -> if matchHint (hintS c) (hint i) && (isParseError i || matchFunc (funcS c) (func i)) then rankS c else r) (rank i) xs2} where xs2 = filter isClassify xs@@ -56,7 +56,7 @@ (UnGuardedRhs bod) (BDecls bind)]) | InfixApp lhs op rhs <- bod, opExp op ~= "==>" = [MatchExp rank (head names) (fromParen lhs) (fromParen rhs) (readSide bind)]- | otherwise = [Classify func rank n | n <- names2, func <- readFuncs bod]+ | otherwise = [Classify rank n func | n <- names2, func <- readFuncs bod] where names = getNames pats bod names2 = ["" | null names] ++ names
src/Test.hs view
@@ -69,7 +69,7 @@ parseTestFile file = do src <- readFile file return [(nm, createTest eqn)- | code <- f $ lines src, let modu = fromParseResult $ parseString file code+ | code <- f $ lines src, let modu = fromParseResult $ parseString False file code , let nm = nameMatch $ moduleImports modu , eqn <- concatMap getEquations $ moduleDecls modu] where
src/Type.hs view
@@ -27,43 +27,40 @@ -- Classify and MatchExp are read from the Settings file -- Idea are generated by the program+data Setting+ = Classify {rankS :: Rank, hintS :: String, funcS :: FuncName}+ | MatchExp {rankS :: Rank, hintS :: String, lhs :: Exp, rhs :: Exp, side :: Maybe Exp}+ deriving Show+ data Idea- = Classify {func :: FuncName, rank :: Rank, hint :: String}- | MatchExp {rank :: Rank, hint :: String, lhs :: Exp, rhs :: Exp, side :: Maybe Exp}- | Idea {func :: FuncName, rank :: Rank, hint :: String, loc :: SrcLoc, from :: String, to :: String}+ = Idea {func :: FuncName, rank :: Rank, hint :: String, loc :: SrcLoc, from :: String, to :: String}+ | ParseError {rank :: Rank, hint :: String, loc :: SrcLoc, msg :: String, from :: String} deriving Eq -type Setting = Idea - isClassify Classify{} = True; isClassify _ = False isMatchExp MatchExp{} = True; isMatchExp _ = False+isParseError ParseError{} = True; isParseError _ = False instance Show Idea where- show MatchExp{..} = unlines $ ("MatchExp " ++ show rank) :- map (\x -> " " ++ prettyPrint x) ([lhs,rhs] ++ maybeToList side)- show Classify{..} = unwords ["Classify",show func,show rank,show hint]-- show Idea{..} = unlines $- [showSrcLoc loc ++ " " ++ show rank ++ ": " ++ hint] ++ f "Found" from ++ f "Why not" to- where f msg x = (msg ++ ":") : map (" "++) (lines x)-- showList = showString . concatMap show+ show = showEx id showANSI :: IO (Idea -> String) showANSI = do prefs <- readColourPrefs- return $ showPrefsANSI prefs+ return $ showEx (hscolour prefs) -showPrefsANSI :: ColourPrefs -> Idea -> String-showPrefsANSI prefs Idea{..} = unlines $+showEx :: (String -> String) -> Idea -> String+showEx tt Idea{..} = unlines $ [showSrcLoc loc ++ " " ++ show rank ++ ": " ++ hint] ++ f "Found" from ++ f "Why not" to- where f msg x = (msg ++ ":") : map (" "++) (lines $ hscolour prefs x)-showPrefsANSI prefs x = show x+ where f msg x = (msg ++ ":") : map (" "++) (lines $ tt x) +showEx tt ParseError{..} = unlines $+ [showSrcLoc loc ++ " Parse error","Error message:"," " ++ msg,"Code:"] ++ map (" "++) (lines $ tt from) + -- The real key will be filled in by applyHint idea rank hint loc from to = Idea ("","") rank hint loc (f from) (f to) where f = dropWhile isSpace . prettyPrint@@ -88,12 +85,12 @@ applyHint :: Hint -> FilePath -> IO [Idea] applyHint h file = do src <- readFile file- case parseString file src of+ case parseString False file src of ParseFailed sl msg -> do let ticks = [" "," ","> "," "," "]- let bad = zipWith (++) ticks $ take 5 $ drop (srcLine sl - 3) $ lines src+ let bad = zipWith (++) ticks $ take 5 $ drop (srcLine sl - 3) $ lines src ++ [""] let bad2 = reverse $ dropWhile (all isSpace) $ reverse $ dropWhile (all isSpace) bad- return [Idea ("","") Warning "Parse error" sl msg (unlines bad2)]+ return [ParseError Warning "Parse error" sl msg (unlines bad2)] ParseOk m -> do let name = moduleName m let nm = nameMatch $ moduleImports m