Skip to content

Commit

Permalink
Fix some warnings on GHC 9.6.3
Browse files Browse the repository at this point in the history
  • Loading branch information
HeinrichApfelmus committed Nov 8, 2023
1 parent dcb4372 commit cb7683d
Show file tree
Hide file tree
Showing 22 changed files with 104 additions and 104 deletions.
7 changes: 2 additions & 5 deletions src/Foreign/JavaScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ module Foreign.JavaScript (
debug, timestamp,
) where

import Control.Concurrent.STM as STM
import Control.Monad (unless)
import qualified Data.Aeson as JSON
import Foreign.JavaScript.CallBuffer
import Foreign.JavaScript.EventLoop
import Foreign.JavaScript.Marshal
Expand All @@ -49,12 +46,12 @@ serve
:: Config -- ^ Configuration options.
-> (Window -> IO ()) -- ^ Initialization whenever a client connects.
-> IO ()
serve config init = httpComm config $ eventLoop $ \w -> do
serve config initialize = httpComm config $ eventLoop $ \w -> do
setCallBufferMode w (jsCallBufferMode config)
runFunction w $
ffi "connection.setReloadOnDisconnect(%1)" $ jsWindowReloadOnDisconnect config
flushCallBuffer w -- make sure that all `runEval` commands are executed
init w
initialize w
flushCallBuffer w -- make sure that all `runEval` commands are executed

{-----------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions src/Foreign/JavaScript/CallBuffer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ setCallBufferMode w new =

-- | Get the call buffering mode for the given browser window.
getCallBufferMode :: Window -> IO CallBufferMode
getCallBufferMode w@Window{..} = atomically $ readTVar wCallBufferMode
getCallBufferMode Window{..} = atomically $ readTVar wCallBufferMode

-- | Flush the call buffer,
-- i.e. send all outstanding JavaScript to the client in one single message.
Expand All @@ -26,7 +26,7 @@ flushCallBuffer w = flushCallBufferWithAtomic w $ return ()

-- | Flush the call buffer, and atomically perform an additional action
flushCallBufferWithAtomic :: Window -> STM a -> IO a
flushCallBufferWithAtomic w@Window{..} action = do
flushCallBufferWithAtomic Window{..} action = do
-- by taking the call buffer, we ensure that no further code
-- is added to the buffer while we execute the current buffer's code.
code' <- atomically $ takeTMVar wCallBuffer
Expand All @@ -39,7 +39,7 @@ flushCallBufferWithAtomic w@Window{..} action = do
-- | Schedule a piece of JavaScript code to be run with `runEval`,
-- depending on the buffering mode
bufferRunEval :: Window -> String -> IO ()
bufferRunEval w@Window{..} code = do
bufferRunEval Window{..} code = do
action <- atomically $ do
mode <- readTVar wCallBufferMode
case mode of
Expand All @@ -50,5 +50,5 @@ bufferRunEval w@Window{..} code = do
putTMVar wCallBuffer (msg . (\s -> ";" ++ code ++ s))
return Nothing
case action of
Nothing -> return ()
Just code -> runEval code
Nothing -> return ()
Just code1 -> runEval code1
23 changes: 10 additions & 13 deletions src/Foreign/JavaScript/EventLoop.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module Foreign.JavaScript.EventLoop (
newHandler, fromJSStablePtr, newJSObjectFromCoupon
) where

import Control.Applicative
import Control.Concurrent
import Control.Concurrent.Async
import Control.Concurrent.STM as STM
Expand All @@ -15,10 +14,7 @@ import Control.Exception as E
import Control.Monad
import qualified Data.Aeson as JSON
import qualified Data.ByteString.Char8 as BS
import Data.IORef
import qualified Data.Map as Map
import qualified Data.Text as T
import qualified System.Mem

import Foreign.RemotePtr as Foreign
import Foreign.JavaScript.CallBuffer
Expand All @@ -35,19 +31,20 @@ rebug = return ()
Event Loop
------------------------------------------------------------------------------}
-- | Handle a single event
handleEvent w@(Window{..}) (name, args) = do
handleEvent :: Window -> (Coupon, JSON.Value) -> IO ()
handleEvent Window{..} (name, args) = do
mhandler <- Foreign.lookup name wEventHandlers
case mhandler of
Nothing -> return ()
Just f -> withRemotePtr f (\_ f -> f args)
Just f -> withRemotePtr f (\_ g -> g args)


type Result = Either String JSON.Value

-- | Event loop for a browser window.
-- Supports concurrent invocations of `runEval` and `callEval`.
eventLoop :: (Window -> IO void) -> EventLoop
eventLoop init server info comm = void $ do
eventLoop initialize server info comm = void $ do
-- To support concurrent FFI calls, we need three threads.
-- A fourth thread supports
--
Expand Down Expand Up @@ -112,12 +109,12 @@ eventLoop init server info comm = void $ do

-- Send FFI calls to client and collect results
let handleCalls = forever $ do
ref <- atomically $ do
(ref, msg) <- readTQueue calls
mref <- atomically $ do
(mref, msg) <- readTQueue calls
writeServer comm msg
return ref
return mref
atomically $
case ref of
case mref of
Just ref -> do
result <- readTQueue results
putTMVar ref result
Expand Down Expand Up @@ -155,7 +152,7 @@ eventLoop init server info comm = void $ do
withAsync multiplexer $ \_ ->
withAsync handleCalls $ \_ ->
withAsync (flushCallBufferPeriodically w) $ \_ ->
E.finally (init w >> handleEvents) $ do
E.finally (initialize w >> handleEvents) $ do
putStrLn "Foreign.JavaScript: Browser window disconnected."
-- close communication channel if still necessary
commClose comm
Expand All @@ -175,7 +172,7 @@ flushCallBufferPeriodically w =
------------------------------------------------------------------------------}
-- | Turn a Haskell function into an event handler.
newHandler :: Window -> ([JSON.Value] -> IO ()) -> IO HsEvent
newHandler w@(Window{..}) handler = do
newHandler Window{..} handler = do
coupon <- newCoupon wEventHandlers
newRemotePtr coupon (handler . parseArgs) wEventHandlers
where
Expand Down
4 changes: 2 additions & 2 deletions src/Foreign/JavaScript/Include.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import System.IO

include :: FilePath -> Q Exp
include path = do
path <- makeRelativeToProject path
LitE . StringL <$> runIO (readFileUTF8 path)
relativePath <- makeRelativeToProject path
LitE . StringL <$> runIO (readFileUTF8 relativePath)

readFileUTF8 :: FilePath -> IO String
readFileUTF8 path = do
Expand Down
2 changes: 1 addition & 1 deletion src/Foreign/JavaScript/Marshal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import qualified Data.Aeson.Encode as JSON (encodeToTextBuilder)
#else
import qualified Data.Aeson.Text as JSON (encodeToTextBuilder)
#endif
import qualified Data.Aeson.Types as JSON
import Data.Functor ((<$>))
import Data.List (intercalate)
import qualified Data.Text as T
Expand Down Expand Up @@ -48,6 +47,7 @@ class ToJS a where
ys <- mapM render xs
jsCode $ "[" ++ intercalate "," (map unJSCode ys) ++ "]"

jsCode :: String -> IO JSCode
jsCode = return . JSCode

instance ToJS Float where render = render . JSON.toJSON
Expand Down
14 changes: 7 additions & 7 deletions src/Foreign/JavaScript/Server.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ import Data.ByteString (ByteString)
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as LBS
import qualified Data.Map as M
import Data.Text
import Data.Text (Text)
import qualified Safe as Safe
import System.Environment
import System.FilePath

-- import web libraries
import Data.Aeson ((.=))
import qualified Data.Aeson as JSON
import qualified Network.WebSockets as WS
import qualified Network.WebSockets.Snap as WS
import Snap.Core as Snap
import Snap.Core as Snap hiding (path, dir)
import qualified Snap.Http.Server as Snap
import Snap.Util.FileServe

Expand Down Expand Up @@ -114,15 +113,15 @@ communicationFromWebSocket request = do
let commClose = atomically $ STM.writeTVar commOpen False

-- read/write data until an exception occurs or the channel is no longer open
forkFinally (sendData `race_` readData `race_` sentry) $ \_ -> void $ do
_ <- forkFinally (sendData `race_` readData `race_` sentry) $ \_ -> void $ do
-- close the communication channel explicitly if that didn't happen yet
commClose

-- attempt to close websocket if still necessary/possible
-- ignore any exceptions that may happen if it's already closed
let all :: E.SomeException -> Maybe ()
all _ = Just ()
E.tryJust all $ WS.sendClose connection $ LBS.pack "close"
let allExceptions :: E.SomeException -> Maybe ()
allExceptions _ = Just ()
E.tryJust allExceptions $ WS.sendClose connection $ LBS.pack "close"

return $ Comm {..}

Expand Down Expand Up @@ -155,6 +154,7 @@ routeResources server customHTML staticDir =
Nothing -> logError "Foreign.JavaScript: Cannot use jsCustomHTML file without jsStatic"
Nothing -> writeTextMime defaultHtmlFile "text/html"

writeTextMime :: MonadSnap m => Text -> ByteString -> m ()
writeTextMime text mime = do
modifyResponse (setHeader "Content-type" mime)
writeText text
Expand Down
20 changes: 9 additions & 11 deletions src/Foreign/RemotePtr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ module Foreign.RemotePtr (

import Prelude hiding (lookup)
import Control.Monad
import Control.Concurrent
import qualified Data.Text as T
import qualified Data.HashMap.Strict as Map
import Data.Functor

Check warning on line 22 in src/Foreign/RemotePtr.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-ghc-8.10.7

The import of ‘Data.Functor’ is redundant

Check warning on line 22 in src/Foreign/RemotePtr.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-ghc-8.6.5

The import of ‘Data.Functor’ is redundant

Check warning on line 22 in src/Foreign/RemotePtr.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-ghc-8.8.4

The import of ‘Data.Functor’ is redundant

Check warning on line 22 in src/Foreign/RemotePtr.hs

View workflow job for this annotation

GitHub Actions / ubuntu-latest-ghc-9.2.8

The import of ‘Data.Functor’ is redundant
import Data.IORef

import System.IO.Unsafe (unsafePerformIO)
import System.Mem.Weak hiding (addFinalizer)
import qualified System.Mem.Weak as Weak

import qualified GHC.Base as GHC
import qualified GHC.Weak as GHC
Expand All @@ -42,14 +39,14 @@ atomicModifyIORef' = atomicModifyIORef
mkWeakIORefValue :: IORef a -> value -> IO () -> IO (Weak value)
#if CABAL
#if MIN_VERSION_base(4,9,0)
mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v (GHC.IO f) = GHC.IO $ \s ->
mkWeakIORefValue (GHC.IORef (GHC.STRef r#)) v (GHC.IO f) = GHC.IO $ \s ->
case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #)
#else
mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v f = GHC.IO $ \s ->
mkWeakIORefValue (GHC.IORef (GHC.STRef r#)) v f = GHC.IO $ \s ->
case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #)
#endif
#else
mkWeakIORefValue r@(GHC.IORef (GHC.STRef r#)) v (GHC.IO f) = GHC.IO $ \s ->
mkWeakIORefValue (GHC.IORef (GHC.STRef r#)) v (GHC.IO f) = GHC.IO $ \s ->
case GHC.mkWeak# r# v f s of (# s1, w #) -> (# s1, GHC.Weak w #)
#endif

Expand Down Expand Up @@ -133,8 +130,9 @@ newRemotePtr coupon value Vendor{..} = do
let self = undefined
ptr <- newIORef RemoteData{..}

let finalize = atomicModifyIORef' coupons $ \m -> (Map.delete coupon m, ())
w <- mkWeakIORef ptr finalize
let doFinalize =
atomicModifyIORef' coupons $ \m -> (Map.delete coupon m, ())
w <- mkWeakIORef ptr doFinalize
atomicModifyIORef' coupons $ \m -> (Map.insert coupon w m, ())
atomicModifyIORef' ptr $ \itemdata -> (itemdata { self = w }, ())
return ptr
Expand All @@ -148,10 +146,10 @@ newRemotePtr coupon value Vendor{..} = do
-- will not be garbage collected
-- and its 'Coupon' can be successfully redeemed at the 'Vendor'.
withRemotePtr :: RemotePtr a -> (Coupon -> a -> IO b) -> IO b
withRemotePtr ptr f = do
RemoteData{..} <- readIORef ptr
withRemotePtr ptr0 f = do
RemoteData{..} <- readIORef ptr0
b <- f coupon value
touch ptr
touch ptr0
return b
where
-- make sure that the pointer is alive at this point in the code
Expand Down
7 changes: 4 additions & 3 deletions src/Graphics/UI/Threepenny/Attributes.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# OPTIONS_GHC -Wno-missing-signatures #-}
module Graphics.UI.Threepenny.Attributes (
-- * Synopsis
-- | Element attributes.
Expand Down Expand Up @@ -50,13 +51,13 @@ selection = fromJQueryProp "selectedIndex" from (JSON.toJSON . maybe (-1) id)
http://hackage.haskell.org/package/html
------------------------------------------------------------------------------}
strAttr :: String -> WriteAttr Element String
strAttr name = mkWriteAttr (set' (attr name))
strAttr attrname = mkWriteAttr (set' (attr attrname))

intAttr :: String -> WriteAttr Element Int
intAttr name = mkWriteAttr (set' (attr name) . show)
intAttr attrname = mkWriteAttr (set' (attr attrname) . show)

emptyAttr :: String -> WriteAttr Element Bool
emptyAttr name = mkWriteAttr (set' (attr name) . f)
emptyAttr attrname = mkWriteAttr (set' (attr attrname) . f)
where
f True = "1"
f False = "0"
Expand Down
9 changes: 4 additions & 5 deletions src/Graphics/UI/Threepenny/Canvas.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Data.List(intercalate)
import Numeric (showHex)

import Graphics.UI.Threepenny.Core
import qualified Data.Aeson as JSON

{-----------------------------------------------------------------------------
Canvas
Expand Down Expand Up @@ -240,8 +239,8 @@ stroke = runFunction . ffi "%1.getContext('2d').stroke()"
-- The 'textAlign' attributes determines the position of the text
-- relative to the point.
fillText :: String -> Point -> Canvas -> UI ()
fillText text (x,y) canvas =
runFunction $ ffi "%1.getContext('2d').fillText(%2, %3, %4)" canvas text x y
fillText t (x,y) canvas =
runFunction $ ffi "%1.getContext('2d').fillText(%2, %3, %4)" canvas t x y

-- | Render the outline of a text at a certain point on the canvas.
--
Expand All @@ -250,8 +249,8 @@ fillText text (x,y) canvas =
-- The 'textAlign' attributes determines the position of the text
-- relative to the point.
strokeText :: String -> Point -> Canvas -> UI ()
strokeText text (x,y) canvas =
runFunction $ ffi "%1.getContext('2d').strokeText(%2, %3, %4)" canvas text x y
strokeText t (x,y) canvas =
runFunction $ ffi "%1.getContext('2d').strokeText(%2, %3, %4)" canvas t x y

{-----------------------------------------------------------------------------
helper functions
Expand Down
Loading

0 comments on commit cb7683d

Please sign in to comment.