Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
gargantext-ihaskell
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gargantext
gargantext-ihaskell
Commits
670ccde9
Commit
670ccde9
authored
May 17, 2014
by
Andrew Gibiansky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
things compile with new hlint and classy-prelude
parent
787e9d69
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
125 additions
and
113 deletions
+125
-113
Evaluate.hs
src/IHaskell/Eval/Evaluate.hs
+3
-2
Lint.hs
src/IHaskell/Eval/Lint.hs
+120
-109
Main.hs
src/Main.hs
+2
-2
No files found.
src/IHaskell/Eval/Evaluate.hs
View file @
670ccde9
...
@@ -1010,10 +1010,11 @@ capturedStatement output stmt = do
...
@@ -1010,10 +1010,11 @@ capturedStatement output stmt = do
]
]
pipeExpr
=
printf
"let %s = %s"
(
var
"pipe_var_"
)
readVariable
pipeExpr
=
printf
"let %s = %s"
(
var
"pipe_var_"
)
readVariable
goStmt
::
String
->
Ghc
RunResult
goStmt
s
=
runStmt
s
RunToCompletion
goStmt
s
=
runStmt
s
RunToCompletion
-- Initialize evaluation context.
-- Initialize evaluation context.
forM_
initStmts
goStmt
void
$
forM
initStmts
goStmt
-- Get the pipe to read printed output from.
-- Get the pipe to read printed output from.
-- This is effectively the source code of dynCompileExpr from GHC API's
-- This is effectively the source code of dynCompileExpr from GHC API's
...
@@ -1101,7 +1102,7 @@ capturedStatement output stmt = do
...
@@ -1101,7 +1102,7 @@ capturedStatement output stmt = do
liftIO
$
modifyMVar_
completed
(
const
$
return
True
)
liftIO
$
modifyMVar_
completed
(
const
$
return
True
)
-- Finalize evaluation context.
-- Finalize evaluation context.
forM_
postStmts
goStmt
void
$
forM
postStmts
goStmt
-- Once context is finalized, reading can finish.
-- Once context is finalized, reading can finish.
-- Wait for reading to finish to that the output accumulator is
-- Wait for reading to finish to that the output accumulator is
...
...
src/IHaskell/Eval/Lint.hs
View file @
670ccde9
...
@@ -4,34 +4,49 @@ module IHaskell.Eval.Lint (
...
@@ -4,34 +4,49 @@ module IHaskell.Eval.Lint (
)
where
)
where
import
Data.String.Utils
(
replace
,
startswith
,
strip
,
split
)
import
Data.String.Utils
(
replace
,
startswith
,
strip
,
split
)
import
Prelude
(
head
,
tail
)
import
Prelude
(
head
,
tail
,
last
)
import
Language.Haskell.HLint
as
HLint
import
ClassyPrelude
hiding
(
last
)
import
ClassyPrelude
import
Control.Monad
import
Control.Monad
import
Data.List
(
findIndex
)
import
Data.List
(
findIndex
)
import
Text.Printf
import
Text.Printf
import
Data.String.Here
import
Data.String.Here
import
Data.Char
import
Data.Char
import
Data.Monoid
import
Data.Monoid
import
Data.Maybe
(
mapMaybe
)
import
System.IO.Unsafe
(
unsafePerformIO
)
import
Language.Haskell.Exts.Annotated.Syntax
hiding
(
Module
)
import
qualified
Language.Haskell.Exts.Annotated.Syntax
as
SrcExts
import
Language.Haskell.Exts.Annotated
(
parseFileContentsWithMode
)
import
Language.Haskell.Exts.Annotated.Build
(
doE
)
import
Language.Haskell.Exts.Annotated
hiding
(
Module
)
import
Language.Haskell.Exts.SrcLoc
import
Language.Haskell.HLint
as
HLint
import
Language.Haskell.HLint2
import
IHaskell.Types
import
IHaskell.Types
import
IHaskell.Display
import
IHaskell.Display
import
IHaskell.IPython
import
IHaskell.IPython
import
IHaskell.Eval.Parser
hiding
(
line
)
import
IHaskell.Eval.Parser
hiding
(
line
)
data
LintSeverity
=
LintWarning
|
LintError
deriving
(
Eq
,
Show
)
type
ExtsModule
=
SrcExts
.
Module
SrcSpanInfo
data
LintSuggestion
data
LintSuggestion
=
Suggest
{
=
Suggest
{
line
::
LineNumber
,
line
::
LineNumber
,
chunkNumber
::
Int
,
found
::
String
,
found
::
String
,
whyNot
::
String
,
whyNot
::
String
,
severity
::
Lint
Severity
,
severity
::
Severity
,
suggestion
::
String
suggestion
::
String
}
}
deriving
(
Eq
,
Show
)
deriving
(
Eq
,
Show
)
-- Store settings for Hlint once it's initialized.
{-# NOINLINE hlintSettings #-}
hlintSettings
::
MVar
(
ParseFlags
,
[
Classify
],
Hint
)
hlintSettings
=
unsafePerformIO
newEmptyMVar
-- | Identifier used when one is needed for proper context.
-- | Identifier used when one is needed for proper context.
lintIdent
::
String
lintIdent
::
String
lintIdent
=
"lintIdentAEjlkQeh"
lintIdent
=
"lintIdentAEjlkQeh"
...
@@ -40,31 +55,106 @@ lintIdent = "lintIdentAEjlkQeh"
...
@@ -40,31 +55,106 @@ lintIdent = "lintIdentAEjlkQeh"
-- report on linting warnings and errors.
-- report on linting warnings and errors.
lint
::
[
Located
CodeBlock
]
->
IO
Display
lint
::
[
Located
CodeBlock
]
->
IO
Display
lint
blocks
=
do
lint
blocks
=
do
let
validBlocks
=
map
makeValid
blocks
-- Initialize hlint settings
fileContents
=
joinBlocks
validBlocks
initialized
<-
isEmptyMVar
hlintSettings
-- Get a temporarly location to store this file.
when
(
not
initialized
)
$
autoSettings
>>=
putMVar
hlintSettings
ihaskellDir
<-
getIHaskellDir
let
filename
=
ihaskellDir
++
"/.hlintFile.hs"
-- Get hlint settings
(
flags
,
classify
,
hint
)
<-
readMVar
hlintSettings
writeFile
(
fromString
filename
)
fileContents
let
mode
=
hseFlags
flags
suggestions
<-
catMaybes
<$>
map
parseSuggestion
<$>
hlint
[
filename
,
"--quiet"
]
-- create 'suggestions'
let
modules
=
mapMaybe
(
createModule
mode
)
blocks
ideas
=
applyHints
classify
hint
modules
suggestions
=
mapMaybe
showIdea
ideas
return
$
Display
$
return
$
Display
$
if
null
suggestions
if
null
suggestions
then
[]
then
[]
else
else
[
plain
$
concatMap
plainSuggestion
suggestions
,
[
plain
$
concatMap
plainSuggestion
suggestions
,
html
$
htmlSuggestions
suggestions
]
html
$
htmlSuggestions
suggestions
]
showIdea
::
Idea
->
Maybe
LintSuggestion
showIdea
idea
=
case
ideaTo
idea
of
Nothing
->
Nothing
Just
whyNot
->
Just
Suggest
{
line
=
srcSpanStartLine
$
ideaSpan
idea
,
found
=
showSuggestion
$
ideaFrom
idea
,
whyNot
=
showSuggestion
$
whyNot
,
severity
=
ideaSeverity
idea
,
suggestion
=
ideaHint
idea
}
createModule
::
ParseMode
->
Located
CodeBlock
->
Maybe
ExtsModule
createModule
mode
(
Located
line
block
)
=
case
block
of
Expression
expr
->
unparse
$
exprToModule
expr
Declaration
decl
->
unparse
$
declToModule
decl
Statement
stmt
->
unparse
$
stmtToModule
stmt
Import
impt
->
unparse
$
imptToModule
impt
Module
mod
->
unparse
$
parseModule
mod
_
->
Nothing
where
where
-- Join together multiple valid file blocks into a single file.
blockStr
=
-- However, join them with padding so that the line numbers are
case
block
of
-- correct.
Expression
expr
->
expr
joinBlocks
::
[
Located
String
]
->
String
Declaration
decl
->
decl
joinBlocks
=
unlines
.
zipWith
addPragma
[
1
..
]
Statement
stmt
->
stmt
Import
impt
->
impt
Module
mod
->
mod
unparse
::
ParseResult
a
->
Maybe
a
unparse
(
ParseOk
a
)
=
Just
a
unparse
_
=
Nothing
srcSpan
::
SrcSpan
srcSpan
=
SrcSpan
{
srcSpanFilename
=
"<interactive>"
,
srcSpanStartLine
=
line
,
srcSpanStartColumn
=
0
,
srcSpanEndLine
=
line
+
length
(
lines
blockStr
),
srcSpanEndColumn
=
length
$
last
$
lines
blockStr
}
loc
::
SrcSpanInfo
loc
=
SrcSpanInfo
srcSpan
[]
moduleWithDecls
::
Decl
SrcSpanInfo
->
ExtsModule
moduleWithDecls
decl
=
SrcExts
.
Module
loc
Nothing
[]
[]
[
decl
]
parseModule
::
String
->
ParseResult
ExtsModule
parseModule
=
parseFileContentsWithMode
mode
declToModule
::
String
->
ParseResult
ExtsModule
declToModule
decl
=
moduleWithDecls
<$>
parseDeclWithMode
mode
decl
exprToModule
::
String
->
ParseResult
ExtsModule
exprToModule
exp
=
moduleWithDecls
<$>
SpliceDecl
loc
<$>
parseExpWithMode
mode
exp
stmtToModule
::
String
->
ParseResult
ExtsModule
stmtToModule
stmtStr
=
case
parseStmtWithMode
mode
stmtStr
of
ParseOk
stmt
->
ParseOk
mod
ParseFailed
a
b
->
ParseFailed
a
b
where
mod
=
moduleWithDecls
decl
decl
::
Decl
SrcSpanInfo
decl
=
SpliceDecl
loc
expr
expr
::
Exp
SrcSpanInfo
expr
=
doE
loc
[
stmt
,
ret
]
stmt
::
Stmt
SrcSpanInfo
ParseOk
stmt
=
parseStmtWithMode
mode
stmtStr
addPragma
::
Int
->
Located
String
->
String
ret
::
Stmt
SrcSpanInfo
addPragma
i
(
Located
desiredLine
str
)
=
linePragma
desiredLine
i
++
str
ParseOk
ret
=
Qualifier
loc
<$>
parseExp
lintIdent
linePragma
=
printf
"{-# LINE %d
\"
%d
\"
#-}
\n
"
imptToModule
::
String
->
ParseResult
ExtsModule
imptToModule
=
parseFileContentsWithMode
mode
plainSuggestion
::
LintSuggestion
->
String
plainSuggestion
::
LintSuggestion
->
String
plainSuggestion
suggest
=
plainSuggestion
suggest
=
...
@@ -91,8 +181,11 @@ htmlSuggestions = concatMap toHtml
...
@@ -91,8 +181,11 @@ htmlSuggestions = concatMap toHtml
where
where
severityClass
=
case
severity
suggest
of
severityClass
=
case
severity
suggest
of
LintWarning
->
"warning"
Error
->
"error"
LintError
->
"error"
Warning
->
"warning"
-- Should not occur
_
->
"warning"
style
::
String
->
String
->
String
style
::
String
->
String
->
String
style
cls
thing
=
[
i
|
<div class="suggestion-${cls}">${thing}</div>
|]
style
cls
thing
=
[
i
|
<div class="suggestion-${cls}">${thing}</div>
|]
...
@@ -106,60 +199,18 @@ htmlSuggestions = concatMap toHtml
...
@@ -106,60 +199,18 @@ htmlSuggestions = concatMap toHtml
floating
::
String
->
String
->
String
floating
::
String
->
String
->
String
floating
dir
thing
=
[
i
|
<div class="suggestion-row" style="float: ${dir};">${thing}</div>
|]
floating
dir
thing
=
[
i
|
<div class="suggestion-row" style="float: ${dir};">${thing}</div>
|]
-- | Parse a suggestion from Hlint. The suggestions look like this:
-- .ihaskell/.hlintFile.hs:1:19: Warning: Redundant bracket
-- Found:
-- ((3))
-- Why not:
-- (3)
-- We extract all the necessary fields and store them.
-- If parsing fails, return Nothing.
parseSuggestion
::
Suggestion
->
Maybe
LintSuggestion
parseSuggestion
suggestion
=
do
let
str
=
showSuggestion
(
show
suggestion
)
severity
=
suggestionSeverity
suggestion
guard
(
severity
/=
HLint
.
Ignore
)
let
lintSeverity
=
case
severity
of
Warning
->
LintWarning
Error
->
LintError
headerLine
:
foundLine
:
rest
<-
Just
(
lines
str
)
-- Expect the line after the header to have 'Found' in it.
guard
(
"Found:"
`
isInfixOf
`
foundLine
)
-- Expect something like:
-- ".hlintFile.hs:1:19: Warning: Redundant bracket"
-- ==>
-- [".hlintFile.hs","1","19"," Warning"," Redundant bracket"]
[
readMay
->
Just
chunkN
,
readMay
->
Just
lineNum
,
_col
,
severity
,
name
]
<-
Just
(
split
":"
headerLine
)
(
before
,
_
:
after
)
<-
Just
(
break
(
"Why not:"
`
isInfixOf
`)
rest
)
return
Suggest
{
line
=
lineNum
,
chunkNumber
=
chunkN
,
found
=
unlines
before
,
whyNot
=
unlines
after
,
suggestion
=
name
,
severity
=
lintSeverity
}
showSuggestion
::
String
->
String
showSuggestion
::
String
->
String
showSuggestion
=
showSuggestion
=
removeSplices
.
remove
lintIdent
.
dropDo
remove
(
"return "
++
lintIdent
)
.
remove
(
lintIdent
++
"="
)
.
dropDo
where
where
remove
str
=
replace
str
""
remove
str
=
replace
str
""
removeSplices
=
id
-- Drop leading ' do ', and blank spaces following.
-- Drop leading ' do ', and blank spaces following.
dropDo
::
String
->
String
dropDo
::
String
->
String
dropDo
string
=
dropDo
string
=
-- If this is not a statement, we don't need to drop the do statement.
-- If this is not a statement, we don't need to drop the do statement.
if
(
"return "
++
lintIdent
)
`
isInfixOf
`
string
if
lintIdent
`
isInfixOf
`
string
then
unlines
.
clean
.
lines
$
string
then
unlines
.
clean
.
lines
$
string
else
string
else
string
...
@@ -180,43 +231,3 @@ showSuggestion =
...
@@ -180,43 +231,3 @@ showSuggestion =
-- Ignore other list elements - just proceed onwards.
-- Ignore other list elements - just proceed onwards.
clean
(
x
:
xs
)
=
x
:
clean
xs
clean
(
x
:
xs
)
=
x
:
clean
xs
clean
[]
=
[]
clean
[]
=
[]
-- | Convert a code chunk into something that could go into a file.
-- The line number on the output is the same as on the input.
makeValid
::
Located
CodeBlock
->
Located
String
makeValid
(
Located
line
block
)
=
Located
line
$
case
block
of
-- Expressions need to be bound to some identifier.
Expression
expr
->
lintIdent
++
"="
++
expr
-- Statements go in a 'do' block bound to an identifier.
--
-- a cell can contain:
-- > x <- readFile "foo"
-- so add a return () to avoid a Parse error: Last statement in
-- a do-block must be an expression
--
-- one place this goes wrong is when the chunk is:
--
-- > do
-- > {- a comment that has to -} let x = 1
-- > {- count as whitespace -} y = 2
-- > return (x+y)
Statement
stmt
->
let
expandTabs
=
replace
"
\t
"
" "
nLeading
=
maybe
0
(
length
.
takeWhile
isSpace
)
$
listToMaybe
$
filter
(
not
.
all
isSpace
)
(
lines
(
expandTabs
stmt
))
finalReturn
=
replicate
nLeading
' '
++
"return "
++
lintIdent
in
intercalate
"
\n
"
((
lintIdent
++
" $ do"
)
:
lines
stmt
++
[
finalReturn
])
-- Modules, declarations, and type signatures are fine as is.
Module
mod
->
mod
Declaration
decl
->
decl
TypeSignature
sig
->
sig
Import
imp
->
imp
-- Output nothing for directives or parse errors.
Directive
{}
->
""
ParseError
{}
->
""
src/Main.hs
View file @
670ccde9
...
@@ -170,8 +170,8 @@ runKernel profileSrc initInfo = do
...
@@ -170,8 +170,8 @@ runKernel profileSrc initInfo = do
state
<-
liftIO
$
takeMVar
stateVar
state
<-
liftIO
$
takeMVar
stateVar
evaluate
state
line
noPublish
evaluate
state
line
noPublish
mapM
_
evaluator
extLines
mapM
evaluator
extLines
mapM
_
evaluator
$
initCells
initInfo
mapM
evaluator
$
initCells
initInfo
forever
$
do
forever
$
do
-- Read the request from the request channel.
-- Read the request from the request channel.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment