Commit fc260a46 authored by Andrew Gibiansky's avatar Andrew Gibiansky

fixing several issues that broke blaze-html integration

parent 8b0aa538
This diff is collapsed.
...@@ -53,7 +53,7 @@ becomes string expected = do ...@@ -53,7 +53,7 @@ becomes string expected = do
forM_ (zip results expected) $ \(result, expected) -> forM_ (zip results expected) $ \(result, expected) ->
case find isPlain result of case find isPlain result of
Just (Display PlainText str) -> expected `shouldBe` str Just (Display PlainText str) -> str `shouldBe` expected
Nothing -> expectationFailure $ "No plain-text output in " ++ show result Nothing -> expectationFailure $ "No plain-text output in " ++ show result
...@@ -100,6 +100,14 @@ evalTests = do ...@@ -100,6 +100,14 @@ evalTests = do
print (Y 3 == Z "No") print (Y 3 == Z "No")
|] `becomes` ["[Y 3,Z \"No\"]", "False"] |] `becomes` ["[Y 3,Z \"No\"]", "False"]
it "evaluates do blocks in expressions" $ do
[hereLit|
show (show (do
Just 10
Nothing
Just 100))
|] `becomes` ["\"\\\"Nothing\\\"\""]
it "is silent for imports" $ do it "is silent for imports" $ do
"import Control.Monad" `becomes` [] "import Control.Monad" `becomes` []
"import qualified Control.Monad" `becomes` [] "import qualified Control.Monad" `becomes` []
...@@ -228,13 +236,13 @@ parseStringTests = describe "Parser" $ do ...@@ -228,13 +236,13 @@ parseStringTests = describe "Parser" $ do
it "parses a <- stmt followed by let stmt" $ it "parses a <- stmt followed by let stmt" $
parses "y <- do print 'no'\nlet x = expr" `like` [ parses "y <- do print 'no'\nlet x = expr" `like` [
Statement "y <- do { print 'no' }", Statement "y <- do print 'no'",
Statement "let x = expr" Statement "let x = expr"
] ]
it "parses <- followed by let followed by expr" $ it "parses <- followed by let followed by expr" $
parses "y <- do print 'no'\nlet x = expr\nexpression" `like` [ parses "y <- do print 'no'\nlet x = expr\nexpression" `like` [
Statement "y <- do { print 'no' }", Statement "y <- do print 'no'",
Statement "let x = expr", Statement "let x = expr",
Expression "expression" Expression "expression"
] ]
...@@ -288,3 +296,15 @@ parseStringTests = describe "Parser" $ do ...@@ -288,3 +296,15 @@ parseStringTests = describe "Parser" $ do
Import "import X", Import "import X",
Expression "print 3" Expression "print 3"
] ]
it "doesn't break on long strings" $ do
let longString = concat $ replicate 20 "hello "
("img ! src \"" ++ longString ++ "\" ! width \"500\"") `is` Expression
it "parses do blocks in expression" $ do
[hereLit|
show (show (do
Just 10
Nothing
Just 100))
|] `is` Expression
...@@ -50,7 +50,7 @@ import IHaskell.Display ...@@ -50,7 +50,7 @@ import IHaskell.Display
data ErrorOccurred = Success | Failure deriving Show data ErrorOccurred = Success | Failure deriving Show
debug :: Bool debug :: Bool
debug = False debug = True
ignoreTypePrefixes :: [String] ignoreTypePrefixes :: [String]
ignoreTypePrefixes = ["GHC.Types", "GHC.Base", "GHC.Show", "System.IO", ignoreTypePrefixes = ["GHC.Types", "GHC.Base", "GHC.Show", "System.IO",
...@@ -394,35 +394,23 @@ evalCommand (Expression expr) = do ...@@ -394,35 +394,23 @@ evalCommand (Expression expr) = do
-- The output is bound to 'it', so we can then use it. -- The output is bound to 'it', so we can then use it.
(success, out) <- evalCommand (Statement expr) (success, out) <- evalCommand (Statement expr)
-- Try to use `display` to convert our type into the output
-- DisplayData. If typechecking fails and there is no appropriate
-- typeclass, this will throw an exception and thus `attempt` will
-- return False, and we just resort to plaintext.
let displayExpr = printf "(IHaskell.Display.display (%s))" expr
canRunDisplay <- attempt $ exprType displayExpr
write displayExpr
-- If evaluation failed, return the failure. If it was successful, we -- If evaluation failed, return the failure. If it was successful, we
-- may be able to use the IHaskellDisplay typeclass. -- may be able to use the IHaskellDisplay typeclass.
case success of if not canRunDisplay
Failure -> return (success, out) then return (success, out)
Success -> do else case success of
-- Try to use `display` to convert our type into the output Success -> useDisplay displayExpr
-- DisplayData. If typechecking fails and there is no appropriate Failure -> if isShowError out
-- typeclass, this will throw an exception and thus `attempt` will then useDisplay displayExpr
-- return False, and we just resort to plaintext. else return (success, out)
canRunDisplay <- attempt $ exprType "IHaskell.Display.display it"
if canRunDisplay
then do
-- If there are instance matches, convert the object into
-- a [DisplayData]. We also serialize it into a bytestring. We get
-- the bytestring as a dynamic and then convert back to
-- a bytestring, which we promptly unserialize. Note that
-- attempting to do this without the serialization to binary and
-- back gives very strange errors - all the types match but it
-- refuses to decode back into a [DisplayData].
displayedBytestring <- dynCompileExpr "IHaskell.Display.serializeDisplay (IHaskell.Display.display it)"
case fromDynamic displayedBytestring of
Nothing -> error "Expecting lazy Bytestring"
Just bytestring ->
case Serialize.decode bytestring of
Left err -> error err
Right displayData -> do
write $ show displayData
return (success, displayData)
else return (success, out)
where where
-- Try to evaluate an action. Return True if it succeeds and False if -- Try to evaluate an action. Return True if it succeeds and False if
...@@ -432,6 +420,35 @@ evalCommand (Expression expr) = do ...@@ -432,6 +420,35 @@ evalCommand (Expression expr) = do
where failure :: SomeException -> Interpreter Bool where failure :: SomeException -> Interpreter Bool
failure _ = return False failure _ = return False
-- Check if the error is due to trying to print something that doesn't
-- implement the Show typeclass.
isShowError errs = case find isPlain errs of
Just (Display PlainText msg) ->
startswith "No instance for (GHC.Show.Show " msg &&
isInfixOf " arising from a use of `System.IO.print'" msg
Nothing -> False
where isPlain (Display mime _) = (mime == PlainText)
useDisplay displayExpr = wrapExecution $ do
-- If there are instance matches, convert the object into
-- a [DisplayData]. We also serialize it into a bytestring. We get
-- the bytestring as a dynamic and then convert back to
-- a bytestring, which we promptly unserialize. Note that
-- attempting to do this without the serialization to binary and
-- back gives very strange errors - all the types match but it
-- refuses to decode back into a [DisplayData].
runStmt displayExpr RunToCompletion
displayedBytestring <- dynCompileExpr "IHaskell.Display.serializeDisplay it"
case fromDynamic displayedBytestring of
Nothing -> error "Expecting lazy Bytestring"
Just bytestring ->
case Serialize.decode bytestring of
Left err -> error err
Right displayData -> do
write $ show displayData
return displayData
evalCommand (Declaration decl) = wrapExecution $ runDecls decl >> return [] evalCommand (Declaration decl) = wrapExecution $ runDecls decl >> return []
evalCommand (ParseError loc err) = wrapExecution $ evalCommand (ParseError loc err) = wrapExecution $
......
...@@ -173,22 +173,16 @@ parseCodeChunk code startLine = do ...@@ -173,22 +173,16 @@ parseCodeChunk code startLine = do
parsers :: DynFlags -> [(String -> CodeBlock, String -> ParseOutput String)] parsers :: DynFlags -> [(String -> CodeBlock, String -> ParseOutput String)]
parsers flags = parsers flags =
[ (Import, unparser toCode partialImport) [ (Import, unparser partialImport)
, (TypeSignature, unparser toCode partialTypeSignature) , (TypeSignature, unparser partialTypeSignature)
, (Declaration, unparser listCode partialDeclaration) , (Declaration, unparser partialDeclaration)
, (Statement, unparser toCode partialStatement) , (Statement, unparser partialStatement)
] ]
where where
toCode :: Outputable a => a -> String unparser :: P a -> String -> ParseOutput String
toCode = strip . showSDoc flags . ppr unparser parser code =
listCode :: Outputable a => OrdList a -> String
listCode = joinLines . map toCode . fromOL
unparser :: (a -> String) -> P a -> String -> ParseOutput String
unparser postprocess parser code =
case runParser flags parser code of case runParser flags parser code of
Success out strs -> Success (postprocess out) strs Success out strs -> Success code strs
Failure err loc -> Failure err loc Failure err loc -> Failure err loc
-- | Find consecutive declarations of the same function and join them into -- | Find consecutive declarations of the same function and join them into
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment