<commit_before>{-# LANGUAGE CPP,
             TypeFamilies,
             ScopedTypeVariables,
             TupleSections,
             OverloadedStrings #-}

module Main where

import           Config (cProjectVersion)
import           GHC
import           Hooks
import           HscMain
import           UniqFM (eltsUFM)
import           DynFlags
import           Platform
import           CorePrep (corePrepPgm)
import           DriverPhases (HscSource, Phase(..),
                               isHaskellSrcFilename, isHaskellUserSrcFilename,
                               isSourceFilename, startPhase)
import           DriverPipeline
import           DriverMkDepend ( doMkDependHS )
import           DsMeta (templateHaskellNames)
import           Exception
import           HscTypes (CgGuts(..), HscEnv(..), Dependencies(..),
                           NameCache (..), isBootSummary,
                           FindResult(..),
                           mkSOName, mkHsSOName )
import           IfaceEnv (initNameCache)
import           LoadIface
import           Outputable (showPpr)
import           Panic
import           Module
import           PrelInfo (wiredInThings)
import           PrelNames (basicKnownKeyNames)
import           PrimOp (allThePrimOps)
import           SysTools ( touch )
import           Packages
import           MkIface
import           GhcMonad
import           Digraph
import           Binary (fingerprintBinMem, openBinMem, put_)
import           Constants (hiVersion)
import           TcRnMonad (initIfaceCheck)
import           Util (looksLikeModuleName)
import           Outputable hiding ((<>))
import           MonadUtils (MonadIO(..))
import qualified SysTools
import           Control.Applicative
import qualified Control.Exception as Ex
import           Control.Monad

import           Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8  as C8
import           Data.Char (toLower)
import           Data.IORef (modifyIORef, writeIORef)
import           Data.List (isSuffixOf, isPrefixOf, tails, partition, nub,
                            intercalate, foldl', isInfixOf, sort)
import qualified Data.Map as M
import           Data.Maybe
import           Data.Monoid
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TL
import qualified Data.Text.Encoding as T

import           Distribution.Package (PackageName(..), PackageIdentifier(..))

import           Options.Applicative
import           Options.Applicative.Types
import           Options.Applicative.Builder.Internal

import           System.Directory (createDirectoryIfMissing, getAppUserDataDirectory,
                                   doesFileExist, copyFile)
import           System.Environment (getArgs, getEnv, getEnvironment)
import           System.Exit
import           System.FilePath
import           System.IO
import           System.Process (rawSystem)

import           GHCJS

import           Compiler.Info
import           Compiler.Variants
import           Compiler.GhcjsHooks
import           Compiler.GhcjsPlatform
import           Compiler.Settings
import           Compiler.Utils         as Util

import qualified Gen2.Utils     as Gen2
import qualified Gen2.Generator as Gen2
import qualified Gen2.Linker    as Gen2
import qualified Gen2.Shim      as Gen2
import qualified Gen2.Rts       as Gen2
import qualified Gen2.PrimIface as Gen2
import qualified Gen2.Foreign   as Gen2
import qualified Gen2.Object    as Object

import           Finder (findImportedModule, cannotFindInterface)

{- |
  Check if we're building a Cabal Setup script, in which case automatically
  switch to building a native executable and skip building all JS

  Detection is a bit tricky:
  - compilation mode is --make
  - Cabal doesn't manage dependencies for Setup.hs, so -hide-all-packages is not used
  - There is one Haskell source file, named Setup.hs or Setup.lhs
  - executable is named setup or setup.exe in a setup subdir
  - object and hi output dirs end with a setup subdir
-}
buildingCabalSetup :: [FilePath] -> DynFlags -> Bool
buildingCabalSetup [hs_src] dflags
  = ghcMode dflags == CompManager         &&
    not (gopt Opt_HideAllPackages dflags) &&
    isSetupOutput (outputFile dflags)     &&
    isSetupDir    (objectDir  dflags)     &&
    isSetupDir    (hiDir      dflags)     &&
    isSetupSource hs_src
  where
    isSetupOutput = maybe False (("/setup/setup" `isSuffixOf`) . dropExtension)
    isSetupDir    = maybe False ("/setup" `isSuffixOf`)
    isSetupSource = (`elem` ["Setup.hs", "Setup.lhs"]) . takeFileName
buildingCabalSetup _ _ = False


getGhcjsSettings :: [String] -> IO ([String], GhcjsSettings)
getGhcjsSettings args
  | Left failure <- p = do
     hPutStrLn stderr =<< errMessage failure "ghcjs"
     exitWith (errExitCode failure)
  | Right gs1 <- p = do
     gs2 <- envSettings
     return (args', gs1 <> gs2)
  where
    (ga,args') = partition (\a -> any (`isPrefixOf` a) as) args
    p = execParserPure (prefs mempty) optParser' ga
    as = [ "--native-executables"
         , "--no-native"
         , "--no-js-executables"
         , "--log-commandline="
         , "--with-ghc="
         , "--debug"
         , "--only-out"
         , "--no-rts"
         , "--no-stats"
         , "--generate-base="
         , "--use-base="<commit_msg>add lowercase `setup.hs` to list of setup scripts<commit_after>{-# LANGUAGE CPP,
             TypeFamilies,
             ScopedTypeVariables,
             TupleSections,
             OverloadedStrings #-}

module Main where

import           Config (cProjectVersion)
import           GHC
import           Hooks
import           HscMain
import           UniqFM (eltsUFM)
import           DynFlags
import           Platform
import           CorePrep (corePrepPgm)
import           DriverPhases (HscSource, Phase(..),
                               isHaskellSrcFilename, isHaskellUserSrcFilename,
                               isSourceFilename, startPhase)
import           DriverPipeline
import           DriverMkDepend ( doMkDependHS )
import           DsMeta (templateHaskellNames)
import           Exception
import           HscTypes (CgGuts(..), HscEnv(..), Dependencies(..),
                           NameCache (..), isBootSummary,
                           FindResult(..),
                           mkSOName, mkHsSOName )
import           IfaceEnv (initNameCache)
import           LoadIface
import           Outputable (showPpr)
import           Panic
import           Module
import           PrelInfo (wiredInThings)
import           PrelNames (basicKnownKeyNames)
import           PrimOp (allThePrimOps)
import           SysTools ( touch )
import           Packages
import           MkIface
import           GhcMonad
import           Digraph
import           Binary (fingerprintBinMem, openBinMem, put_)
import           Constants (hiVersion)
import           TcRnMonad (initIfaceCheck)
import           Util (looksLikeModuleName)
import           Outputable hiding ((<>))
import           MonadUtils (MonadIO(..))
import qualified SysTools
import           Control.Applicative
import qualified Control.Exception as Ex
import           Control.Monad

import           Data.ByteString (ByteString)
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import qualified Data.ByteString.Char8  as C8
import           Data.Char (toLower)
import           Data.IORef (modifyIORef, writeIORef)
import           Data.List (isSuffixOf, isPrefixOf, tails, partition, nub,
                            intercalate, foldl', isInfixOf, sort)
import qualified Data.Map as M
import           Data.Maybe
import           Data.Monoid
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.IO as TL
import qualified Data.Text.Encoding as T

import           Distribution.Package (PackageName(..), PackageIdentifier(..))

import           Options.Applicative
import           Options.Applicative.Types
import           Options.Applicative.Builder.Internal

import           System.Directory (createDirectoryIfMissing, getAppUserDataDirectory,
                                   doesFileExist, copyFile)
import           System.Environment (getArgs, getEnv, getEnvironment)
import           System.Exit
import           System.FilePath
import           System.IO
import           System.Process (rawSystem)

import           GHCJS

import           Compiler.Info
import           Compiler.Variants
import           Compiler.GhcjsHooks
import           Compiler.GhcjsPlatform
import           Compiler.Settings
import           Compiler.Utils         as Util

import qualified Gen2.Utils     as Gen2
import qualified Gen2.Generator as Gen2
import qualified Gen2.Linker    as Gen2
import qualified Gen2.Shim      as Gen2
import qualified Gen2.Rts       as Gen2
import qualified Gen2.PrimIface as Gen2
import qualified Gen2.Foreign   as Gen2
import qualified Gen2.Object    as Object

import           Finder (findImportedModule, cannotFindInterface)

{- |
  Check if we're building a Cabal Setup script, in which case automatically
  switch to building a native executable and skip building all JS

  Detection is a bit tricky:
  - compilation mode is --make
  - Cabal doesn't manage dependencies for Setup.hs, so -hide-all-packages is not used
  - There is one Haskell source file, named Setup.hs or Setup.lhs
  - executable is named setup or setup.exe in a setup subdir
  - object and hi output dirs end with a setup subdir
-}
buildingCabalSetup :: [FilePath] -> DynFlags -> Bool
buildingCabalSetup [hs_src] dflags
  = ghcMode dflags == CompManager         &&
    not (gopt Opt_HideAllPackages dflags) &&
    isSetupOutput (outputFile dflags)     &&
    isSetupDir    (objectDir  dflags)     &&
    isSetupDir    (hiDir      dflags)     &&
    isSetupSource hs_src
  where
    isSetupOutput = maybe False (("/setup/setup" `isSuffixOf`) . dropExtension)
    isSetupDir    = maybe False ("/setup" `isSuffixOf`)
    isSetupSource = (`elem` ["setup.hs", "Setup.hs", "Setup.lhs"]) . takeFileName
buildingCabalSetup _ _ = False


getGhcjsSettings :: [String] -> IO ([String], GhcjsSettings)
getGhcjsSettings args
  | Left failure <- p = do
     hPutStrLn stderr =<< errMessage failure "ghcjs"
     exitWith (errExitCode failure)
  | Right gs1 <- p = do
     gs2 <- envSettings
     return (args', gs1 <> gs2)
  where
    (ga,args') = partition (\a -> any (`isPrefixOf` a) as) args
    p = execParserPure (prefs mempty) optParser' ga
    as = [ "--native-executables"
         , "--no-native"
         , "--no-js-executables"
         , "--log-commandline="
         , "--with-ghc="
         , "--debug"
         , "--only-out"
         , "--no-rts"
         , "--no-stats"
         , "--generate-base="
         , "--use-base="
{'fraction_non_alphanumeric': 0.07467709659814445, 'fraction_numerical': 0.003820265599417864, 'mean_word_length': 2.1173802098100367, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4499733', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2955, 'n_words': 915}