hlint-1.9.18: Source code suggestions

Safe HaskellNone
LanguageHaskell98

Language.Haskell.HLint2

Contents

Description

WARNING: This module represents the evolving second version of the HLint API. It will be deleted in favour of Language.Haskell.HLint3 in the next major version.

This module provides a way to apply HLint hints. As an example of approximating the hlint experience:

(flags, classify, hint) <- autoSettings
Right m <- parseModuleEx flags "MyFile.hs" Nothing
print $ applyHints classify hint [m]

Synopsis

Documentation

applyHints :: [Classify] -> Hint -> [(Module SrcSpanInfo, [Comment])] -> [Idea] Source

Given a way of classifying results, and a Hint, apply to a set of modules generating a list of Ideas. The Idea values will be ordered within a file.

Idea data type

data Idea Source

An idea suggest by a Hint.

Constructors

Idea 

Fields

ideaModule :: String

The module the idea applies to, may be "" if the module cannot be determined or is a result of cross-module hints.

ideaDecl :: String

The declaration the idea applies to, typically the function name, but may be a type name.

ideaSeverity :: Severity

The severity of the idea, e.g. Warning.

ideaHint :: String

The name of the hint that generated the idea, e.g. "Use reverse".

ideaSpan :: SrcSpan

The source code the idea relates to.

ideaFrom :: String

The contents of the source code the idea relates to.

ideaTo :: Maybe String

The suggested replacement, or Nothing for no replacement (e.g. on parse errors).

ideaNote :: [Note]

Notes about the effect of applying the replacement.

Instances

data Severity Source

How severe an issue is.

Constructors

Ignore

The issue has been explicitly ignored and will usually be hidden (pass --show on the command line to see ignored ideas).

Warning

Warnings are things that some people may consider improvements, but some may not.

Error

Errors are suggestions that are nearly always a good idea to apply.

data Note Source

A note describing the impact of the replacement.

Constructors

IncreasesLaziness

The replacement is increases laziness, for example replacing reverse (reverse x) with x makes the code lazier.

DecreasesLaziness

The replacement is decreases laziness, for example replacing (fst x, snd x) with x makes the code stricter.

RemovesError String

The replacement removes errors, for example replacing foldr1 (+) with sum removes an error on [], and might contain the text "on []".

ValidInstance String String

The replacement assumes standard type class lemmas, a hint with the note ValidInstance "Eq" "x" might only be valid if the x variable has a reflexive Eq instance.

Note String

An arbitrary note.

Instances

Settings

data Classify Source

How to classify an Idea. If any matching field is "" then it matches everything.

Constructors

Classify 

Fields

classifySeverity :: Severity

Severity to set the Idea to.

classifyHint :: String

Match on Idea field ideaHint.

classifyModule :: String

Match on Idea field ideaModule.

classifyDecl :: String

Match on Idea field ideaDecl.

Instances

getHLintDataDir :: IO FilePath Source

Get the Cabal configured data directory of HLint

autoSettings :: IO (ParseFlags, [Classify], Hint) Source

The function produces a tuple containg ParseFlags (for parseModuleEx), and Classify and Hint for applyHints. It approximates the normal HLint configuration steps, roughly:

  1. Use findSettings to find and load the HLint settings files.
  2. Use readSettings to interpret the settings files, producing HintRule values (LHS ==> RHS replacements) and Classify values to assign Severity ratings to hints.
  3. Use builtinHints and hintRules to generate a Hint value.
  4. Take all fixities from the findSettings modules and put them in the ParseFlags.

findSettings :: FilePath -> FilePath -> Maybe String -> IO ([String], [Module SrcSpanInfo]) Source

Given the data directory (where the hlint data files reside, see getHLintDataDir), and a filename to read, and optionally that file's contents, produce a pair containing:

  1. Builtin hints to use, e.g. List, which should be resolved using builtinHints.
  2. A list of modules containing hints, suitable for processing with readSettings.

Any parse failures will result in an exception.

readSettings :: Module SrcSpanInfo -> ([Classify], [HintRule]) Source

Given a module containing HLint settings information return the Classify rules and the HintRule expressions. Any fixity declarations will be discarded, but any other unrecognised elements will result in an exception.

Hints

data Hint Source

Functions to generate hints, combined using the Monoid instance.

Constructors

Hint 

Fields

hintModules :: [(Scope, Module SrcSpanInfo)] -> [Idea]

Given a list of modules (and their scope information) generate some Ideas.

hintModule :: Scope -> Module SrcSpanInfo -> [Idea]

Given a single module and its scope information generate some Ideas.

hintDecl :: Scope -> Module SrcSpanInfo -> Decl SrcSpanInfo -> [Idea]

Given a declaration (with a module and scope) generate some Ideas. This function will be partially applied with one module/scope, then used on multiple Decl values.

hintComment :: Comment -> [Idea]

Given a comment generate some Ideas.

Instances

builtinHints :: [(String, Hint)] Source

A list of builtin hints, currently including entries such as "List" and "Bracket".

data HintRule Source

A LHS ==> RHS style hint rule.

Constructors

HintRule 

Fields

hintRuleSeverity :: Severity

Default severity for the hint.

hintRuleName :: String

Name for the hint.

hintRuleScope :: Scope

Module scope in which the hint operates.

hintRuleLHS :: Exp SrcSpanInfo

LHS

hintRuleRHS :: Exp SrcSpanInfo

RHS

hintRuleSide :: Maybe (Exp SrcSpanInfo)

Side condition, typically specified with where _ = ....

hintRuleNotes :: [Note]

Notes about application of the hint.

Instances

Scopes

data Scope Source

Data type representing the modules in scope within a module. Created with scopeCreate and queried with scopeMatch and scopeMove. Note that the mempty Scope is not equivalent to scopeCreate on an empty module, due to the implicit import of Prelude.

Instances

scopeCreate :: Module SrcSpanInfo -> Scope Source

Create a Scope value from a module, based on the modules imports.

scopeMatch :: (Scope, QName SrcSpanInfo) -> (Scope, QName SrcSpanInfo) -> Bool Source

Given a two names in scopes, could they possibly refer to the same thing. This property is reflexive.

scopeMove :: (Scope, QName SrcSpanInfo) -> Scope -> QName SrcSpanInfo Source

Given a name in a scope, and a new scope, create a name for the new scope that will refer to the same thing. If the resulting name is ambiguous, it picks a plausible candidate.

Haskell-src-exts

parseModuleEx :: ParseFlags -> FilePath -> Maybe String -> IO (Either ParseError (Module SrcSpanInfo, [Comment])) Source

Parse a Haskell module. Applies the C pre processor, and uses best-guess fixity resolution if there are ambiguities. The filename - is treated as stdin. Requires some flags (often defaultParseFlags), the filename, and optionally the contents of that file.

data ParseError Source

A parse error from parseModuleEx.

Constructors

ParseError 

Fields

parseErrorLocation :: SrcLoc

Location of the error.

parseErrorMessage :: String

Message about the cause of the error.

parseErrorContents :: String

Snippet of several lines (typically 5) including a > character pointing at the faulty line.

data ParseFlags Source

Created with defaultParseFlags, used by parseModuleEx.

Constructors

ParseFlags 

Fields

encoding :: TextEncoding

How the file is read in (defaults to utf8).

cppFlags :: CppFlags

How the file is preprocessed (defaults to NoCpp).

hseFlags :: ParseMode

How the file is parsed (defaults to all fixities in the base package and most non-conflicting extensions).

data CppFlags Source

What C pre processor should be used.

Constructors

NoCpp

No pre processing is done.

CppSimple

Lines prefixed with # are stripped.

Cpphs CpphsOptions

The cpphs library is used.

File encodings

type Encoding = TextEncoding Source

An Encoding represents how characters are stored in a file. Created with defaultEncoding or readEncoding and used with useEncoding.

defaultEncoding :: Encoding Source

The system default encoding.

readEncoding :: String -> IO Encoding Source

Create an encoding from a string, or throw an error if the encoding is not known. Accepts many encodings including locale, utf-8 and all those supported by the GHC mkTextEncoding function.

useEncoding :: Handle -> Encoding -> IO () Source

Apply an encoding to a Handle.