rubik / argon Goto Github PK
View Code? Open in Web Editor NEWMonitor cyclomatic complexity in Haskell programs
License: BSD 3-Clause "New" or "Revised" License
Monitor cyclomatic complexity in Haskell programs
License: BSD 3-Clause "New" or "Revised" License
Looks like USAGE.txt is missing from hackage tarball (build from source is fine, but neither with cabal nor stack using hackage)
Configuring argon-0.1.0.0...
Warning: 'license: ISC' is not a recognised license. The known licenses are:
GPL, GPL-2, GPL-3, LGPL, LGPL-2.1, LGPL-3, AGPL, AGPL-3, BSD3, MIT, Apache,
Apache-2.0, PublicDomain, AllRightsReserved, OtherLicense
Building argon-0.1.0.0...
Preprocessing library argon-0.1.0.0...
[1 of 6] Compiling Argon.Types ( src/Argon/Types.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon/Types.o )
src/Argon/Types.hs:16:10: Warning:
Orphan instance: instance ToJSON ComplexityBlock
src/Argon/Types.hs:28:10: Warning:
Orphan instance: instance ToJSON (FilePath, AnalysisResult)
[2 of 6] Compiling Argon.Visitor ( src/Argon/Visitor.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon/Visitor.o )
[3 of 6] Compiling Argon.Formatters ( src/Argon/Formatters.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon/Formatters.o )
[4 of 6] Compiling Argon.Results ( src/Argon/Results.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon/Results.o )
[5 of 6] Compiling Argon.Parser ( src/Argon/Parser.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon/Parser.o )
[6 of 6] Compiling Argon ( src/Argon.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/Argon.o )
In-place registering argon-0.1.0.0...
Preprocessing executable 'argon' for argon-0.1.0.0...
[1 of 1] Compiling Main ( app/Main.hs, .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/argon/argon-tmp/Main.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.5.0.0 ... linking ... done.
Loading package deepseq-1.3.0.2 ... linking ... done.
Loading package bytestring-0.10.4.0 ... linking ... done.
Loading package containers-0.5.5.1 ... linking ... done.
Loading package text-1.2.0.6 ... linking ... done.
Loading package hashable-1.2.3.3 ... linking ... done.
Loading package scientific-0.3.3.8 ... linking ... done.
Loading package attoparsec-0.12.1.6 ... linking ... done.
Loading package dlist-0.7.1.1 ... linking ... done.
Loading package transformers-0.3.0.0 ... linking ... done.
Loading package mtl-2.1.3.1 ... linking ... done.
Loading package old-locale-1.0.0.6 ... linking ... done.
Loading package syb-0.4.4 ... linking ... done.
Loading package pretty-1.1.1.1 ... linking ... done.
Loading package template-haskell ... linking ... done.
Loading package time-1.4.2 ... linking ... done.
Loading package unordered-containers-0.2.5.1 ... linking ... done.
Loading package primitive-0.6 ... linking ... done.
Loading package vector-0.10.12.3 ... linking ... done.
Loading package aeson-0.8.0.2 ... linking ... done.
Loading package unix-2.7.0.1 ... linking ... done.
Loading package ansi-terminal-0.6.2.1 ... linking ... done.
Loading package filepath-1.3.0.2 ... linking ... done.
Loading package directory-1.2.1.0 ... linking ... done.
Loading package old-time-1.1.0.2 ... linking ... done.
Loading package polyparse-1.11 ... linking ... done.
Loading package cpphs-1.19 ... linking ... done.
Loading package parsec-3.1.9 ... linking ... done.
Loading package th-lift-0.7.2 ... linking ... done.
Loading package docopt-0.7.0.4 ... linking ... done.
Loading package haskell-src-exts-1.16.0.1 ... linking ... done.
Loading package uniplate-1.6.12 ... linking ... done.
Loading package argon-0.1.0.0 ... linking ... done.
app/Main.hs:10:12:
Exception when trying to run compile-time code:
USAGE.txt: openFile: does not exist (No such file or directory)
Code: template-haskell:Language.Haskell.TH.Quote.quoteExp
docoptFile "USAGE.txt"
Failed to install argon with cabal install argon
.
Error message:
Preprocessing library pipes-files-0.1.3...
Pipes/Files.hs:8:14: Unsupported extension: TypeApplications
cabal: Leaving directory '/tmp/cabal-tmp-20/pipes-files-0.1.3'
Installed pipes-bytestring-2.1.6
cabal: Error: some packages failed to install:
argon-0.4.1.0 depends on pipes-files-0.1.3 which failed to install.
pipes-files-0.1.3 failed during the building phase. The exception was:
ExitFailure 1
Hello,
I cannot compile argon
with stack
nor cabal
on a fresh installation of Ubuntu 20.20. Can you provide some hints as what to do?
I am attaching the output of the proposed installation commands:
> stack install argon
Writing implicit global project config file to: /home/me/.stack/global-project/stack.yaml
Note: You can change the snapshot via the resolver field there.
Using latest snapshot resolver: lts-16.12
Downloading lts-16.12 build plan ...
RedownloadInvalidResponse Request {
host = "raw.githubusercontent.com"
port = 443
secure = True
requestHeaders = []
path = "/fpco/lts-haskell/master//lts-16.12.yaml"
queryString = ""
method = "GET"
proxy = Nothing
rawBody = False
redirectCount = 10
responseTimeout = ResponseTimeoutDefault
requestVersion = HTTP/1.1
}
"/home/me/.stack/build-plan/lts-16.12.yaml" (Response {responseStatus = Status {statusCode = 404, statusMessage = "Not Found"}, responseVersion = HTTP/1.1, responseHeaders = [("Connection","keep-alive"),("Content-Length","14"),("Content-Type","text/plain; charset=utf-8"),("Content-Security-Policy","default-src 'none'; style-src 'unsafe-inline'; sandbox"),("Strict-Transport-Security","max-age=31536000"),("X-Content-Type-Options","nosniff"),("X-Frame-Options","deny"),("X-XSS-Protection","1; mode=block"),("Via","1.1 varnish (Varnish/6.0)"),("X-GitHub-Request-Id","3CF4:BA30:142FF35:158CA0C:5F50A696"),("Accept-Ranges","bytes"),("Date","Thu, 03 Sep 2020 08:17:26 GMT"),("Via","1.1 varnish"),("X-Served-By","cache-hhn4040-HHN"),("X-Cache","MISS, MISS"),("X-Cache-Hits","0, 0"),("X-Timer","S1599121046.450962,VS0,VE158"),("Vary","Authorization,Accept-Encoding"),("Access-Control-Allow-Origin","*"),("X-Fastly-Request-ID","7a1307a21b5c9698a0e821e11924f7db20b11d95"),("Expires","Thu, 03 Sep 2020 08:22:26 GMT"),("Source-Age","0")], responseBody = (), responseCookieJar = CJ {expose = []}, responseClose' = ResponseClose})
> cabal install argon
Warning: The install command is a part of the legacy v1 style of cabal usage.
Please switch to using either the new project style and the new-install
command or the legacy v1-install alias as new-style projects will become the
default in the next version of cabal-install. Please file a bug if you cannot
replicate a working v1- use case with the new-style commands.
For more information, see: https://wiki.haskell.org/Cabal/NewBuild
Config file path source is default config file.
Config file /home/me/.cabal/config not found.
Writing default configuration to /home/me/.cabal/config
Warning: The package list for 'hackage.haskell.org' does not exist. Run 'cabal
update' to download it.
cabal: There is no package named 'argon'.
You may need to run 'cabal update' to get the latest list of available
packages.
> cabal update
Warning: The update command is a part of the legacy v1 style of cabal usage.
Please switch to using either the new project style and the new-update command
or the legacy v1-update alias as new-style projects will become the default in
the next version of cabal-install. Please file a bug if you cannot replicate a
working v1- use case with the new-style commands.
For more information, see: https://wiki.haskell.org/Cabal/NewBuild
Downloading the latest package list from hackage.haskell.org
> cabal install argon
Warning: The install command is a part of the legacy v1 style of cabal usage.
Please switch to using either the new project style and the new-install
command or the legacy v1-install alias as new-style projects will become the
default in the next version of cabal-install. Please file a bug if you cannot
replicate a working v1- use case with the new-style commands.
For more information, see: https://wiki.haskell.org/Cabal/NewBuild
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: argon-0.4.1.0 (user goal)
[__1] trying: pipes-files-0.1.3 (dependency of argon)
[__2] trying: hierarchy-1.0.2 (dependency of pipes-files)
[__3] next goal: ghc (dependency of argon)
[__3] rejecting: ghc-8.6.5/installed-8.6... (conflict: argon => ghc>=7.8 &&
<8)
[__3] rejecting: ghc-8.10.1 (unsupported spec-version 3.0)
[__3] rejecting: ghc-8.8.3, ghc-8.8.1, ghc-8.6.5, ghc-8.6.4, ghc-8.6.1,
ghc-8.4.4, ghc-8.4.3, ghc-8.4.1, ghc-8.2.2, ghc-8.2.1 (conflict: argon =>
ghc>=7.8 && <8)
[__3] fail (backjumping, conflict set: argon, ghc)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: argon, base, haskell-src-exts, ghc,
pipes-files, hierarchy
My question is about the Types.Config
data type, and the uses the code makes of exts
, headers
and includeDirs
. This questions is not directly aimed at modifying or improving the code, I ask mainly to understand better how this works.
exts
would be the extensions to activate in the parsing of the file. In the case in which the cabal file is read, is this option still useful? How?
Similarly, could you do an example in which headers
and includeDirs
are useful?
With this option it will be possible to parse the Cabal file and read default extensions.
This issue describes the status of the porting, which proceeds on the ghc-api
branch.
To do:
LogAction
)Visitor.getFuncName
safe (safe handling of RdrName
)Span.srcSpanToSpan
safe (safe handling of SrcSpan
)Visitor.visitOp
implementationVisitor.complexity
(complexity isn't counted correctly)Visitor.isFunction
Tests should cover at the very least:
#if !MIN_VERSION_base(4,8,0)
gives:
error: 67:22 error: token is not a valid binary operator in a preprocessor subexpression
(context)
Hi,
It'd be nice to have an explanation about what the different figures (1, 5, 10) actually mean. Cyclomatic complexity is usually defined for imperative programs, but I could not find what is the definition of cyclomatic complexity that argon
uses. If you have a reference to a paper or article I can help with updating the readme.
There should be as little code as possible in Main.hs
. Most should be moved in Argon.CLI
so that it can be tested.
Needed to specify custom header files for CPP. It would also solve #15 if one included cabal_macros.h
.
Currently the following call raises an error:
$ argon --min 3 --no-color src
while this works:
$ argon --no-color --min 3 src
Not an Argon bug though. Waiting for a new version of ghc-syb-utils to fix this.
Search cabal file in the current directory and the parent ones. If more than one cabal files are found, then no one is chosen.
Let's investigate the last two errors remaining when supplying the src
directory of hint
. For reference, I'm running argon
with the command
argon --min 10 --cabal-macros $(stack path --dist-dir)/build/autogen/cabal_macros.h --cabal-file hint.cabal src
where the --min 10
is a hack to see only the errors.
After the corrections we talked about in the previous post, we were left with:
src/Hint/Base.hs
error: 94:14 Illegal symbol '.' in type
Perhaps you intended to use RankNTypes or a similar language
extension to enable explicit-forall syntax: forall <tvs>. <type>
src/Hint/Configuration.hs
error: 59:20 Not a data constructor: ‘forall’
Perhaps you intended to use ExistentialQuantification
This strongly hints that the problem is with ExplicitForAll
, and indeed, if I add ExplicitForAll
to the cabal file, the sources are all processed without errors. However, the sources contained also Rank2Types
(which I switched for RankNTypes
with no observable difference), which according to common experience (and this useful diagram) should imply ExplicitForAll
.
So the question is: how could argon be convinced to load also that extension? Where does the mismatch with the behavior of the compiler happen (the compiler doesn't throw an error)?
UPDATE Massimo told me on irc that here's where ghc implements the extension dependencies.
Hi!
I've been using Argon for a while now and it seems to not detect guards.
Here's some code I shamelessly picked out of stackoverflow.
nthElement :: [a] -> Int -> Maybe a
nthElement [] a = Nothing
nthElement (x:xs) a | a <= 0 = Nothing
| a == 1 = Just x
| a > 1 = nthElement xs (a-1)
nthElementIf :: [a] -> Int -> Maybe a
nthElementIf [] a = Nothing
nthElementIf (x:xs) a = if a <= 1
then if a <= 0
then Nothing
else Just x -- a == 1
else nthElementIf xs (a-1)
nthElementCases :: [a] -> Int -> Maybe a
nthElementCases [] a = Nothing
nthElementCases (x:xs) a = case a <= 0 of
True -> Nothing
False -> case a == 1 of
True -> Just x
False -> nthElementCases xs (a-1)
Argon computes a cyclomatic complexity of 4 for nthElementCases
and 4 for nthElementIf
, but just 2 for nthElement
.
I've tried this with a Fibonacci function I wrote, and I get the same problem.
Is it that guards are deliberately not supported, or that there is a bug in the code?
DatatypeContexts
is deprecated anyway and the following file will yield an error, while it compiles perfectly with ghc-8.0.2:
module Foo where
data Show a => Foo a = Foo a
Error:
src/Foo.hs
error: 3:6 Illegal datatype context (use DatatypeContexts): Show a =>
It appears argon can't currently be dependency resolved by the default, stable Stack. To build it with a Stack project requires adding this to stack.yml: extra-deps: [pipes-files-0.1.1, hierarchy-0.3.1, posix-paths-0.2.1.0]
.
With pipes-files.
Example code:
{-# LANGUAGE ScopedTypeVariables #-}
module Utility.Exception where
import Control.Monad.Catch as X hiding (Handler)
import qualified Control.Monad.Catch as M
catchNonAsync :: MonadCatch m => m a -> (SomeException -> m a) -> m a
catchNonAsync a onerr = a `catches`
[ M.Handler (\ (e :: SomeException) -> onerr e)
]
Expected output (actual output with GHC 7.10.2):
stv.hs
9:1 catchNonAsync - 1
Actual output (GHC 7.8.4):
argon: argon: panic! (the 'impossible' happened)
(GHC version 7.8.4 for x86_64-unknown-linux):
mkHsTyWithBndrs:kvs
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
Currently all the parsed results are kept in memory. To improve this, we will use a streaming library such as pipes. Ongoing efforts are on the pipes branch.
src/Concurrent/Internal/Counted.hs
error: 27:1 Invalid type signature: pattern (:+) :: a -> Counted a -> Counted a
I have a project in which I specified a few commonly used ghc extensions inside the cabal file. It seems to me that argon does not pickup the extensions from the cabal file, since I am getting a lot of errors. If I put the extension at the top of the module {-# LANGUAGE BangPatterns #-}
it works fine.
Is this related to how the cyclomatic complexity algorithm is designed? Does DataKinds bork everything because expressions become types? I have no idea how the complexity analysis works, I will read up on it to catch up.
As of now, the Span
type is useless, because it refers to the span of the function name, not the one of all the function code. Since the function name is almost always on a single line, Span
s are in this form:
(start line, start col, start line, start col + function name length)
Possible solutions:
(start line, start col)
tupleCurrently missing from tests:
--cabal-file
and --cabal-macros
and -I --include-dir
I tried argon
with hint
(in particular the src
directory) and I get a bunch of errors related to the cpp directives, like:
src/Language/Haskell/Interpreter/Unsafe.hs
error: 28:2 lexical error at character 'i'
src/Hint/InterpreterT.hs
error: 38:2 lexical error at character 'i'
src/Hint/CompatPlatform.hs
error: 1:2 lexical error at character 'i'
A sample error which generates this is:
#if __GLASGOW_HASKELL__ < 800
, Functor m
#endif
Can you reproduce this error?
More generally, I'm searching for a stable way to remove all the cpp preprocessing, so that I can than analyze the code with the ghc
api or haskell-src-exts
. Do you have any advice?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.