Commit Graph

147 Commits

Author SHA1 Message Date
ryndubei
46b1f42acc
Merge 27ff3674a5 into 6c78e13703 2024-11-05 12:19:09 +00:00
George Thomas
6c78e13703
Bump all dependency upper bounds (#183)
This allows us to build with GHC 9.10.

Co-authored-by: Teo Camarasu <teofilcamarasu@gmail.com>
2024-11-05 12:12:20 +00:00
Teo Camarasu
801491c9ae
Allow specifying rts options (#181)
Most rts options are disable without -rtsopts
2024-10-28 16:44:36 +00:00
ryndubei
56028d0c80
Fix test failure for ModuleRoot (#179) 2024-09-12 13:48:14 +01:00
Ollie Charles
bd6084776f
Correct CHANGELOG.md (#175) 2024-08-10 14:12:51 +00:00
Ollie Charles
fa9c7dc77b
Release 2.9.0 (#174) 2024-08-10 13:59:16 +00:00
Matthias Fischmann
7ba2aa4833
Re-implement getFilesIn (#165) 2024-08-10 13:38:37 +00:00
Ollie Charles
1cb230b1a9
Build with lens-5.3 (#173) 2024-08-10 14:34:13 +01:00
Pranay Sashank
5c34e70fbd
Improve performance of weeder when type-class-roots = false is set. (#172)
For analysing evidence uses we collect evidence uses in,

```haskell
requestedEvidence :: Map Declaration (Set Name)
```
In analyseEvidenceUses, we loop over all the names in all the sets of
the map, to construct dependency graph after calling `getEvidenceTree`
on the name. However, these names in sets across different
declarations are duplicated a lot. In one example in a repo at work,
we have 16961625 names in which only 200330 are unique. So now, we
instead pre-construct an evidence trees map `Map Name [Declaration]`
for all the unique name and perform a lookup in this map to construct
the graph.

In a private repo, the times before this change and after

```
❯ find . -name '*.hie'  | wc -l
   1097

❯ time result/bin/weeder # weeder from master

real    5m53.707s
user    5m50.350s
sys     0m2.206s

 ❯ time result/bin/weeder # weeder from this branch

real    0m34.008s
user    0m31.716s
sys     0m2.196s
```
2024-08-10 14:23:03 +01:00
ryndubei
5f23719e44
Add root-modules field (#157) 2024-06-10 12:30:04 +00:00
ryndubei
27ff3674a5 Extend TemplateHaskell test further 2024-06-10 14:13:46 +02:00
ryndubei
6aa54d64b5 Extend TemplateHaskell test 2024-06-10 14:06:29 +02:00
ryndubei
b8006fe0c8 Amend TemplateHaskell test for GHC98 2024-06-10 14:01:10 +02:00
ryndubei
0a5be87c88 Update TemplateHaskell.failing 2024-06-10 12:55:38 +02:00
ryndubei
057799f054 Add KindSignatures to TemplateHaskell test 2024-06-10 12:52:30 +02:00
ryndubei
3fc3f7a1d1 Add .failing for TemplateHaskell test 2024-06-10 12:50:55 +02:00
ryndubei
a43ecc61a3 Add TemplateHaskell test 2024-06-10 12:50:52 +02:00
Ollie Charles
26f0b93725
Don't use requireHsFiles when running tests (#167)
This causes a directory listing of `./.` to be forced (to find all `.hs` files), which for my checkout is a huge search. We don't really need this check though, so for tests it can be turned off. For me, this brings test execution time all the way down to <0.1s
2024-06-10 10:17:16 +00:00
George Thomas
919f629cb5
Use program-options instead of package * in README (#164)
This means the option is only passed to local packages, which avoids rebuilding dependencies.
2024-06-10 09:25:58 +00:00
Tom Sydney Kerckhove
d17ac85219
Show the package name in output too (#156)
Co-authored-by: Tom Sydney Kerckhove <syd@cs-syd.eu>
2024-06-09 13:52:05 +01:00
Tom Sydney Kerckhove
2fb2eb9cde
Sort weeds by column too (#155)
* Rewrite tests to use `tasty` & `tasty-golden`

* Sort weeds by column too

---------

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
Co-authored-by: Tom Sydney Kerckhove <syd@cs-syd.eu>
2024-06-09 13:29:12 +01:00
Ollie Charles
4a160e3498
Rewrite tests to use tasty & tasty-golden (#159)
This keeps the general shape of the test suite, but instead of using HSpec as the driver we now use tasty. The main benefit here is we can use `tasty-golden`, which makes it easier to update the golden files if the output legitimately changes.
2024-06-09 13:23:29 +01:00
Matthias Fischmann
4c4fbd6ea8
Add terminfo dep (for older ghc versions). (#162) 2024-06-09 10:23:12 +00:00
ryndubei
4a4d65d772
Display TOML parse error correctly (#161) 2024-06-08 15:42:12 +00:00
Ollie Charles
fdf3405677
Enable profiling in the dev shell by default (#160) 2024-06-08 14:24:59 +00:00
Ollie Charles
8bdda00524
Add hspec-discover to weeder.cabal (#158) 2024-06-08 13:17:42 +00:00
Tom Sydney Kerckhove
66fbba0523
Add weeder-nix to README.md (#151) 2024-04-29 10:11:52 +00:00
Andreas Abel
2a75a61782
Prune unused build-depends from executable (#145)
The executable just calls a main function from the library, so it only
depends on the library and `base`.
2024-02-22 15:02:07 +00:00
Ollie Charles
f7e880a65e
Release 2.8.0 (#144) 2024-02-15 11:34:18 +00:00
Ollie Charles
d9e2eaf9da
Use GHC 9.8 for CI and Nix shell (#143) 2024-02-15 11:20:34 +00:00
Taylor Fausak
0411e525dc
Upgrade to GHC 9.8.1 (#142) 2024-01-29 16:34:20 +00:00
ryndubei
a959f2e35a
Release 2.7.0 (#140) 2023-08-17 17:01:18 +00:00
ryndubei
a61f581a0e
Remove mention of root-classes (#139) 2023-08-11 15:24:27 +00:00
ryndubei
cead2c16ca
Add changie files (#138)
* Add changie files

* Mention -j and -N for #137
2023-08-10 13:00:28 +00:00
ryndubei
224542a16c
Improving performance (#137)
* outputableDeclarations optimisation

We now only match on declarations that can appear in the output (i.e.
with a span) when evaluating `roots` and `dead` in `runWeeder`,
instead of searching through all of them.

* initialGraph optimisation

`addAllDeclarations` turned out to largely be an unnecessary step:
`define` and `addDependency` already created vertices for the
involved declarations on their own.

This skips that step when unused-types = false, and otherwise
minimises the number of added vertices.

* Compile regex in Config.hs

GHC does not optimise repeated calls to `=~`, so we were
recompiling the regex for every single declaration we matched on.
This took up 15% of runtime and 40% of memory usage.

This compiles regular expressions in advance, immediately after we
parse the config file. Besides performance, this has the additional
benefit of making `runWeeder` a total function: regex parse
failures are now emitted alongside TOML errors.

* Parallel analysis

We now run most of our analysis on each `HieFile` in parallel.

Doing this in batches of 100 turned out to not have any performance
difference from doing this with 1 `HieFile` at a time.

Given enough cores, this can almost double Weeder's performance.

* getHieFiles as a stream

This uses lazy IO via `getChanContents` to begin analysis in
`runWeeder` before `[HieFile]` is fully read.

This neither benefits nor harms performance when Weeder is given
only one core, but improves performance by about the runtime of
`getHieFiles` when given two or more cores. On my machine this is
15%, but this may vary depending on disk speed.

As following uses of type class instances requires information from
all HIE files, it is now done in a separate stage via
`analyseEvidenceUses`, applied only after the initial analysis is
fully evaluated.

* Fix throwing exit code 2 in getHieFiles

Switches `forkIO` to `async` in order to rethrow exceptions
encountered by `getHieFiles`.

* Replace type families with lists

* Set capabilities with -j and -N

* Update comments in Weeder.hs

---------

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-08-10 12:57:50 +00:00
ryndubei
342a33d0de
Use distinct exit codes (#134)
* Use separate exit codes

* Update Spec.hs

* Use exit code 3 for config parse error

* Update src/Weeder/Main.hs

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>

* Replace Show instance with formatWeed

* Add constants for exit codes

* Exit code 4 when no hie files found

* Replace .hie with HIE in error message

* Override unexpected exit codes

* Put weeder exceptions in a datatype

* Add mainWithConfig'

Done in order to not expose WeederException while still exporting mainWithConfig

* Do not intercept ExitCode

* Move Weeder to Weeder.Analysis

* Move runWeeder to Weeder

* Revert "Move runWeeder to Weeder"

This reverts commit f3bd25f25c.

* Revert "Move Weeder to Weeder.Analysis"

This reverts commit e84e790735.

* Move runWeeder to Weeder.Run

* Redundant imports

* Change Weeder.Main to Weeder.Run in Spec.hs

* Wrap getHieFiles with handleWeederException

* Remove Weeder.Run exports from Weeder.Main exports

---------

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-08-10 12:45:06 +00:00
ryndubei
b3810a677e
Update README.md (#135)
* Update README.md

* Update README.md

Co-authored-by: ryndubei <114586905+ryndubei@users.noreply.github.com>

* Format paragraph

* Update Calling Weeder

* Add exit code table to README

* Update Tips

* Add type families to limitations

* Add configuration options table

* Update README.md

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>

* Update README.md

* Update README.md for #136

---------

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-08-10 12:41:40 +00:00
ryndubei
e54b8b1573
Combine root-instances and root-classes (#136)
* Combine rootClasses and rootInstances

* Make InstancePattern a record

* Update test config files

* Match on full class declaration in root-instances
2023-08-05 18:25:05 +00:00
ryndubei
9de21bfb99
Add support for unused types (#132)
* Tests for datatypes in output

The .stdout file for TypeFamilies is a concept for what the output of a type family instance weed may look like.

* Assign spans to data declarations

* Support for record field occurrences

* Lookup types of declarations in addAllDeclarations

* Analyse type synonyms and type family declarations

* Add unused-types config field

* Fix warning in analyseExport

* Add annsContain function

* Fix explicit foralls

* Type alias GADT test

* Add type signatures to topLevelAnalysis

* Fix false positives with data declarations

* Keep acyclicity in record declarations
2023-07-22 12:44:28 +00:00
ryndubei
f9d4ce7305
Improve config (#133)
* Optional weeder.toml and --write-default-config

* Add prop_configToToml to tests

* Add module to rootInstances and rootClasses

* Specify modules in root-classes and root-instances

* Add ConfigInstanceModules test

* Make instance and class fields optional

* Add IsString and IsList to default root-classes

* Move prop_configToToml to tests

* Mandatory config file

* Introduce PatternWithModule type

* Introduce CLIArguments type

* Lowercase language pragma

* Move main in test suite back to Spec.hs

* Add --no-default-fields flag
2023-07-20 12:15:12 +00:00
ryndubei
626a3180a2
Add support for type class instances (#126)
* Remove double addition of declarations

* Implement test suite

* Add mainWithConfig'

* Export dotfiles of dependency graphs

* Draw dotfiles to PNG via graphviz

* Flag for drawing graph PNGs

* Type class instances have spans and dependencies

Also includes class declarations and (both regular and standalone) derived instances. Consequently, they show up in the output if unreachable.

* Follow type class evidence uses back to bindings

* Add failing tests (number and string literals)

* Failing test for OverloadedLists

* More tests, not all failing

Also tested on 9.4.5.

`OverloadedStringsNoSig` correctly gives no output. `Monads` incorrectly claims that the instances for `Identity'` (used by `bar`) are unreachable, while correctly giving no output on the instances for `Identity` (used by `foo`). `RangeEnum` incorrectly claims that `$fEnumColour` is unreachable.

Note that what all the incorrect outputs have in common are top-level type signatures. The type signature does not have to be immediately relevant: see `OverloadedStringsNoSig` - the type of `root` and `root'` is `Char`, but explicitly writing that breaks their evidence variables for `IsString`. When type signatures are omitted, evidence usages for syntax are present in `hie` files as expected.

In `Monads.hie`, this is the node corresponding to `bar`:
```
 929   │   Node@test/Spec/Monads/Monads.hs:(36,1)-(38,13): Source: From source
 930   │                                                   {(annotations: {(FunBind, HsBindLR),
 931   │                                                                   (Match, Match),
 932   │                                                                   (XHsBindsLR, HsBindLR)}),
 933   │                                                    (types: [304]),  (identifier info: {})}
```

and this is the node for `foo`:
```
 837   │   Node@test/Spec/Monads/Monads.hs:(31,1)-(33,12): Source: From source
 838   │                                                   {(annotations: {(FunBind, HsBindLR),
 839   │                                                                   (Match, Match),
 840   │                                                                   (XHsBindsLR, HsBindLR)}),
 841   │                                                    (types: [302]),
 842   │                                                    (identifier info: {(name $dNum,  Details:  Just 3 {usage of evidence variable}),
 843   │                                                                       (name $fMonadIdentity,  Details:  Just 167 {usage of evidence variable}),
 844   │                                                                       (name $dMonad,  Details:  Just 167 {evidence variable bound by a let, depending on: [$fMonadIdentity]
 845   │                                                                                                           with scope: LocalScope test/Spec/Monads/Monads.hs:(31,1)-(33,12)
 846   │                                                                                                           bound at: test/Spec/Monads/Monads.hs:(31,1)-(33,12)}),
 847   │                                                                       (name $dNum,  Details:  Just 3 {evidence variable bound by a let, depending on: [$dNum]
 848   │                                                                                                       with scope: LocalScope test/Spec/Monads/Monads.hs:(31,1)-(33,12)
 849   │                                                                                                       bound at: test/Spec/Monads/Monads.hs:(31,1)-(33,12)}),
 850   │                                                                       (name $dNum,  Details:  Just 3 {evidence variable bound by a let, depending on: [$dNum]
 851   │                                                                                                       with scope: LocalScope test/Spec/Monads/Monads.hs:(31,1)-(33,12)
 852   │                                                                                                       bound at: test/Spec/Monads/Monads.hs:(31,1)-(33,12)})})}
```

The appearance of `foo` and `bar` in GHC's renamer AST does not differ in any meaningful way. In the typechecker AST, `bar` contains a (seemingly redundant) `EpAnn` annotation, which is missing in `foo`, but is otherwise the same everywhere else. For this reason I suppose the problem is not too deep within GHC and any required fixes are probably limited to modules directly handling `hie` files.

* Mark tests as failing

A `.failing` file should contain the current expected output of a failing test, overriding the `.stdout` file. This allows the test suite return a 0 exit code without having to disable failing tests.

If the test happens to return exactly the correct output contained in the `.stdout` file, it fails with a `not expected:` failure.

I think it would be worthwhile to make a small extension of `hspec` that allows marking tests as expected failures in a more polished way, assuming such an extension does not already exist.

* Tests for OverloadedLabels and ApplicativeDo

OverloadedLabels already works perfectly, but ApplicativeDo has the same problem as Monad

* Add InstanceRoot constructor

* Store pretty-printed type in InstanceRoot

* Add root-instances and root-classes fields

* Clean up tests

* Show pretty-printed type of instances in output

* Omit instance OccNames in output

* MonadReader for pretty-printed instance types

* MonadReader for following evidence uses

* Update test/Spec/InstanceRootConstraint.toml

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>

---------

Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-07-10 14:39:52 +00:00
Ollie Charles
3e3f764e2d
Switch to Nix Flakes (#129) 2023-07-08 17:21:57 +01:00
Ollie Charles
ffa91d2484
Release 2.6.0 (#127) 2023-07-07 12:47:16 +01:00
ryndubei
12b018e405
Remove double addition of declarations (#114) 2023-06-25 18:04:55 +01:00
ryndubei
e39cd7d986
Implement test suite (#116)
* Implement test suite

* Add mainWithConfig'

* Export dotfiles of dependency graphs

* Draw dotfiles to PNG via graphviz

* Flag for drawing graph PNGs

* Remove failing tests for now

* Combine mainWithConfig and mainWithConfig'
2023-06-23 20:54:10 +00:00
ryndubei
d8df2df683
Sort weeds by line number (#122) 2023-06-23 18:44:49 +00:00
Tristan de Cacqueray
9732ba1e28
Support GHC 9.6 (#115)
Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-06-23 12:12:16 +01:00
Taylor Fausak
11ab798d46
Replace Dhall with TOML using toml-reader (#120)
Co-authored-by: Ollie Charles <ollie@ocharles.org.uk>
2023-06-22 14:28:09 +01:00
Ollie Charles
e0ed4661b4
Update CI (#121) 2023-06-22 13:56:43 +01:00
Ollie Charles
01c900f742
Release 2.5.0 (#111) 2023-01-20 13:08:49 +00:00