headroom-0.4.0.0: src/Headroom/FileSupport.hs
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ViewPatterns #-}
{-|
Module : Headroom.FileSupport
Description : Support for handling various source code file types
Copyright : (c) 2019-2021 Vaclav Svejcar
License : BSD-3-Clause
Maintainer : vaclav.svejcar@gmail.com
Stability : experimental
Portability : POSIX
/Headroom/ currently supports working with file types defined in 'FileType'
type, and because every type of source code file requires different handling of
some aspects, this file type specific support is implemented for every supported
file type and exposed as instance of 'FileSupport' data type.
-}
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
------------------------------ PUBLIC FUNCTIONS ------------------------------
-- | Returns 'FileSupport' for corresponding 'FileType'.
fileSupport :: FileType -> FileSupport
fileSupport C = C.fileSupport
fileSupport CPP = CPP.fileSupport
fileSupport CSS = CSS.fileSupport
fileSupport Haskell = Haskell.fileSupport
fileSupport HTML = HTML.fileSupport
fileSupport Java = Java.fileSupport
fileSupport JS = JS.fileSupport
fileSupport PureScript = PureScript.fileSupport
fileSupport Rust = Rust.fileSupport
fileSupport Scala = Scala.fileSupport
fileSupport Shell = Shell.fileSupport
-- | Analyzes the raw source code of given type using provided 'FileSupport'.
analyzeSourceCode :: FileSupport
-- ^ 'FileSupport' implementation used for analysis
-> Text
-- ^ raw source code to analyze
-> SourceCode
-- ^ analyzed source code
analyzeSourceCode fs = fromText state0 process
where
SyntaxAnalysis {..} = fsSyntaxAnalysis fs
state0 = 0 :: Int
process (T.strip -> l) = do
cs <- get
let isStart = saIsCommentStart
isEnd = saIsCommentEnd
tpe = \c -> if c > 0 then Comment else Code
(ns, res) = if
| isStart l && isEnd l -> (cs, Comment)
| isStart l -> (cs + 1, Comment)
| isEnd l -> (cs - 1, tpe cs)
| cs > 0 -> (cs, Comment)
| otherwise -> (0, Code)
put ns
pure res