diff --git a/.github/workflows/hlint.yml b/.github/workflows/hlint.yml index f39191b48a..053c49a03d 100644 --- a/.github/workflows/hlint.yml +++ b/.github/workflows/hlint.yml @@ -6,7 +6,7 @@ on: - '**' jobs: - build10: + hlint: name: "Hlint check run" runs-on: ubuntu-latest steps: @@ -15,11 +15,12 @@ jobs: - name: 'Installing' uses: rwe/actions-hlint-setup@v1 with: - version: '3.3.4' + version: '3.4' - name: 'Checking code' uses: rwe/actions-hlint-run@v1 with: - hlint-bin: "hlint --with-group=extra --hint=ghcide/.hlint.yaml" - path: '[ "ghcide/src", "ghcide/exe", "ghcide/bench/lib", "ghcide/bench/exe", "ghcide/bench/hist", "shake-bench/src", "ghcide/test/exe"]' + hlint-bin: "hlint --with-group=extra" + fail-on: error + path: . diff --git a/.hlint.yaml b/.hlint.yaml new file mode 100644 index 0000000000..e8cf2d9751 --- /dev/null +++ b/.hlint.yaml @@ -0,0 +1,185 @@ +# HLint configuration file +# https://github.com/ndmitchell/hlint +########################## + +# To run HLint do: +# $ hlint --git -j4 + +# Warnings currently triggered by our code +- ignore: {name: "Use <$>"} +- ignore: {name: "Use :"} +- ignore: {name: "Redundant do"} +- ignore: {name: "Avoid lambda"} +- ignore: {name: "Use newtype instead of data"} +- ignore: {name: "Use unless"} +- ignore: {name: "Move brackets to avoid $"} +- ignore: {name: "Eta reduce"} +- ignore: {name: "Parse error"} +- ignore: {name: "Reduce duplication"} +- ignore: {name: "Use ++"} +- ignore: {name: "Use $>"} +- ignore: {name: "Use section"} +- ignore: {name: "Use record patterns"} +- ignore: {name: "Use camelCase"} +- ignore: {name: "Use uncurry"} +- ignore: {name: "Avoid lambda using `infix`"} + +# Gives at least one suggestion we don't like. +- ignore: {name: "Use <=<"} +- ignore: {name: "Use zipFrom"} +- ignore: {name: "Use zipWithFrom"} + +# We are using the "redundant" return/pure to assign a name. We do not want to +# delete it. In particular, this is not an improvement: +# Found: +# do options <- somethingComplicated +# pure options +# Perhaps: +# do somethingComplicated +- ignore: {name: "Redundant return"} +- ignore: {name: "Redundant pure"} + +# Off by default hints we like +- warn: {name: Use module export list} + +# Condemn nub and friends +- warn: {lhs: nub (sort x), rhs: Data.List.Extra.nubSort x} +- warn: {lhs: nub, rhs: Data.List.Extra.nubOrd} +- warn: {lhs: nubBy, rhs: Data.List.Extra.nubOrdBy} +- warn: {lhs: Data.List.Extra.nubOn, rhs: Data.List.Extra.nubOrdOn} + +- functions: + # Things that are unsafe in Haskell base library + - name: unsafePerformIO + within: + - Development.IDE.Core.Shake + - Development.IDE.GHC.Util + - Development.IDE.Graph.Internal.Database + - Development.IDE.Graph.Internal.Paths + - Development.IDE.Graph.Internal.Profile + - Ide.Types + - Test.Hls + - Test.Hls.Command + - Wingman.Debug + - Wingman.Types + - AutoTupleSpec + - name: unsafeInterleaveIO + within: + - Development.IDE.LSP.LanguageServer + - {name: unsafeDupablePerformIO, within: []} + - name: unsafeCoerce + within: + - Ide.Plugin.Eval.Code + - Development.IDE.Core.Compile + - Development.IDE.Types.Shake + - Wingman.Judgements.SYB + - Ide.Plugin.Properties + + # Things that are a bit dangerous in the GHC API + - name: nameModule + within: + - Development.IDE.GHC.CoreFile + - Ide.Plugin.CallHierarchy.Internal + - Ide.Plugin.Rename + - Compat.HieBin + + # Partial functions + - name: Data.List.head + within: + - Main + - Experiments + - Development.IDE.Core.Shake + - Development.IDE.Plugin.CodeAction + - Development.IDE.Plugin.Completions + - Development.IDE.Plugin.CodeAction.ExactPrint + - Development.IDE.Session + - Development.IDE.Spans.Documentation + - Ide.Plugin.CallHierarchy.Internal + - TExpectedActual + - TRigidType + - TRigidType + - Ide.Plugin.Class + - Wingman.Tactics + + - name: Data.List.tail + within: + - Main + - Development.Benchmark.Rules + - Development.IDE.Plugin.CodeAction + - Development.IDE.Plugin.CodeAction.ExactPrint + - Development.IDE.Session + - IDE.Plugin.Eval.Code + - IDE.Plugin.Eval.Util + - UnificationSpec + + - name: Data.List.last + within: + - GenChangelogs + - Main + + - name: Data.List.init + within: [] + + - name: Data.List.foldl1' + within: [] + + - name: Data.List.foldr1' + within: [] + + - name: "Data.List.!!" + within: + - Main + - Experiments + - FunctionalCodeAction + - Development.IDE.Plugin.CodeAction + - Development.IDE.Plugin.Completions.Logic + - Development.IDE.Spans.Documentation + - Wingman.CaseSplit + - Wingman.Simplify + + + - name: Data.Text.head + within: + - Development.IDE.Plugin.CodeAction + - Development.IDE.Plugin.Completions.Logic + + - name: Data.Foldable.foldl1 + within: [] + + - name: Data.Foldable.foldr1 + within: + - Wingman.Tactics + + - name: Data.Maybe.fromJust + within: + - Experiments + - Main + - MultipleImports + - Progress + - Utils + - Development.IDE.Core.Compile + - Development.IDE.Core.Rules + - Development.IDE.Core.Shake + - Development.IDE.Plugin.Completions + - Development.IDE.Plugin.CodeAction.ExactPrint + - Development.IDE.Test + - Development.IDE.Graph.Internal.Profile + - Development.IDE.Graph.Internal.Rules + - Ide.Plugin.Class + + - name: "Data.Map.!" + within: + - Wingman.LanguageServer + + - name: "Data.IntMap.!" + within: [] + + - name: "Data.Vector.!" + within: [] + + - name: "GHC.Arr.!" + within: [] + +# We really do not want novel usages of restricted functions, and mere +# Warning is not enough to prevent those consistently; you need a build failure. +- error: {name: Avoid restricted function} diff --git a/ghcide/.hlint.yaml b/ghcide/.hlint.yaml deleted file mode 100644 index a188671994..0000000000 --- a/ghcide/.hlint.yaml +++ /dev/null @@ -1,180 +0,0 @@ -# HLint configuration file -# https://github.com/ndmitchell/hlint -########################## - -# To run HLint do: -# $ hlint --git -j4 - -# Warnings currently triggered by our code -- ignore: {name: "Use <$>"} -- ignore: {name: "Use :"} -- ignore: {name: "Redundant do"} -- ignore: {name: "Avoid lambda"} -- ignore: {name: "Use newtype instead of data"} -- ignore: {name: "Use unless"} -- ignore: {name: "Move brackets to avoid $"} -- ignore: {name: "Eta reduce"} -- ignore: {name: "Parse error"} -- ignore: {name: "Reduce duplication"} -- ignore: {name: "Use ++"} -- ignore: {name: "Use $>"} -- ignore: {name: "Use section"} -- ignore: {name: "Use record patterns"} -- ignore: {name: "Use camelCase"} -- ignore: {name: "Use uncurry"} -- ignore: {name: "Avoid lambda using `infix`"} - -# Gives at least one suggestion we don't like. -- ignore: {name: "Use <=<"} -- ignore: {name: "Use zipFrom"} -- ignore: {name: "Use zipWithFrom"} - -# We are using the "redundant" return/pure to assign a name. We do not want to -# delete it. In particular, this is not an improvement: -# Found: -# do options <- somethingComplicated -# pure options -# Perhaps: -# do somethingComplicated -- ignore: {name: "Redundant return"} -- ignore: {name: "Redundant pure"} - -# Off by default hints we like -- warn: {name: Use module export list} - -# Condemn nub and friends -- warn: {lhs: nub (sort x), rhs: Data.List.Extra.nubSort x} -- warn: {lhs: nub, rhs: Data.List.Extra.nubOrd} -- warn: {lhs: nubBy, rhs: Data.List.Extra.nubOrdBy} -- warn: {lhs: Data.List.Extra.nubOn, rhs: Data.List.Extra.nubOrdOn} - -# DA specific hints -- warn: {lhs: Data.Text.pack (DA.Pretty.renderPlain x), rhs: DA.Pretty.renderPlain x} -- warn: {lhs: Data.Text.Extended.pack (DA.Pretty.renderPlain x), rhs: DA.Pretty.renderPlain x} -- warn: {lhs: DA.Pretty.renderPlain (DA.Pretty.pretty x), rhs: DA.Pretty.renderPretty x} -- warn: {lhs: Data.Text.readFile, rhs: Data.Text.Extended.readFileUtf8} -- warn: {lhs: Data.Text.writeFile, rhs: Data.Text.Extended.writeFileUtf8} -- warn: {lhs: Data.Text.Lazy.readFile, rhs: Data.Text.Extended.readFileUtf8} -- warn: {lhs: Data.Text.Lazy.writeFile, rhs: Data.Text.Extended.writeFileUtf8} -- warn: {lhs: System.Environment.setEnv, rhs: System.Environment.Blank.setEnv} - -# Specify additional command line arguments -# -- arguments: ["--cpp-include=include"] - -- extensions: - - default: true - - # Extensions enabled by `bazel` and `da-ghci` by default. We ban them here - # to avoid useless pragmas piling up on the top of files. - - {name: BangPatterns, within: []} - - {name: DeriveDataTypeable, within: []} - - {name: DeriveFoldable, within: []} - - {name: DeriveFunctor, within: []} - - {name: DeriveGeneric, within: []} - - {name: DeriveTraversable, within: []} - - {name: FlexibleContexts, within: []} - - {name: GeneralizedNewtypeDeriving, within: []} - - {name: LambdaCase, within: []} - - {name: NamedFieldPuns, within: []} - - {name: RecordWildCards, within: []} - - {name: ScopedTypeVariables, within: []} - - {name: StandaloneDeriving, within: []} - - {name: TupleSections, within: []} - - {name: TypeApplications, within: []} - - {name: ViewPatterns, within: []} - - # Shady extensions - - name: CPP - within: - - Development.IDE.Compat - - Development.IDE.Core.FileStore - - Development.IDE.Core.FileUtils - - Development.IDE.Core.Compile - - Development.IDE.Core.Rules - - Development.IDE.Core.Tracing - - Development.IDE.GHC.Compat - - Development.IDE.GHC.Compat.Core - - Development.IDE.GHC.Compat.Env - - Development.IDE.GHC.Compat.ExactPrint - - Development.IDE.GHC.Compat.Iface - - Development.IDE.GHC.Compat.Logger - - Development.IDE.GHC.Compat.Outputable - - Development.IDE.GHC.Compat.Parser - - Development.IDE.GHC.Compat.Plugins - - Development.IDE.GHC.Compat.Units - - Development.IDE.GHC.Compat.Util - - Development.IDE.GHC.CPP - - Development.IDE.GHC.Dump - - Development.IDE.GHC.ExactPrint - - Development.IDE.GHC.Orphans - - Development.IDE.GHC.Util - - Development.IDE.Import.FindImports - - Development.IDE.LSP.Outline - - Development.IDE.Spans.Calculate - - Development.IDE.Spans.Documentation - - Development.IDE.Spans.Common - - Development.IDE.Spans.AtPoint - - Development.IDE.Spans.Pragmas - - Development.IDE.Plugin.CodeAction - - Development.IDE.Plugin.CodeAction.Args - - Development.IDE.Plugin.CodeAction.ExactPrint - - Development.IDE.Plugin.Completions - - Development.IDE.Plugin.Completions.Logic - - Development.IDE.Types.Location - -- flags: - - default: false - - {name: [-Wno-missing-signatures, -Wno-orphans, -Wno-overlapping-patterns, -Wno-incomplete-patterns, -Wno-missing-fields, -Wno-unused-matches]} - - {name: [-Wno-dodgy-imports,-Wno-incomplete-uni-patterns], within: [Main, Development.IDE.GHC.Compat, Development.IDE.GHC.Compat.Core, Development.Benchmark.Rules]} - - {name: [-Wno-unused-imports], within: [Development.IDE.GHC.Compat.Core]} - - {name: [-Wno-deprecations, -Wno-unticked-promoted-constructors], within: [Main, Experiments]} -# - modules: -# - {name: [Data.Set, Data.HashSet], as: Set} # if you import Data.Set qualified, it must be as 'Set' -# - {name: Control.Arrow, within: []} # Certain modules are banned entirely -# -- functions: - # Things that are unsafe in Haskell base library - - {name: unsafeInterleaveIO, within: [Development.IDE.LSP.LanguageServer]} - - {name: unsafeDupablePerformIO, within: []} - - {name: unsafeCoerce, within: [Ide.Plugin.Eval.Code, Development.IDE.Core.Compile, Development.IDE.Types.Shake]} - # Things that are a bit dangerous in the GHC API - - {name: nameModule, within: []} - # Partials and their legacy locations - - name: tail - within: - - Development.Benchmark.Rules - - Development.IDE.Plugin.CodeAction - - Development.IDE.Plugin.CodeAction.ExactPrint - - Development.IDE.Session - # ghcide/test/exe - - Main - # plugins/hls-tactics-plugin/test - # - UnificationSpec - -# We really do not want novel usages of restricted functions, and mere -# Warning is not enough to prevent those consistently; you need a build failure. -- error: {name: Avoid restricted function} - -# Add custom hints for this project -# -# Will suggest replacing "wibbleMany [myvar]" with "wibbleOne myvar" -# - error: {lhs: "wibbleMany [x]", rhs: wibbleOne x} - -# Turn on hints that are off by default -# -# Ban "module X(module X) where", to require a real export list -# - warn: {name: Use explicit module export list} -# -# Replace a $ b $ c with a . b $ c -# - group: {name: dollar, enabled: true} -# -# Generalise map to fmap, ++ to <> -# - group: {name: generalise, enabled: true} - -# Ignore some builtin hints -# - ignore: {name: Use let} -# - ignore: {name: Use const, within: SpecialModule} # Only within certain modules - -# Define some custom infix operators -# - fixity: infixr 3 ~^#^~ diff --git a/plugins/hls-hlint-plugin/.hlint.yaml b/plugins/hls-hlint-plugin/.hlint.yaml new file mode 100644 index 0000000000..7bcab2e941 --- /dev/null +++ b/plugins/hls-hlint-plugin/.hlint.yaml @@ -0,0 +1,2 @@ +# This is here so that the tests in this package don't +# pick up the configuration from HLS's own .hlint.yaml diff --git a/test/testdata/wErrorTest/src/WError.hs b/test/testdata/wErrorTest/src/WError.hs index 86e0ad2a3d..70db26840d 100644 --- a/test/testdata/wErrorTest/src/WError.hs +++ b/test/testdata/wErrorTest/src/WError.hs @@ -1,2 +1,3 @@ module WError where +{-# ANN module "HLint: ignore" #-} main = undefined