Merge pull request #56 from Profpatsch/mkDots-automatic-symbol-quoting

mkDots automatic symbol quoting
This commit is contained in:
John Wiegley 2017-04-21 11:31:18 -07:00 committed by GitHub
commit aba54891c5
6 changed files with 65 additions and 4 deletions

View file

@ -11,6 +11,8 @@ import Data.Fix
import qualified Data.Map as Map
import Nix.Atoms
import Nix.Expr.Types
import Text.Regex.TDFA.Text ()
import Text.Regex.TDFA ((=~))
-- | Make an integer literal expression.
mkInt :: Integer -> NExpr
@ -126,10 +128,21 @@ mkFunction :: Params NExpr -> NExpr -> NExpr
mkFunction params = Fix . NAbs params
mkDot :: NExpr -> Text -> NExpr
mkDot e key = Fix $ NSelect e [StaticKey key] Nothing
mkDot e key = mkDots e [key]
mkDots :: NExpr -> [Text] -> NExpr
mkDots e keys = Fix $ NSelect e (StaticKey <$> keys) Nothing
mkDots e keys = Fix $ NSelect e (toKey <$> keys) Nothing
where
toKey :: Text -> NKeyName NExpr
toKey k = (if isPlainSymbol k then StaticKey else dynamicKey) k
-- | Make a dynamic key name that is only enclosed in double quotes
-- (no antiquotes).
dynamicKey :: Text -> NKeyName NExpr
dynamicKey k = DynamicKey $ Plain $ DoubleQuoted [Plain k]
-- | Check if its a valid nix symbol
-- the nix lexer regex for IDs (symbols) is [a-zA-Z\_][a-zA-Z0-9\_\'\-]*
isPlainSymbol :: Text -> Bool
isPlainSymbol s = s =~ ("^[a-zA-Z_][a-zA-Z0-9_'-]*$" :: Text)
-- | An `inherit` clause without an expression to pull from.
inherit :: [NKeyName e] -> Binding e

View file

@ -1,6 +1,9 @@
{ nixpkgs ? import <nixpkgs> {}, compiler ? "ghc801" }:
{ nixpkgs ? import <nixpkgs> {}, compiler ? null }:
let
haskellPackages = nixpkgs.pkgs.haskell.packages.${compiler};
haskellPackages = if compiler == null
# use the current default version
then nixpkgs.pkgs.haskellPackages
else nixpkgs.pkgs.haskell.packages.${compiler};
in
haskellPackages.callPackage ./project.nix {

View file

@ -62,6 +62,8 @@ Library
, data-fix
, deepseq
, semigroups >= 0.18 && < 0.19
, regex-tdfa
, regex-tdfa-text
if flag(parsec)
Cpp-options: -DUSE_PARSEC
Build-depends: parsec

View file

@ -1,6 +1,7 @@
{ mkDerivation, ansi-wl-pprint, base, containers, data-fix, deepseq
, parsers, stdenv, tasty, tasty-hunit, tasty-th, text, transformers
, trifecta, unordered-containers, criterion, pkgs, deriving-compat
, regex-tdfa, regex-tdfa-text
}:
let
@ -19,6 +20,7 @@ mkDerivation {
libraryHaskellDepends = [
ansi-wl-pprint base containers data-fix deepseq parsers text
transformers trifecta unordered-containers criterion deriving-compat
regex-tdfa regex-tdfa-text
];
executableHaskellDepends = [
ansi-wl-pprint base containers data-fix deepseq

View file

@ -4,6 +4,7 @@ import Test.Tasty
import qualified ParserTests
import qualified EvalTests
import qualified ShorthandTests
import Prelude (IO, ($))
@ -11,4 +12,5 @@ main :: IO ()
main = defaultMain $ testGroup "hnix"
[ ParserTests.tests
, EvalTests.tests
, ShorthandTests.tests
]

39
tests/ShorthandTests.hs Normal file
View file

@ -0,0 +1,39 @@
{-# LANGUAGE TemplateHaskell, OverloadedStrings #-}
module ShorthandTests (tests) where
import Prelude
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.TH
import Control.Monad (forM_)
import Data.Monoid ((<>))
import Data.Fix
import Nix.Expr
case_mkDotsSymbolEscaping :: Assertion
case_mkDotsSymbolEscaping = do
let check xs errmsg assert =
forM_ xs $ \x -> assertBool (errmsg <> ": " <> show x) $ assert x
check plain "not a plain value" $ assertIsSingle
check nonPlain "not a non-plain value" $ not . assertIsSingle
where
plain = [ "abc09", "_A_'-", "AbC" ]
nonPlain = [ "abc def", "\\", "'abc", "\"", "-foo", "a.b.c" ]
assertIsSingle = isPlainSingle . getKey . mkDot "dummy"
getKey (Fix (NSelect _ [key] _)) = key
getKey _ = error "invalid"
isPlainSingle (StaticKey _) = True
isPlainSingle (DynamicKey (Plain (DoubleQuoted [Plain _]))) = False
isPlainSingle _ = error "invalid"
---------------------------
tests :: TestTree
tests = $(testGroupGenerator)