<commit_before>{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}

module PureScript.Ide.Externs
  (
    ExternDecl(..),
    ModuleIdent,
    DeclIdent,
    Type,
    Fixity(..),
    readExternFile,
    convertExterns
  ) where


import           Data.Maybe                  (mapMaybe)
import           Control.Monad.Except
import qualified Data.Text                   as T
import qualified Data.Text.IO                as T
import qualified Language.PureScript.Externs as PE
import qualified Language.PureScript.AST.Declarations as D
import qualified Language.PureScript.Names   as N
import qualified Language.PureScript.Pretty  as PP
import           PureScript.Ide.CodecJSON
import           PureScript.Ide.Error        (PscIdeError (..))
import           PureScript.Ide.Types

readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
                  FilePath -> m PE.ExternsFile
readExternFile fp = do
   parseResult <- liftIO (decodeT <$> T.readFile fp)
   case parseResult of
     Nothing -> throwError . GeneralError $ "Parsing the extern at: " ++ fp ++ " failed"
     Just externs -> pure externs

moduleNameToText :: N.ModuleName -> T.Text
moduleNameToText = T.pack . N.runModuleName

properNameToText :: N.ProperName a -> T.Text
properNameToText = T.pack . N.runProperName

identToText :: N.Ident -> T.Text
identToText  = T.pack . N.runIdent

convertExterns :: PE.ExternsFile -> Module
convertExterns ef = (moduleName, exportDecls ++ importDecls ++ otherDecls)
  where
    moduleName = moduleNameToText (PE.efModuleName ef)
    importDecls = convertImport <$> PE.efImports ef
    exportDecls = mapMaybe convertExport (PE.efExports ef)
    -- Ignoring operator fixities for now since we're not using them
    -- operatorDecls = convertOperator <$> PE.efFixities ef
    otherDecls = mapMaybe convertDecl (PE.efDeclarations ef)

convertImport :: PE.ExternsImport -> ExternDecl
convertImport ei = Dependency (moduleNameToText (PE.eiModule ei)) []

convertExport :: D.DeclarationRef -> Maybe ExternDecl
convertExport (D.ModuleRef mn) = Just (Export (T.pack $ N.runModuleName mn))
convertExport _ = Nothing

convertDecl :: PE.ExternsDeclaration -> Maybe ExternDecl
convertDecl (PE.EDType{..}) = Just $
  DataDecl
  (properNameToText edTypeName)
  (T.pack (PP.prettyPrintKind edTypeKind))
convertDecl (PE.EDTypeSynonym{..}) = Just $
  DataDecl
  (properNameToText edTypeSynonymName)
  (T.pack (PP.prettyPrintType edTypeSynonymType))
convertDecl (PE.EDDataConstructor{..}) = Just $
  DataDecl
  (properNameToText edDataCtorName)
  (T.pack (PP.prettyPrintType edDataCtorType))
convertDecl (PE.EDValue{..}) = Just $
  FunctionDecl
  (identToText edValueName)
  (T.pack (PP.prettyPrintType edValueType))
convertDecl _ = Nothing
<commit_msg>strips newlines off the pretty printed types<commit_after>{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE RecordWildCards     #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}

module PureScript.Ide.Externs
  (
    ExternDecl(..),
    ModuleIdent,
    DeclIdent,
    Type,
    Fixity(..),
    readExternFile,
    convertExterns
  ) where


import           Data.Maybe                  (mapMaybe)
import           Control.Monad.Except
import           Data.Text (Text)
import qualified Data.Text                   as T
import qualified Data.Text.IO                as T
import qualified Language.PureScript.Externs as PE
import qualified Language.PureScript.AST.Declarations as D
import qualified Language.PureScript.Names   as N
import qualified Language.PureScript.Pretty  as PP
import           PureScript.Ide.CodecJSON
import           PureScript.Ide.Error        (PscIdeError (..))
import           PureScript.Ide.Types

readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
                  FilePath -> m PE.ExternsFile
readExternFile fp = do
   parseResult <- liftIO (decodeT <$> T.readFile fp)
   case parseResult of
     Nothing -> throwError . GeneralError $ "Parsing the extern at: " ++ fp ++ " failed"
     Just externs -> pure externs

moduleNameToText :: N.ModuleName -> Text
moduleNameToText = T.pack . N.runModuleName

properNameToText :: N.ProperName a -> Text
properNameToText = T.pack . N.runProperName

identToText :: N.Ident -> Text
identToText  = T.pack . N.runIdent

convertExterns :: PE.ExternsFile -> Module
convertExterns ef = (moduleName, exportDecls ++ importDecls ++ otherDecls)
  where
    moduleName = moduleNameToText (PE.efModuleName ef)
    importDecls = convertImport <$> PE.efImports ef
    exportDecls = mapMaybe convertExport (PE.efExports ef)
    -- Ignoring operator fixities for now since we're not using them
    -- operatorDecls = convertOperator <$> PE.efFixities ef
    otherDecls = mapMaybe convertDecl (PE.efDeclarations ef)

convertImport :: PE.ExternsImport -> ExternDecl
convertImport ei = Dependency (moduleNameToText (PE.eiModule ei)) []

convertExport :: D.DeclarationRef -> Maybe ExternDecl
convertExport (D.ModuleRef mn) = Just (Export (T.pack $ N.runModuleName mn))
convertExport _ = Nothing

convertDecl :: PE.ExternsDeclaration -> Maybe ExternDecl
convertDecl PE.EDType{..} = Just $
  DataDecl
  (properNameToText edTypeName)
  (packAndStrip (PP.prettyPrintKind edTypeKind))
convertDecl PE.EDTypeSynonym{..} = Just $
  DataDecl
  (properNameToText edTypeSynonymName)
  (packAndStrip (PP.prettyPrintType edTypeSynonymType))
convertDecl PE.EDDataConstructor{..} = Just $
  DataDecl
  (properNameToText edDataCtorName)
  (packAndStrip (PP.prettyPrintType edDataCtorType))
convertDecl PE.EDValue{..} = Just $
  FunctionDecl
  (identToText edValueName)
  (packAndStrip (PP.prettyPrintType edValueType))
convertDecl _ = Nothing

packAndStrip :: String -> Text
packAndStrip = T.unwords . fmap T.strip . T.lines . T.pack

{'fraction_non_alphanumeric': 0.09885290148448043, 'fraction_numerical': 0.0, 'mean_word_length': 3.4312406576980568, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 32, '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': '3195817', 'n_tokens_mistral': 1952, 'n_tokens_neox': 1879, 'n_words': 462}