{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
module Headroom.FileSupport
( fileSupport
, analyzeSourceCode
)
where
import Control.Monad.State ( get
, put
)
import qualified Headroom.FileSupport.C as C
import qualified Headroom.FileSupport.CPP as CPP
import qualified Headroom.FileSupport.CSS as CSS
import qualified Headroom.FileSupport.Haskell as Haskell
import qualified Headroom.FileSupport.HTML as HTML
import qualified Headroom.FileSupport.Java as Java
import qualified Headroom.FileSupport.JS as JS
import qualified Headroom.FileSupport.PureScript as PureScript
import qualified Headroom.FileSupport.Rust as Rust
import qualified Headroom.FileSupport.Scala as Scala
import qualified Headroom.FileSupport.Shell as Shell
import Headroom.FileSupport.Types ( FileSupport(..)
, SyntaxAnalysis(..)
)
import Headroom.FileType.Types ( FileType(..) )
import Headroom.SourceCode ( LineType(..)
, SourceCode
, fromText
)
import RIO
import qualified RIO.Text as T
fileSupport :: FileType -> FileSupport
fileSupport :: FileType -> FileSupport
fileSupport FileType
C = FileSupport
C.fileSupport
fileSupport FileType
CPP = FileSupport
CPP.fileSupport
fileSupport FileType
CSS = FileSupport
CSS.fileSupport
fileSupport FileType
Haskell = FileSupport
Haskell.fileSupport
fileSupport FileType
HTML = FileSupport
HTML.fileSupport
fileSupport FileType
Java = FileSupport
Java.fileSupport
fileSupport FileType
JS = FileSupport
JS.fileSupport
fileSupport FileType
PureScript = FileSupport
PureScript.fileSupport
fileSupport FileType
Rust = FileSupport
Rust.fileSupport
fileSupport FileType
Scala = FileSupport
Scala.fileSupport
fileSupport FileType
Shell = FileSupport
Shell.fileSupport
analyzeSourceCode :: FileSupport
-> Text
-> SourceCode
analyzeSourceCode :: FileSupport -> Text -> SourceCode
analyzeSourceCode FileSupport
fs = Int -> (Text -> State Int LineType) -> Text -> SourceCode
forall a. a -> (Text -> State a LineType) -> Text -> SourceCode
fromText Int
state0 Text -> State Int LineType
forall (m :: * -> *) a.
(MonadState a m, Num a, Ord a) =>
Text -> m LineType
process
where
SyntaxAnalysis {Text -> Bool
saIsCommentEnd :: SyntaxAnalysis -> Text -> Bool
saIsCommentStart :: SyntaxAnalysis -> Text -> Bool
saIsCommentEnd :: Text -> Bool
saIsCommentStart :: Text -> Bool
..} = FileSupport -> SyntaxAnalysis
fsSyntaxAnalysis FileSupport
fs
state0 :: Int
state0 = Int
0 :: Int
process :: Text -> m LineType
process (Text -> Text
T.strip -> Text
l) = do
a
cs <- m a
forall s (m :: * -> *). MonadState s m => m s
get
let isStart :: Text -> Bool
isStart = Text -> Bool
saIsCommentStart
isEnd :: Text -> Bool
isEnd = Text -> Bool
saIsCommentEnd
tpe :: a -> LineType
tpe = \a
c -> if a
c a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 then LineType
Comment else LineType
Code
(a
ns, LineType
res) = if
| Text -> Bool
isStart Text
l Bool -> Bool -> Bool
&& Text -> Bool
isEnd Text
l -> (a
cs, LineType
Comment)
| Text -> Bool
isStart Text
l -> (a
cs a -> a -> a
forall a. Num a => a -> a -> a
+ a
1, LineType
Comment)
| Text -> Bool
isEnd Text
l -> (a
cs a -> a -> a
forall a. Num a => a -> a -> a
- a
1, a -> LineType
tpe a
cs)
| a
cs a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
0 -> (a
cs, LineType
Comment)
| Bool
otherwise -> (a
0, LineType
Code)
a -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put a
ns
LineType -> m LineType
forall (f :: * -> *) a. Applicative f => a -> f a
pure LineType
res