Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix c2hs handling in Cabal #6233

Draft
wants to merge 40 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
fbef0e3
Add sorting mechanism for chs files
vmchale Sep 11, 2019
c3e9b87
Fix nested parser bug + remove dead code
vmchale Sep 11, 2019
e74115e
Style improvements + slimming
vmchale Sep 11, 2019
cca903b
Reorder c2hs files in a library
vmchale Sep 11, 2019
2290218
Prettify
vmchale Sep 11, 2019
625423e
Update ChangeLog
vmchale Sep 11, 2019
71b6d32
Compatibility with older GHCs
vmchale Sep 11, 2019
16b00a2
Disbale warning since we're using a wrapper/template
vmchale Sep 11, 2019
8358fdf
Use Cabal prelude
vmchale Sep 11, 2019
6338732
Fix build for older GHCs
vmchale Sep 11, 2019
c018b57
Check Cabal/Distribution/C2Hs/Lexer.hs into version control for sake …
vmchale Sep 11, 2019
f721560
Use bootstraph script for Alex
vmchale Sep 11, 2019
64c7d1a
Use Makefile for lexer
vmchale Sep 11, 2019
6281535
Use makefile approach
vmchale Sep 11, 2019
bc1ed2c
Modify makefile
vmchale Sep 11, 2019
0dc1c71
Try to reduce time on Mac
vmchale Sep 11, 2019
a4a2448
Travis don't install happy
vmchale Sep 11, 2019
f71b5af
Pass verbosity appropriately + use cabal's graph/sort capabilities
vmchale Sep 13, 2019
a8c95ae
Add comments to functions
vmchale Sep 13, 2019
5f2814f
Clean up + consistent indentation
vmchale Sep 13, 2019
746ae57
Polish up lexer module w.r.t. documentation
vmchale Sep 13, 2019
2154c2c
Use revTopSort instead of reverse . topSort
vmchale Sep 13, 2019
eb3d592
Merge branch 'master' of github.com:vmchale/cabal
vmchale Sep 13, 2019
b616f0e
Polish/rewrite Distribution.C2Hs
vmchale Sep 13, 2019
243e6b8
Add a few unit tests
vmchale Sep 13, 2019
e9cb223
Add tests of c2hs import lexer
vmchale Sep 13, 2019
7b2c729
Add tests of reorderC2Hs + example source files
vmchale Sep 13, 2019
0d0ec9e
Fix documentation + escape correctly
vmchale Sep 13, 2019
0812063
Don't bother supporting .chs main file
vmchale Sep 14, 2019
34f3ff0
Don't use $> to preserve GHC 7.6.3 compatibility
vmchale Sep 14, 2019
280e647
Merge branch 'master' of github.com:haskell/cabal
vmchale Sep 16, 2019
f4c354a
Merge branch 'master' of github.com:haskell/cabal
vmchale Sep 24, 2019
d6f6feb
Merge branch 'master' of github.com:haskell/cabal
vmchale Sep 25, 2019
6b461de
Fix block comments
vmchale Sep 28, 2019
6ae37b0
Add unit tests for block comments
vmchale Sep 28, 2019
fe760c5
Move test modules
vmchale Sep 28, 2019
6031b43
Expand module-level comment
vmchale Sep 28, 2019
ca7537b
Add a module-level comment to Cabal.Distribution.C2Hs
vmchale Sep 28, 2019
5bc4c03
Merge branch 'master' of github.com:haskell/cabal
vmchale Oct 13, 2019
0bba20f
merge
vmchale Nov 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ library
Distribution.Version
Language.Haskell.Extension
Distribution.Compat.Binary
Distribution.C2Hs
Distribution.C2Hs.Lexer

-- Parsec parser-related modules
build-depends:
Expand Down Expand Up @@ -606,6 +608,8 @@ test-suite unit-tests
UnitTests.Distribution.Utils.ShortText
UnitTests.Distribution.Version
UnitTests.Distribution.PkgconfigVersion
UnitTests.Distribution.C2Hs.Lexer
UnitTests.Distribution.C2Hs
main-is: UnitTests.hs
build-depends:
array,
Expand Down
1 change: 1 addition & 0 deletions Cabal/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* `cabal check` verifies `cpp-options` more pedantically, allowing only
options starting with `-D` and `-U`.
* TODO
* Fix dependency resolution for preprocessing `chs` files.

----

Expand Down
49 changes: 49 additions & 0 deletions Cabal/Distribution/C2Hs.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}

-- | This module contains a function to order @.chs@ files based on their
-- dependencies on one another thusly: it lexes the @.chs@ source files
-- looking for @{\# import \#}@ declarations and then topologically sorts
-- the modules. This ensures that a module's dependencies are preprocessed
-- first.
module Distribution.C2Hs ( reorderC2Hs ) where

import Prelude()
import Distribution.Compat.Graph
import Distribution.Compat.Prelude
import Distribution.C2Hs.Lexer
import Distribution.ModuleName (ModuleName, toFilePath)
import Distribution.Parsec (simpleParsec)
import Distribution.Simple.Utils (warn, findFileWithExtension)
import Distribution.Verbosity (Verbosity)

-- | Given a list of 'ModuleName's, sort it according to @c2hs@ @{\#import\#}@
-- declarations.
reorderC2Hs :: Verbosity
-> [FilePath] -- ^ Source directories
-> [ModuleName] -- ^ Module names
-> IO [ModuleName] -- ^ Sorted modules
reorderC2Hs v dirs preMods = do

chsFiles <- traverse findCHS preMods

modDeps <- traverse (extractDeps v) (zip preMods chsFiles)

pure $ fmap (\(N m _ _) -> m) (revTopSort $ fromDistinctList modDeps)

where findCHS = findFileWithExtension [".chs"] dirs . toFilePath


-- | Given a 'ModuleName' and its corresponding filepath, return a 'Node'
-- with its associated @c2hs@ dependencies
extractDeps :: Verbosity -> (ModuleName, Maybe FilePath) -> IO (Node ModuleName ModuleName)
-- If the 'FilePath' is 'Nothing', it's not a @.chs@ file
extractDeps _ (m, Nothing) = pure (N m m [])
extractDeps v (m, Just f) = do
con <- readFile f
mods <- case getImports con of
Right ms -> case traverse simpleParsec ms of
Just ms' -> pure ms'
Nothing -> do { warn v ("Cannot parse module name in c2hs file " ++ f) ; pure [] }
Left err -> do { warn v ("Cannot parse c2hs import in " ++ f ++ ": " ++ err) ; pure [] }
pure (N m m mods)
511 changes: 511 additions & 0 deletions Cabal/Distribution/C2Hs/Lexer.hs

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions Cabal/Distribution/Simple/PreProcess.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import Prelude ()
import Distribution.Compat.Prelude
import Distribution.Compat.Stack

import Distribution.C2Hs
import Distribution.Simple.PreProcess.Unlit
import Distribution.Backpack.DescribeUnitId
import Distribution.Package
Expand Down Expand Up @@ -168,21 +169,24 @@ preprocessComponent pd comp lbi clbi isSrcDist verbosity handlers = do
(CLib lib@Library{ libBuildInfo = bi }) -> do
let dirs = hsSourceDirs bi ++ [autogenComponentModulesDir lbi clbi
,autogenPackageModulesDir lbi]
for_ (map ModuleName.toFilePath $ allLibModules lib clbi) $
mods <- reorderC2Hs verbosity dirs (allLibModules lib clbi)
for_ (map ModuleName.toFilePath mods) $
pre dirs (componentBuildDir lbi clbi) (localHandlers bi)
(CFLib flib@ForeignLib { foreignLibBuildInfo = bi, foreignLibName = nm }) -> do
let nm' = unUnqualComponentName nm
let flibDir = buildDir lbi </> nm' </> nm' ++ "-tmp"
dirs = hsSourceDirs bi ++ [autogenComponentModulesDir lbi clbi
,autogenPackageModulesDir lbi]
for_ (map ModuleName.toFilePath $ foreignLibModules flib) $
mods <- reorderC2Hs verbosity dirs (foreignLibModules flib)
for_ (map ModuleName.toFilePath mods) $
pre dirs flibDir (localHandlers bi)
(CExe exe@Executable { buildInfo = bi, exeName = nm }) -> do
let nm' = unUnqualComponentName nm
let exeDir = buildDir lbi </> nm' </> nm' ++ "-tmp"
dirs = hsSourceDirs bi ++ [autogenComponentModulesDir lbi clbi
,autogenPackageModulesDir lbi]
for_ (map ModuleName.toFilePath $ otherModules bi) $
mods <- reorderC2Hs verbosity dirs (otherModules bi)
for_ (map ModuleName.toFilePath mods) $
pre dirs exeDir (localHandlers bi)
pre (hsSourceDirs bi) exeDir (localHandlers bi) $
dropExtensions (modulePath exe)
Expand Down
8 changes: 7 additions & 1 deletion Cabal/tests/UnitTests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import Distribution.Simple.Utils
import Distribution.Verbosity
import Distribution.Compat.Time

import qualified UnitTests.Distribution.C2Hs
import qualified UnitTests.Distribution.C2Hs.Lexer
import qualified UnitTests.Distribution.Compat.CreatePipe
import qualified UnitTests.Distribution.Compat.Time
import qualified UnitTests.Distribution.Compat.Graph
Expand All @@ -37,7 +39,11 @@ tests mtimeChangeCalibrated =
else mtimeChangeCalibrated
in
testGroup "Unit Tests"
[ testGroup "Distribution.Compat.CreatePipe"
[ testGroup "Distribution.C2Hs"
UnitTests.Distribution.C2Hs.tests
, testGroup "Distribution.C2Hs.Lexer"
UnitTests.Distribution.C2Hs.Lexer.tests
, testGroup "Distribution.Compat.CreatePipe"
UnitTests.Distribution.Compat.CreatePipe.tests
, testGroup "Distribution.Compat.Time"
(UnitTests.Distribution.Compat.Time.tests mtimeChange)
Expand Down
18 changes: 18 additions & 0 deletions Cabal/tests/UnitTests/Distribution/C2Hs.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{-# LANGUAGE OverloadedStrings #-}

module UnitTests.Distribution.C2Hs ( tests ) where

import Distribution.C2Hs
import Distribution.Verbosity (normal)

import Test.Tasty
import Test.Tasty.HUnit

tests :: [TestTree]
tests = [ testCase "libarchive" $
reorderC2Hs normal ["tests/c2hsTestModules/src"] ["Codec.Archive.Foreign.Archive", "Codec.Archive.Types.Foreign"]
>>= (@?= ["Codec.Archive.Types.Foreign", "Codec.Archive.Foreign.Archive"])
, testCase "libarchive" $
reorderC2Hs normal ["tests/c2hsTestModules/src"] ["Codec.Archive.Types.Foreign", "Codec.Archive.Foreign.Archive"]
>>= (@?= ["Codec.Archive.Types.Foreign", "Codec.Archive.Foreign.Archive"])
]
21 changes: 21 additions & 0 deletions Cabal/tests/UnitTests/Distribution/C2Hs/Lexer.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module UnitTests.Distribution.C2Hs.Lexer ( tests ) where

import Distribution.C2Hs.Lexer

import Test.Tasty
import Test.Tasty.HUnit

tests :: [TestTree]
tests = [ testCase "simple import" $
getImports "{# import Data.Char #}" @?= Right ["Data.Char"]
, testCase "line comment" $
getImports "-- {# import Data.Char #}" @?= Right []
, testCase "nested block comment" $
getImports "{- nested {- comment -} -} {# import Data.Char #}" @?= Right ["Data.Char"]
, testCase "Not find spurious imports" $
getImports "import Data.Word\n{# import Data.Char #}" @?= Right ["Data.Char"]
, testCase "Work with qualified imports + spaces" $
getImports "{# import qualified Data.Char #}" @?= Right ["Data.Char"]
, testCase "Error on bad block comments" $
getImports "{- {- block comment -} {# import Data.Char #}" @?= Left "Error in nested comment at line 1, column 46"
]
Loading