Module

Whine.Types

Package
purescript-whine-core
Repository
collegevine/purescript-whine

#Handle Source

newtype Handle :: (Type -> Type) -> Typenewtype Handle astNode

This function is the core functionality of a linting rule: it takes an AST node and reports anything wrong with it as effects in the monad.

The type variable e is a peculiarity of how the language-cst-parser library is structured: the whole AST is parametrized by this type, which represents possible errors with parsing. When the tree is fully parsed successfully, e is set to Void. Otherwise it's some error type.

Because for the purposes of this library we don't actually care whether the parsing was successful, the handler function is polymorphic in e. But we have to have a RangeOf instance for it, because it's a prerequisite for other RangeOf instances for AST nodes, and we do need those, because we need to report a source location for every violation.

Constructors

#RuleId Source

type RuleId = String

#Rule Source

type Rule = { onBinder :: Handle Binder, onDecl :: Handle Declaration, onExpr :: Handle Expr, onModule :: Handle Module, onModuleExport :: Handle Export, onModuleImport :: Handle ImportDecl, onType :: Handle Type }

A linting rule is just a collection of Handle functions for different types of AST nodes. See comments on Handle for explanation of how it works.

When constructing a rule, use the emptyRule value as base, so you don't have to provide every field.

#Violation Source

type Violation :: Row Type -> Typetype Violation r = { message :: String, source :: Maybe SourceRange | r }

Violation is an open record. When generated by a rule implementation, it starts out with just source and message, but at higher stack levels gets annotated with ID of the rule that created the violation (see WithRule), with the file whence the violation came (see WithFile), and with a flag showing if this particular violation was muted (see WithMuted).

#Violations Source

#WithRule Source

type WithRule :: Row Type -> Row Typetype WithRule r = (rule :: RuleId | r)

See comments on Violation

#WithMuted Source

type WithMuted :: Row Type -> Row Typetype WithMuted r = (muted :: Boolean | r)

See comments on Violation

#WithFile Source

type WithFile :: Row Type -> Row Typetype WithFile r = (file :: File | r)

See comments on Violation

#RuleFactory Source

type RuleFactory = JSON -> Either String Rule

See comments on ruleFactory

#RuleFactories Source

type RuleFactories = Array (RuleId /\ RuleFactory)

See comments on ruleFactory

#File Source

type File = { lines :: Maybe (Array String), path :: FilePath }

#MonadRules Source

class MonadRules :: Row Type -> (Type -> Type) -> Constraintclass (Monad m, MonadLog m) <= MonadRules v m | m -> v where

The monad in which each individual rule is run.

Members

#ruleFactory Source

ruleFactory :: forall args. RuleId -> Codec args -> (args -> Rule) -> RuleId /\ RuleFactory

This function is intended to pair rules with their IDs. Every rule would take its own args and provide a JSON codec to decode the args, and the list of possible rules and their IDs would be constructed like this:

factories :: ∀ m. RuleFactories m
factories =
  [ ruleFactory "RuleOne" ruleOneArgsCodec ruleOne
  , ruleFactory "RuleTwo" ruleTwoArgsCodec ruleTwo
  ]

ruleOne :: { arg :: Int, anotherArg :: String } -> Rule m
ruleTwo :: {} -> Rule m

ruleFactory takes care of parsing the arguments and reporting any errors, so that the actual rule implementation only has to deal with strongly typed arguments.

#emptyRule Source