<commit_before>module IdePurescript.Modules (Module, modulesState, initialModulesState, State, getMainModule, getModulesForFile,
  getUnqualActiveModules, getQualModule, findImportInsertPos) where

import Prelude ((<$>), pure, ($), bind, map, (==), (<<<), (++), const, (+))
import Data.Maybe (Maybe(Nothing, Just), maybe, fromMaybe)
import Data.Array (filter, singleton, findLastIndex)
import Control.Monad.Aff (Aff)
import Data.Either (either)
import Control.Monad.Eff.Ref (writeRef, readRef, newRef, REF)
import Control.Monad.Eff.Class (liftEff)
import Control.Monad.Eff (Eff)
import Data.String (split)
import Data.String.Regex as R

import PscIde as P
import PscIde.Command as C

import Control.Promise as Promise
import Data.Array (length, head)

data Module = Unqualified String | Qualified String String

getModuleName :: Module -> String
getModuleName (Qualified _ m) = m
getModuleName (Unqualified m) = m

type State =
  { main :: Maybe String
  , modules :: Array Module
  }

type Path = String

getMainModule :: String -> Maybe String
getMainModule text =
  case R.match regex text of
    Just [_, Just m] -> Just m
    _ -> Nothing
  where
  regex = R.regex """module\s+([\w.]+)""" $ R.noFlags { multiline = true }

getModulesForFile :: forall eff. Path -> String -> Aff (net :: P.NET | eff) State
getModulesForFile file fullText = do
  imports <- P.listImports file
  let modules = either (const []) (\(C.ImportList l) -> map mod l) imports
  let main = getMainModule fullText
  pure { main, modules }
  where
  mod (C.Import { moduleName, qualifier: Nothing }) = Unqualified moduleName
  mod (C.Import { moduleName, qualifier: Just qual }) = Qualified qual moduleName

getUnqualActiveModules :: State -> Array String
getUnqualActiveModules {modules, main} =
  map getModuleName $ maybe [] (singleton <<< Unqualified) main ++ modules


getQualModule :: String -> State -> Array String
getQualModule qualifier {modules} =
  map getModuleName $ filter (qual qualifier) modules
  where
  qual q (Qualified q' _) = q == q'
  qual _ _ = false

initialModulesState :: State
initialModulesState =  { main: Nothing, modules: [] }

modulesStateImpl = do
  stateRef <- newRef { main: Nothing, modules: [] }
  pure $
    {
      getQualModule: \s -> getQualModule s <$> readRef stateRef
    , getUnqualActiveModules: getUnqualActiveModules <$> readRef stateRef
    , loadModulesForFile: \f s -> do
        state <- getModulesForFile f s
        liftEff $ writeRef stateRef state
    , getMainModule: (\m -> fromMaybe "" m.main) <$> readRef stateRef
    }

modulesState :: forall eff. Eff (ref :: REF | eff) _
modulesState = do
  m <- modulesStateImpl
  pure
    {
      loadModules: \f s -> Promise.fromAff $ m.loadModulesForFile f s
    , getUnqualActiveModules: m.getUnqualActiveModules
    , getQualModule: m.getQualModule
    , getMainModule: m.getMainModule
    , getMainModuleForFile: fromMaybe "" <<< getMainModule
    }

findImportInsertPos :: String -> Int
findImportInsertPos text =
  let regex = R.regex """^(module|import) [A-Z][^(]*($|\([^()]*\))""" R.noFlags
      lines = split "\n" text
      res = fromMaybe 0 $ findLastIndex (R.test regex) lines
  in res+1<commit_msg>Remove unused functinos<commit_after>module IdePurescript.Modules (
    Module
  , initialModulesState
  , State
  , getMainModule
  , getModulesForFile
  , getUnqualActiveModules
  , getQualModule
  , findImportInsertPos
  ) where

import Prelude ((+), ($), map, (==), (<<<), (++), pure, const, bind)
import Data.Maybe (Maybe(Nothing, Just), maybe, fromMaybe)
import Data.Array (filter, singleton, findLastIndex)
import Control.Monad.Aff (Aff)
import Data.Either (either)
import Data.String (split)
import Data.String.Regex as R

import PscIde as P
import PscIde.Command as C

data Module = Unqualified String | Qualified String String

getModuleName :: Module -> String
getModuleName (Qualified _ m) = m
getModuleName (Unqualified m) = m

type State =
  { main :: Maybe String
  , modules :: Array Module
  }

type Path = String

getMainModule :: String -> Maybe String
getMainModule text =
  case R.match regex text of
    Just [_, Just m] -> Just m
    _ -> Nothing
  where
  regex = R.regex """module\s+([\w.]+)""" $ R.noFlags { multiline = true }

getModulesForFile :: forall eff. Path -> String -> Aff (net :: P.NET | eff) State
getModulesForFile file fullText = do
  imports <- P.listImports file
  let modules = either (const []) (\(C.ImportList l) -> map mod l) imports
  let main = getMainModule fullText
  pure { main, modules }
  where
  mod (C.Import { moduleName, qualifier: Nothing }) = Unqualified moduleName
  mod (C.Import { moduleName, qualifier: Just qual }) = Qualified qual moduleName

getUnqualActiveModules :: State -> Array String
getUnqualActiveModules {modules, main} =
  map getModuleName $ maybe [] (singleton <<< Unqualified) main ++ modules

getQualModule :: String -> State -> Array String
getQualModule qualifier {modules} =
  map getModuleName $ filter (qual qualifier) modules
  where
  qual q (Qualified q' _) = q == q'
  qual _ _ = false

initialModulesState :: State
initialModulesState =  { main: Nothing, modules: [] }

findImportInsertPos :: String -> Int
findImportInsertPos text =
  let regex = R.regex """^(module|import) [A-Z][^(]*($|\([^()]*\))""" R.noFlags
      lines = split "\n" text
      res = fromMaybe 0 $ findLastIndex (R.test regex) lines
  in res+1
{'fraction_non_alphanumeric': 0.121431219873934, 'fraction_numerical': 0.0007415647015202076, 'mean_word_length': 3.9224452554744524, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5913212', 'n_tokens_mistral': 1699, 'n_tokens_neox': 1693, 'n_words': 526}