From 051405f98fc94db1646d82974971e220823785f5 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 8 Nov 2021 17:56:33 +0200 Subject: [PATCH 01/33] TestCommon: refactor --- tests/EvalTests.hs | 2 +- tests/TestCommon.hs | 40 ++++++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/tests/EvalTests.hs b/tests/EvalTests.hs index b68f1e3f..7fafb44f 100644 --- a/tests/EvalTests.hs +++ b/tests/EvalTests.hs @@ -625,7 +625,7 @@ constantEqualText expected actual = do constantEqualText' expected actual mres <- liftIO $ on (<|>) lookupEnv "ALL_TESTS" "MATCHING_TESTS" - whenJust (const $ assertEvalMatchesNix actual) mres + whenJust (const $ assertEvalTextMatchesNix actual) mres assertNixEvalThrows :: Text -> Assertion assertNixEvalThrows a = diff --git a/tests/TestCommon.hs b/tests/TestCommon.hs index 023245f7..20fbcfcd 100644 --- a/tests/TestCommon.hs +++ b/tests/TestCommon.hs @@ -35,6 +35,8 @@ hnixEvalFile opts file = ) parseResult +nixEvalFile :: Path -> IO Text +nixEvalFile (coerce -> fp) = fromString <$> readProcess "nix-instantiate" ["--eval", "--strict", fp] mempty hnixEvalText :: Options -> Text -> IO StdVal hnixEvalText opts src = either @@ -42,8 +44,8 @@ hnixEvalText opts src = (runWithBasicEffects opts . (normalForm <=< nixEvalExpr mempty)) $ parseNixText src -nixEvalString :: Text -> IO Text -nixEvalString expr = +nixEvalText :: Text -> IO Text +nixEvalText expr = do (fp, h) <- mkstemp "nix-test-eval" Text.hPutStr h expr @@ -52,21 +54,27 @@ nixEvalString expr = removeLink fp pure res -nixEvalFile :: Path -> IO Text -nixEvalFile fp = fromString <$> readProcess "nix-instantiate" ["--eval", "--strict", coerce fp] mempty +assertEvalMatchesNix + :: ( Options + -> Text -> IO (NValue t (StdCited StandardIO) StandardIO) + ) + -> (Text -> IO Text) + -> Text + -> IO () +assertEvalMatchesNix evalHNix evalNix fp = + do + time <- liftIO getCurrentTime + hnixVal <- (<> "\n") . printNix <$> evalHNix (defaultOptions time) fp + nixVal <- evalNix fp + assertEqual (toString fp) nixVal hnixVal assertEvalFileMatchesNix :: Path -> Assertion assertEvalFileMatchesNix fp = - do - time <- liftIO getCurrentTime - hnixVal <- (<> "\n") . printNix <$> hnixEvalFile (defaultOptions time) fp - nixVal <- nixEvalFile fp - assertEqual (coerce fp) nixVal hnixVal + assertEvalMatchesNix + (\ o -> hnixEvalFile o . coerce . toString) + (nixEvalFile . coerce . toString) + $ fromString $ coerce fp -assertEvalMatchesNix :: Text -> Assertion -assertEvalMatchesNix expr = - do - time <- liftIO getCurrentTime - hnixVal <- (<> "\n") . printNix <$> hnixEvalText (defaultOptions time) expr - nixVal <- nixEvalString expr - assertEqual (toString expr) nixVal hnixVal +assertEvalTextMatchesNix :: Text -> Assertion +assertEvalTextMatchesNix = + assertEvalMatchesNix hnixEvalText nixEvalText From 3d75a2026a689a8467367a66cbbc8b1a4075c937 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 8 Nov 2021 19:04:07 +0200 Subject: [PATCH 02/33] Expr.Strings: m clean-up --- src/Nix/Expr/Strings.hs | 12 +++++++----- tests/TestCommon.hs | 17 +++++++++-------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index 377e78c2..a80f9855 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -39,14 +39,16 @@ runAntiquoted nl f _ EscapedNewline = f nl runAntiquoted _ _ k (Antiquoted r) = k r -- | Split a stream representing a string with antiquotes on line breaks. -splitLines :: [Antiquoted Text r] -> [[Antiquoted Text r]] -splitLines = uncurry (flip (:)) . go where - go (Plain t : xs) = (Plain l :) <$> foldr f (go xs) ls +splitLines :: forall r . [Antiquoted Text r] -> [[Antiquoted Text r]] +splitLines = uncurry (flip (:)) . go + where + go :: [Antiquoted Text r] -> ([[Antiquoted Text r]], [Antiquoted Text r]) + go (Plain t : xs) = (one (Plain l) <>) <$> foldr f (go xs) ls where (l : ls) = T.split (== '\n') t f prefix (finished, current) = ((Plain prefix : current) : finished, mempty) - go (Antiquoted a : xs) = (Antiquoted a :) <$> go xs - go (EscapedNewline : xs) = (EscapedNewline :) <$> go xs + go (Antiquoted a : xs) = (one (Antiquoted a) <>) <$> go xs + go (EscapedNewline : xs) = (one EscapedNewline <>) <$> go xs go [] = mempty -- | Join a stream of strings containing antiquotes again. This is the inverse diff --git a/tests/TestCommon.hs b/tests/TestCommon.hs index 20fbcfcd..900ab4ff 100644 --- a/tests/TestCommon.hs +++ b/tests/TestCommon.hs @@ -24,14 +24,15 @@ hnixEvalFile opts file = do setEnv "TEST_VAR" "foo" runWithBasicEffects opts $ - catch (evaluateExpression (pure $ coerce file) nixEvalExprLoc normalForm expr) $ - \case - NixException frames -> - errorWithoutStackTrace . show - =<< renderFrames - @StdVal - @StdThun - frames + evaluateExpression (pure $ coerce file) nixEvalExprLoc normalForm expr + `catch` + \case + NixException frames -> + errorWithoutStackTrace . show + =<< renderFrames + @StdVal + @StdThun + frames ) parseResult From 65a107b696d6cd87a450b218e2fe3a4100fc7809 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 8 Nov 2021 19:07:23 +0200 Subject: [PATCH 03/33] Parser: flatten the structure of quatation functions --- src/Nix/Parser.hs | 130 +++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/src/Nix/Parser.hs b/src/Nix/Parser.hs index ff1a11ac..8b3fdc88 100644 --- a/src/Nix/Parser.hs +++ b/src/Nix/Parser.hs @@ -271,73 +271,73 @@ nixAntiquoted p = antiquotedLexeme <|> Plain <$> p +escapeCode :: Parser Char +escapeCode = + msum + [ c <$ char e | (c, e) <- escapeCodes ] + <|> anySingle + +stringChar + :: Parser () + -> Parser () + -> Parser (Antiquoted Text NExprLoc) + -> Parser (Antiquoted Text NExprLoc) +stringChar end escStart esc = + antiquoted + <|> Plain . one <$> char '$' + <|> esc + <|> Plain . fromString <$> some plainChar + where + plainChar :: Parser Char + plainChar = + notFollowedBy (end <|> void (char '$') <|> escStart) *> anySingle + +doubleQuoted :: Parser (NString NExprLoc) +doubleQuoted = + label "double quoted string" $ + DoubleQuoted . removeEmptyPlains . mergePlain <$> + inQuotationMarks (many $ stringChar quotationMark (void $ char '\\') doubleEscape) + where + inQuotationMarks :: Parser a -> Parser a + inQuotationMarks expr = quotationMark *> expr <* quotationMark + + quotationMark :: Parser () + quotationMark = void $ char '"' + + doubleEscape :: Parser (Antiquoted Text r) + doubleEscape = Plain . one <$> (char '\\' *> escapeCode) + +indented :: Parser (NString NExprLoc) +indented = + label "indented string" $ + stripIndent <$> + inIndentedQuotation (many $ join stringChar indentedQuotationMark indentedEscape) + where + indentedEscape :: Parser (Antiquoted Text r) + indentedEscape = + try $ + do + indentedQuotationMark + (Plain <$> ("''" <$ char '\'' <|> "$" <$ char '$')) + <|> + do + _ <- char '\\' + c <- escapeCode + + pure $ + bool + EscapedNewline + (Plain $ one c) + (c /= '\n') + + inIndentedQuotation :: Parser a -> Parser a + inIndentedQuotation expr = indentedQuotationMark *> expr <* indentedQuotationMark + + indentedQuotationMark :: Parser () + indentedQuotationMark = label "\"''\"" . void $ chunk "''" + nixString' :: Parser (NString NExprLoc) nixString' = label "string" $ lexeme $ doubleQuoted <|> indented - where - doubleQuoted :: Parser (NString NExprLoc) - doubleQuoted = - label "double quoted string" $ - DoubleQuoted . removeEmptyPlains . mergePlain <$> - inQuotationMarks (many $ stringChar quotationMark (void $ char '\\') doubleEscape) - where - inQuotationMarks :: Parser a -> Parser a - inQuotationMarks expr = quotationMark *> expr <* quotationMark - - quotationMark :: Parser () - quotationMark = void $ char '"' - - doubleEscape :: Parser (Antiquoted Text r) - doubleEscape = Plain . one <$> (char '\\' *> escapeCode) - - indented :: Parser (NString NExprLoc) - indented = - label "indented string" $ - stripIndent <$> - inIndentedQuotation (many $ join stringChar indentedQuotationMark indentedEscape) - where - indentedEscape :: Parser (Antiquoted Text r) - indentedEscape = - try $ - do - indentedQuotationMark - (Plain <$> ("''" <$ char '\'' <|> "$" <$ char '$')) - <|> - do - _ <- char '\\' - c <- escapeCode - - pure $ - bool - EscapedNewline - (Plain $ one c) - (c /= '\n') - - inIndentedQuotation :: Parser a -> Parser a - inIndentedQuotation expr = indentedQuotationMark *> expr <* indentedQuotationMark - - indentedQuotationMark :: Parser () - indentedQuotationMark = label "\"''\"" . void $ chunk "''" - - stringChar - :: Parser () - -> Parser () - -> Parser (Antiquoted Text NExprLoc) - -> Parser (Antiquoted Text NExprLoc) - stringChar end escStart esc = - antiquoted - <|> Plain . one <$> char '$' - <|> esc - <|> Plain . fromString <$> some plainChar - where - plainChar :: Parser Char - plainChar = - notFollowedBy (end <|> void (char '$') <|> escStart) *> anySingle - - escapeCode :: Parser Char - escapeCode = - msum - [ c <$ char e | (c, e) <- escapeCodes ] - <|> anySingle nixString :: Parser NExprLoc nixString = annNStr <$> annotateLocation1 nixString' From 1683aea44fb105c990540bfff6e44d85ed2c8eaa Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 10 Jan 2022 23:35:59 +0200 Subject: [PATCH 04/33] Pretty: a bit of docs --- src/Nix/Pretty.hs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index f47cdefa..fd14b64e 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -116,6 +116,7 @@ escapeDoubleQuoteString (x: Doc ann prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" where @@ -133,11 +134,14 @@ prettyString (Indented _ parts) = group $ nest 2 $ vcat flt [Plain t] | Text.null (strip t) = False flt _ = True + prettyLine :: [Antiquoted Text (NixDoc ann)] -> Doc ann prettyLine = hcat . fmap prettyPart - prettyPart (Plain t) = - pretty . replace "${" "''${" . replace "''" "'''" $ t - prettyPart EscapedNewline = "\\n" - prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" + where + prettyPart :: Antiquoted Text (NixDoc ann) -> Doc ann + prettyPart (Plain t) = + pretty . replace "${" "''${" . replace "''" "'''" $ t + prettyPart EscapedNewline = "\\n" + prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" prettyVarName :: VarName -> Doc ann prettyVarName = pretty @Text . coerce @@ -174,9 +178,9 @@ prettyBind (NamedVar n v _p) = prettySelector n <> " = " <> withoutParens v <> ";" prettyBind (Inherit s ns _p) = "inherit " <> scope <> align (fillSep $ prettyVarName <$> ns) <> ";" - where - scope = - ((<> " ") . parens . withoutParens) `whenJust` s + where + scope = + ((<> " ") . parens . withoutParens) `whenJust` s prettyKeyName :: NKeyName (NixDoc ann) -> Doc ann prettyKeyName (StaticKey key) = From d3dd6a274bb3ec777153e90a58ea540812edbdcc Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 8 Nov 2021 21:50:08 +0200 Subject: [PATCH 05/33] Builtins: splitVersion: m upd --- src/Nix/Builtins.hs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs index 30dc0e66..00b3efe1 100644 --- a/src/Nix/Builtins.hs +++ b/src/Nix/Builtins.hs @@ -247,22 +247,20 @@ instance Show VersionComponent where splitVersion :: Text -> [VersionComponent] splitVersion s = - whenJust - (\ (x, xs) -> if - | isRight eDigitsPart -> - either - (\ e -> error $ "splitVersion: did hit impossible: '" <> fromString e <> "' while parsing '" <> s <> "'.") - (\ res -> - one (VersionComponentNumber $ fst res) - <> splitVersion (snd res) - ) - eDigitsPart + (\ (x, xs) -> if + | isRight eDigitsPart -> + either + (\ e -> error $ "splitVersion: did hit impossible: '" <> fromString e <> "' while parsing '" <> s <> "'.") + (\ res -> + one (VersionComponentNumber $ fst res) + <> splitVersion (snd res) + ) + eDigitsPart - | x `elem` separators -> splitVersion xs + | x `elem` separators -> splitVersion xs - | otherwise -> one charsPart <> splitVersion rest2 - ) - (Text.uncons s) + | otherwise -> one charsPart <> splitVersion rest2 + ) `whenJust` Text.uncons s where -- | Based on https://github.com/NixOS/nix/blob/4ee4fda521137fed6af0446948b3877e0c5db803/src/libexpr/names.cc#L44 separators :: String From 67072c21098119758af90ea1b9613c6cccdb5ed7 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 8 Nov 2021 21:55:36 +0200 Subject: [PATCH 06/33] Parser: m doc --- src/Nix/Parser.hs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Nix/Parser.hs b/src/Nix/Parser.hs index 8b3fdc88..0bf79b25 100644 --- a/src/Nix/Parser.hs +++ b/src/Nix/Parser.hs @@ -307,12 +307,14 @@ doubleQuoted = doubleEscape :: Parser (Antiquoted Text r) doubleEscape = Plain . one <$> (char '\\' *> escapeCode) + indented :: Parser (NString NExprLoc) indented = label "indented string" $ stripIndent <$> inIndentedQuotation (many $ join stringChar indentedQuotationMark indentedEscape) - where + where + -- | Read escaping inside of the "'' ''" indentedEscape :: Parser (Antiquoted Text r) indentedEscape = try $ @@ -330,12 +332,15 @@ indented = (Plain $ one c) (c /= '\n') + -- | Enclosed into indented quatation "'' ''" inIndentedQuotation :: Parser a -> Parser a inIndentedQuotation expr = indentedQuotationMark *> expr <* indentedQuotationMark + -- | Symbol "''" indentedQuotationMark :: Parser () indentedQuotationMark = label "\"''\"" . void $ chunk "''" + nixString' :: Parser (NString NExprLoc) nixString' = label "string" $ lexeme $ doubleQuoted <|> indented From ea5351f35a1e6bb92f8b5f91ecc003f7f4b85544 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 16:48:48 +0200 Subject: [PATCH 07/33] EvalTestsL m clean-up --- tests/EvalTests.hs | 3 +-- tests/TestCommon.hs | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/EvalTests.hs b/tests/EvalTests.hs index 7fafb44f..8329eda8 100644 --- a/tests/EvalTests.hs +++ b/tests/EvalTests.hs @@ -649,9 +649,8 @@ sameFreeVars a xs = do let Right a' = parseNixText a - xs' = S.fromList xs free' = getFreeVars a' - assertEqual mempty xs' free' + assertEqual mempty (S.fromList xs) free' maskedFiles :: [Path] maskedFiles = one "builtins.fetchurl-01.nix" diff --git a/tests/TestCommon.hs b/tests/TestCommon.hs index 900ab4ff..bf9b9309 100644 --- a/tests/TestCommon.hs +++ b/tests/TestCommon.hs @@ -69,6 +69,7 @@ assertEvalMatchesNix evalHNix evalNix fp = nixVal <- evalNix fp assertEqual (toString fp) nixVal hnixVal +-- | Compares @HNix@ & @Nix@ return results. assertEvalFileMatchesNix :: Path -> Assertion assertEvalFileMatchesNix fp = assertEvalMatchesNix From a1b9ee19458e7aade64ee16cb5be7304150cc2be Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 16:49:46 +0200 Subject: [PATCH 08/33] Pretty: m clean-up --- src/Nix/Pretty.hs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index fd14b64e..df734fad 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -156,7 +156,7 @@ prettyParams (ParamSet mname variadic pset) = toDoc (coerce -> name) = ("@" <> pretty name) `whenFalse` Text.null name -prettyParamSet :: Variadic -> ParamSet (NixDoc ann) -> Doc ann +prettyParamSet :: forall ann . Variadic -> ParamSet (NixDoc ann) -> Doc ann prettyParamSet variadic args = encloseSep "{ " @@ -164,6 +164,7 @@ prettyParamSet variadic args = sep (fmap prettySetArg args <> one "..." `whenTrue` (variadic == Variadic)) where + prettySetArg :: (VarName, Maybe (NixDoc ann)) -> Doc ann prettySetArg (n, maybeDef) = maybe varName @@ -171,7 +172,7 @@ prettyParamSet variadic args = maybeDef where varName = prettyVarName n - sep = align ", " + sep = align ", " prettyBind :: Binding (NixDoc ann) -> Doc ann prettyBind (NamedVar n v _p) = From 18d07bec2884a6ebac80ec6153a15bbdc24decd7 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 17:02:55 +0200 Subject: [PATCH 09/33] Pretty: clean-up --- src/Nix/Pretty.hs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index df734fad..3e8ee812 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -83,7 +83,7 @@ hasAttrOp = getSpecialOperator NHasAttrOp wrapParens :: OperatorInfo -> NixDoc ann -> Doc ann wrapParens op sub = bool - (\ a -> "(" <> a <> ")") + parens id ( precedence (rootOp sub) < precedence op || (precedence (rootOp sub) == precedence op @@ -188,9 +188,10 @@ prettyKeyName (StaticKey key) = bool "\"\"" (bool - varName - ("\"" <> varName <> "\"") + id + dquotes (HashSet.member key reservedNames) + varName ) (not $ Text.null $ coerce key) where @@ -258,7 +259,7 @@ exprFNixDoc = \case ] where opInfo = getBinaryOperator op - f :: NAssoc -> NixDoc ann1 -> Doc ann1 + f :: NAssoc -> NixDoc ann -> Doc ann f x = wrapParens $ bool @@ -276,11 +277,8 @@ exprFNixDoc = \case (mkNixDoc selectOp) (const leastPrecedence) o - $ wrapPath selectOp r <> "." <> prettySelector attr <> ordoc - where - r = mkNixDoc selectOp (wrapParens appOpNonAssoc r') - ordoc = - ((" or " <>) . wrapParens appOpNonAssoc) `whenJust` o + $ wrapPath selectOp (mkNixDoc selectOp (wrapParens appOpNonAssoc r')) <> "." <> prettySelector attr <> + ((" or " <>) . wrapParens appOpNonAssoc) `whenJust` o NHasAttr r attr -> mkNixDoc hasAttrOp (wrapParens hasAttrOp r <> " ? " <> prettySelector attr) NEnvPath p -> simpleExpr $ pretty @String $ "<" <> coerce p <> ">" From ef52b4e9f67619248d70709be215cfd4d9f8e942 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 17:17:22 +0200 Subject: [PATCH 10/33] Pretty: m clean-up --- src/Nix/Pretty.hs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 3e8ee812..bf5ca36e 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -230,7 +230,7 @@ prettyOriginExpr = withoutParens . go -- . go . originExpr) -- mempty (reverse ps) -exprFNixDoc :: NExprF (NixDoc ann) -> NixDoc ann +exprFNixDoc :: forall ann . NExprF (NixDoc ann) -> NixDoc ann exprFNixDoc = \case NConstant atom -> prettyAtom atom NStr str -> simpleExpr $ prettyString str @@ -307,11 +307,15 @@ exprFNixDoc = \case leastPrecedence $ group $ nest 2 $ - sep - [ "if " <> withoutParens cond - , align ("then " <> withoutParens trueBody) - , align ("else " <> withoutParens falseBody) - ] + sep $ + ifThenElse withoutParens + where + ifThenElse :: (NixDoc ann -> Doc ann) -> [Doc ann] + ifThenElse wp = + [ "if " <> wp cond + , align ("then " <> wp trueBody) + , align ("else " <> wp falseBody) + ] NWith scope body -> prettyAddScope "with " scope body NAssert cond body -> @@ -418,10 +422,8 @@ printNix = iterNValueByDiscardWith thk phi v (tryRead @Int <|> tryRead @Float) where - surround s = "\"" <> s <> "\"" - tryRead :: forall a . (Read a, Show a) => Maybe Text - tryRead = fmap (surround . show) (readMaybe (toString v) :: Maybe a) + tryRead = fmap ((\ s -> "\"" <> s <> "\"") . show) $ readMaybe @a $ toString v phi NVClosure'{} = "<>" phi (NVPath' fp ) = fromString $ coerce fp phi (NVBuiltin' name _) = "< coerce name <> ">>" From a898e493e5719745931508ad932cb25e4a7cd884 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Mon, 10 Jan 2022 23:37:45 +0200 Subject: [PATCH 11/33] Pretty: NixDoc: (withoutParens->getDoc) --- src/Nix/Pretty.hs | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index bf5ca36e..f6a4c512 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -35,8 +35,8 @@ import Nix.Value -- | This type represents a pretty printed nix expression -- together with some information about the expression. data NixDoc ann = NixDoc - { -- | The rendered expression, without any parentheses. - withoutParens :: Doc ann + { -- | Rendered expression. Without surrounding parenthesis. + getDoc :: Doc ann -- | The root operator is the operator at the root of -- the expression tree. For example, in '(a * b) + c', '+' would be the root @@ -48,7 +48,7 @@ data NixDoc ann = NixDoc } mkNixDoc :: OperatorInfo -> Doc ann -> NixDoc ann -mkNixDoc o d = NixDoc { withoutParens = d, rootOp = o, wasPath = False } +mkNixDoc o d = NixDoc { getDoc = d, rootOp = o, wasPath = False } -- | A simple expression is never wrapped in parentheses. The expression -- behaves as if its root operator had a precedence higher than all @@ -66,7 +66,7 @@ pathExpr d = (simpleExpr d) { wasPath = True } -- binding). leastPrecedence :: Doc ann -> NixDoc ann leastPrecedence = - mkNixDoc (OperatorInfo maxBound NAssocNone "least precedence") + mkNixDoc $ OperatorInfo maxBound NAssocNone "least precedence" appOp :: OperatorInfo appOp = getBinaryOperator NApp @@ -90,7 +90,7 @@ wrapParens op sub = && associativity (rootOp sub) == associativity op && associativity op /= NAssocNone) ) - (withoutParens sub) + (getDoc sub) -- Used in the selector case to print a path in a selector as -- "${./abc}" @@ -98,7 +98,7 @@ wrapPath :: OperatorInfo -> NixDoc ann -> Doc ann wrapPath op sub = bool (wrapParens op sub) - ("\"${" <> withoutParens sub <> "}\"") + ("\"${" <> getDoc sub <> "}\"") (wasPath sub) @@ -122,7 +122,13 @@ prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" where prettyPart (Plain t) = pretty $ escapeDoubleQuoteString t prettyPart EscapedNewline = "''\\n" - prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" + prettyPart (Antiquoted r) = "${" <> getDoc r <> "}" + escape '"' = "\\\"" + escape x = + maybe + (one x) + (('\\' :) . one) + (toEscapeCode x) prettyString (Indented _ parts) = group $ nest 2 $ vcat ["''", content, "''"] where @@ -141,7 +147,7 @@ prettyString (Indented _ parts) = group $ nest 2 $ vcat prettyPart (Plain t) = pretty . replace "${" "''${" . replace "''" "'''" $ t prettyPart EscapedNewline = "\\n" - prettyPart (Antiquoted r) = "${" <> withoutParens r <> "}" + prettyPart (Antiquoted r) = "${" <> getDoc r <> "}" prettyVarName :: VarName -> Doc ann prettyVarName = pretty @Text . coerce @@ -168,7 +174,7 @@ prettyParamSet variadic args = prettySetArg (n, maybeDef) = maybe varName - (\x -> varName <> " ? " <> withoutParens x) + (\x -> varName <> " ? " <> getDoc x) maybeDef where varName = prettyVarName n @@ -176,12 +182,12 @@ prettyParamSet variadic args = prettyBind :: Binding (NixDoc ann) -> Doc ann prettyBind (NamedVar n v _p) = - prettySelector n <> " = " <> withoutParens v <> ";" + prettySelector n <> " = " <> getDoc v <> ";" prettyBind (Inherit s ns _p) = "inherit " <> scope <> align (fillSep $ prettyVarName <$> ns) <> ";" where scope = - ((<> " ") . parens . withoutParens) `whenJust` s + ((<> " ") . parens . getDoc) `whenJust` s prettyKeyName :: NKeyName (NixDoc ann) -> Doc ann prettyKeyName (StaticKey key) = @@ -200,7 +206,7 @@ prettyKeyName (DynamicKey key) = runAntiquoted (DoubleQuoted $ one $ Plain "\n") prettyString - (\ x -> "${" <> withoutParens x <> "}") + (\ x -> "${" <> getDoc x <> "}") key prettySelector :: NAttrPath (NixDoc ann) -> Doc ann @@ -210,14 +216,14 @@ prettyAtom :: NAtom -> NixDoc ann prettyAtom = simpleExpr . pretty . atomText prettyNix :: NExpr -> Doc ann -prettyNix = withoutParens . foldFix exprFNixDoc +prettyNix = getDoc . foldFix exprFNixDoc prettyOriginExpr :: forall t f m ann . HasCitations1 m (NValue t f m) f => NExprLocF (Maybe (NValue t f m)) -> Doc ann -prettyOriginExpr = withoutParens . go +prettyOriginExpr = getDoc . go where go = exprFNixDoc . stripAnnF . fmap render where @@ -226,7 +232,7 @@ prettyOriginExpr = withoutParens . go render (Just (Free (reverse . citations @m -> p:_))) = go (_originExpr p) render _ = simpleExpr "?" -- render (Just (NValue (citations -> ps))) = - -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . withoutParens + -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . getDoc -- . go . originExpr) -- mempty (reverse ps) @@ -245,7 +251,7 @@ exprFNixDoc = \case nest 2 $ vsep [ prettyParams args <> ":" - , withoutParens body + , getDoc body ] NBinary NApp fun arg -> mkNixDoc appOp (wrapParens appOp fun <> " " <> wrapParens appOpNonAssoc arg) @@ -301,14 +307,14 @@ exprFNixDoc = \case vsep [ "let" , indent 2 (vsep (fmap prettyBind binds)) - , "in " <> withoutParens body + , "in " <> getDoc body ] NIf cond trueBody falseBody -> leastPrecedence $ group $ nest 2 $ sep $ - ifThenElse withoutParens + ifThenElse getDoc where ifThenElse :: (NixDoc ann -> Doc ann) -> [Doc ann] ifThenElse wp = @@ -331,7 +337,7 @@ exprFNixDoc = \case prettyAddScope h c b = leastPrecedence $ vsep - [h <> withoutParens c <> ";", align $ withoutParens b] + [h <> getDoc c <> ";", align $ getDoc b] valueToExpr :: forall t f m . MonadDataContext f m => NValue t f m -> NExpr From 64b3c10dae752f42198d348712e9fdd9e221de4c Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 18:46:31 +0200 Subject: [PATCH 12/33] Pretty: (wrapParens->precedenceWrap) --- src/Nix/Parser.hs | 13 ++++++++----- src/Nix/Pretty.hs | 49 +++++++++++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/src/Nix/Parser.hs b/src/Nix/Parser.hs index 0bf79b25..5737c63a 100644 --- a/src/Nix/Parser.hs +++ b/src/Nix/Parser.hs @@ -592,6 +592,7 @@ nixOperators selector = one $ binaryR NImpl "->" ] +-- 2021-11-09: NOTE: rename OperatorInfo accessors to `get*` -- 2021-08-10: NOTE: -- All this is a sidecar: -- * This type @@ -601,11 +602,13 @@ nixOperators selector = -- * getSpecialOperation -- can reduced in favour of adding precedence field into @NOperatorDef@. -- details: https://github.com/haskell-nix/hnix/issues/982 -data OperatorInfo = OperatorInfo - { precedence :: Int - , associativity :: NAssoc - , operatorName :: Text - } deriving (Eq, Ord, Generic, Typeable, Data, Show) +data OperatorInfo = + OperatorInfo + { precedence :: Int + , associativity :: NAssoc + , operatorName :: Text + } + deriving (Eq, Ord, Generic, Typeable, Data, Show) detectPrecedence :: Ord a diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index f6a4c512..97f3cd6a 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -5,6 +5,7 @@ {-# options_ghc -fno-warn-name-shadowing #-} +-- 2021-11-09: NOTE: Please do not reduce explicit `"${" <> a <> "}"` types of wrappings - as they are readable and so analyzable at eyesight. HNix already has a difficult task of 100% matching the escaping of an unpstream project. module Nix.Pretty where @@ -80,24 +81,34 @@ selectOp = getSpecialOperator NSelectOp hasAttrOp :: OperatorInfo hasAttrOp = getSpecialOperator NHasAttrOp -wrapParens :: OperatorInfo -> NixDoc ann -> Doc ann -wrapParens op sub = - bool - parens - id - ( precedence (rootOp sub) < precedence op - || (precedence (rootOp sub) == precedence op - && associativity (rootOp sub) == associativity op - && associativity op /= NAssocNone) - ) - (getDoc sub) +-- | Determine if to return doc wraped into parens, +-- according the given operator. +precedenceWrap :: OperatorInfo -> NixDoc ann -> Doc ann +precedenceWrap op sub = maybeWrap (getDoc sub) + where + maybeWrap :: Doc ann -> Doc ann + maybeWrap = + bool + parens + id + needsParens + + root = rootOp sub + + needsParens :: Bool + needsParens = + precedence root < precedence op + || (precedence root == precedence op + && associativity root == associativity op + && associativity op /= NAssocNone + ) -- Used in the selector case to print a path in a selector as -- "${./abc}" wrapPath :: OperatorInfo -> NixDoc ann -> Doc ann wrapPath op sub = bool - (wrapParens op sub) + (precedenceWrap op sub) ("\"${" <> getDoc sub <> "}\"") (wasPath sub) @@ -241,7 +252,7 @@ exprFNixDoc = \case NConstant atom -> prettyAtom atom NStr str -> simpleExpr $ prettyString str NList xs -> - prettyContainer "[" (wrapParens appOpNonAssoc) "]" xs + prettyContainer "[" (precedenceWrap appOpNonAssoc) "]" xs NSet NonRecursive xs -> prettyContainer "{" prettyBind "}" xs NSet Recursive xs -> @@ -254,7 +265,7 @@ exprFNixDoc = \case , getDoc body ] NBinary NApp fun arg -> - mkNixDoc appOp (wrapParens appOp fun <> " " <> wrapParens appOpNonAssoc arg) + mkNixDoc appOp (precedenceWrap appOp fun <> " " <> precedenceWrap appOpNonAssoc arg) NBinary op r1 r2 -> mkNixDoc opInfo $ @@ -267,7 +278,7 @@ exprFNixDoc = \case opInfo = getBinaryOperator op f :: NAssoc -> NixDoc ann -> Doc ann f x = - wrapParens + precedenceWrap $ bool opInfo (opInfo { associativity = NAssocNone }) @@ -275,7 +286,7 @@ exprFNixDoc = \case NUnary op r1 -> mkNixDoc opInfo $ - pretty (operatorName opInfo) <> wrapParens opInfo r1 + pretty (operatorName opInfo) <> precedenceWrap opInfo r1 where opInfo = getUnaryOperator op NSelect o r' attr -> @@ -283,10 +294,10 @@ exprFNixDoc = \case (mkNixDoc selectOp) (const leastPrecedence) o - $ wrapPath selectOp (mkNixDoc selectOp (wrapParens appOpNonAssoc r')) <> "." <> prettySelector attr <> - ((" or " <>) . wrapParens appOpNonAssoc) `whenJust` o + $ wrapPath selectOp (mkNixDoc selectOp (precedenceWrap appOpNonAssoc r')) <> "." <> prettySelector attr <> + ((" or " <>) . precedenceWrap appOpNonAssoc) `whenJust` o NHasAttr r attr -> - mkNixDoc hasAttrOp (wrapParens hasAttrOp r <> " ? " <> prettySelector attr) + mkNixDoc hasAttrOp (precedenceWrap hasAttrOp r <> " ? " <> prettySelector attr) NEnvPath p -> simpleExpr $ pretty @String $ "<" <> coerce p <> ">" NLiteralPath p -> pathExpr $ From 235d27933cf93d1cc09114ec29aed1fd36f1dec9 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 20:42:52 +0200 Subject: [PATCH 13/33] Provenance: rename Provenance & NCited constructors --- src/Nix/Cited.hs | 17 +++++++++-------- src/Nix/Pretty.hs | 9 +++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Nix/Cited.hs b/src/Nix/Cited.hs index 9a97e62b..ba236067 100644 --- a/src/Nix/Cited.hs +++ b/src/Nix/Cited.hs @@ -16,8 +16,9 @@ import Control.Monad.Free ( Free(Pure, Free) ) data Provenance m v = Provenance - { _lexicalScope :: Scopes m v - , _originExpr :: NExprLocF (Maybe v) + { getLexicalScope :: Scopes m v + -- 2021-11-09: NOTE: Better name? + , getOriginExpr :: NExprLocF (Maybe v) -- ^ When calling the function x: x + 2 with argument x = 3, the -- 'originExpr' for the resulting value will be 3 + 2, while the -- 'contextExpr' will be @(x: x + 2) 3@, preserving not only the @@ -27,8 +28,8 @@ data Provenance m v = data NCited m v a = NCited - { _provenance :: [Provenance m v] - , _cited :: a + { getProvenance :: [Provenance m v] + , getCited :: a } deriving (Generic, Typeable, Functor, Foldable, Traversable, Show) @@ -37,11 +38,11 @@ instance Applicative (NCited m v) where (<*>) (NCited xs f) (NCited ys x) = NCited (xs <> ys) (f x) instance Comonad (NCited m v) where - duplicate p = NCited (_provenance p) p - extract = _cited + duplicate p = NCited (getProvenance p) p + extract = getCited instance ComonadEnv [Provenance m v] (NCited m v) where - ask = _provenance + ask = getProvenance $(makeLenses ''Provenance) $(makeLenses ''NCited) @@ -55,7 +56,7 @@ class HasCitations m v a where addProvenance :: Provenance m v -> a -> a instance HasCitations m v (NCited m v a) where - citations = _provenance + citations = getProvenance addProvenance x (NCited p v) = NCited (x : p) v instance HasCitations1 m v f diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 97f3cd6a..e145f236 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -73,7 +73,7 @@ appOp :: OperatorInfo appOp = getBinaryOperator NApp appOpNonAssoc :: OperatorInfo -appOpNonAssoc = (getBinaryOperator NApp) { associativity = NAssocNone } +appOpNonAssoc = appOp { associativity = NAssocNone } selectOp :: OperatorInfo selectOp = getSpecialOperator NSelectOp @@ -236,11 +236,12 @@ prettyOriginExpr -> Doc ann prettyOriginExpr = getDoc . go where + go :: NExprLocF (Maybe (NValue t f m)) -> NixDoc ann go = exprFNixDoc . stripAnnF . fmap render where render :: Maybe (NValue t f m) -> NixDoc ann render Nothing = simpleExpr "_" - render (Just (Free (reverse . citations @m -> p:_))) = go (_originExpr p) + render (Just (Free (reverse . citations @m -> p:_))) = go (getOriginExpr p) render _ = simpleExpr "?" -- render (Just (NValue (citations -> ps))) = -- simpleExpr $ foldr ((\x y -> vsep [x, y]) . parens . indent 2 . getDoc @@ -388,7 +389,7 @@ prettyNValueProv v = fillSep [ prettyNVal , indent 2 $ - "(" <> fold (one "from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")" + "(" <> fold (one "from: " <> (prettyOriginExpr . getOriginExpr <$> ps)) <> ")" ] ) (citations @m @(NValue t f m) v) @@ -412,7 +413,7 @@ prettyNThunk t = fillSep [ v' , indent 2 $ - "(" <> fold (one "thunk from: " <> (prettyOriginExpr . _originExpr <$> ps)) <> ")" + "(" <> fold (one "thunk from: " <> (prettyOriginExpr . getOriginExpr <$> ps)) <> ")" ] From a557fc72312084f2bb1023765d164cb092f698dd Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 9 Nov 2021 22:48:34 +0200 Subject: [PATCH 14/33] Pretty: add prettyExtractFromProvenance --- src/Nix/Pretty.hs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index e145f236..e99367b1 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -248,6 +248,15 @@ prettyOriginExpr = getDoc . go -- . go . originExpr) -- mempty (reverse ps) +-- | Takes original expression from inside provenance information. +-- Prettifies that expression. +prettyExtractFromProvenance + :: forall t f m ann + . HasCitations1 m (NValue t f m) f + => [Provenance m (NValue t f m)] -> [Doc ann] +prettyExtractFromProvenance = + fmap (prettyOriginExpr . getOriginExpr) + exprFNixDoc :: forall ann . NExprF (NixDoc ann) -> NixDoc ann exprFNixDoc = \case NConstant atom -> prettyAtom atom @@ -389,7 +398,7 @@ prettyNValueProv v = fillSep [ prettyNVal , indent 2 $ - "(" <> fold (one "from: " <> (prettyOriginExpr . getOriginExpr <$> ps)) <> ")" + "(" <> fold (one "from: " <> prettyExtractFromProvenance ps) <> ")" ] ) (citations @m @(NValue t f m) v) @@ -413,7 +422,7 @@ prettyNThunk t = fillSep [ v' , indent 2 $ - "(" <> fold (one "thunk from: " <> (prettyOriginExpr . getOriginExpr <$> ps)) <> ")" + "(" <> fold (one "thunk from: " <> prettyExtractFromProvenance ps) <> ")" ] From b133a6ee3146b12349e4812dac8c14cbbec67a0d Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 00:26:51 +0200 Subject: [PATCH 15/33] Pretty: m layout --- src/Nix/Pretty.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index e99367b1..0247442e 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -336,9 +336,9 @@ exprFNixDoc = \case nest 2 $ sep $ ifThenElse getDoc - where - ifThenElse :: (NixDoc ann -> Doc ann) -> [Doc ann] - ifThenElse wp = + where + ifThenElse :: (NixDoc ann -> Doc ann) -> [Doc ann] + ifThenElse wp = [ "if " <> wp cond , align ("then " <> wp trueBody) , align ("else " <> wp falseBody) From fd1dcc966978ea9e75d7c93bcd9db4c297f69ce2 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 13:44:17 +0200 Subject: [PATCH 16/33] Expr.Strings: upd excapeCodes --- src/Nix/Expr/Strings.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index a80f9855..8168e31c 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -110,7 +110,7 @@ stripIndent xs = escapeCodes :: [(Char, Char)] escapeCodes = - [('\n', 'n'), ('\r', 'r'), ('\t', 't'), ('\\', '\\'), ('$', '$'), ('"', '"')] + [('\\', '\\'), ('$', '$'), ('"', '"'), ('\n', 'n'), ('\r', 'r'), ('\t', 't')] fromEscapeCode :: Char -> Maybe Char fromEscapeCode = (`lookup` (swap <$> escapeCodes)) From 45b63e706fc9e9cfcdb3d216e04e0730348646fc Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 13:44:52 +0200 Subject: [PATCH 17/33] Expr.Strings: add escapeMap --- src/Nix/Expr/Strings.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index 8168e31c..5e3aca9c 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -114,6 +114,8 @@ escapeCodes = fromEscapeCode :: Char -> Maybe Char fromEscapeCode = (`lookup` (swap <$> escapeCodes)) +escapeMap :: [(Text, Text)] +escapeMap = [("\\", "\\\\"), ("${", "\\${"), ("\"", "\\\""), ("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t")] toEscapeCode :: Char -> Maybe Char toEscapeCode = (`lookup` escapeCodes) From 5c90a8fb23462549dbfdefb9ef7e6cf003dcf3e8 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 13:46:19 +0200 Subject: [PATCH 18/33] Pretty.escapeDoubleQuoteString -> Expr.Strings.escapeString This can be optimized further using `text-replace`. --- src/Nix/Expr/Strings.hs | 2 ++ src/Nix/Pretty.hs | 20 ++------------------ 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index 5e3aca9c..4c636a4d 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -119,3 +119,5 @@ escapeMap = [("\\", "\\\\"), ("${", "\\${"), ("\"", "\\\""), ("\n", "\\n"), ("\r toEscapeCode :: Char -> Maybe Char toEscapeCode = (`lookup` escapeCodes) +escapeString :: Text -> Text +escapeString = flip (foldl' (flip id)) (fmap (uncurry T.replace) escapeMap) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 0247442e..423b4ebd 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -1,6 +1,5 @@ {-# language CPP #-} {-# language AllowAmbiguousTypes #-} -{-# language ViewPatterns, PatternSynonyms, OverloadedStrings #-} {-# options_ghc -fno-warn-name-shadowing #-} @@ -112,26 +111,11 @@ wrapPath op sub = ("\"${" <> getDoc sub <> "}\"") (wasPath sub) - -infixr 5 :< -pattern (:<) :: Char -> Text -> Text -pattern t :< ts <- (Text.uncons -> Just (t, ts)) - where (:<) = Text.cons - -escapeDoubleQuoteString :: Text -> Text -escapeDoubleQuoteString ('"': escapeDoubleQuoteString xs -escapeDoubleQuoteString ('$':<'{': escapeDoubleQuoteString xs -escapeDoubleQuoteString ('$': escapeDoubleQuoteString xs -escapeDoubleQuoteString a = a - - -- | Handle Output representation of the string escape codes. prettyString :: NString (NixDoc ann) -> Doc ann prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" where - prettyPart (Plain t) = pretty $ escapeDoubleQuoteString t + prettyPart (Plain t) = pretty $ escapeString t prettyPart EscapedNewline = "''\\n" prettyPart (Antiquoted r) = "${" <> getDoc r <> "}" escape '"' = "\\\"" @@ -434,7 +418,7 @@ printNix = iterNValueByDiscardWith thk phi phi :: NValue' t f m Text -> Text phi (NVConstant' a ) = atomText a - phi (NVStr' ns) = "\"" <> escapeDoubleQuoteString (ignoreContext ns) <> "\"" + phi (NVStr' ns) = "\"" <> escapeString (ignoreContext ns) <> "\"" phi (NVList' l ) = "[ " <> unwords l <> " ]" phi (NVSet' _ s) = "{ " <> From 3d7ae8dfb4e4d6ac541ac8a4f80766cf31501ca5 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 18:14:18 +0200 Subject: [PATCH 19/33] Pretty: add antiquote --- src/Nix/Pretty.hs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 423b4ebd..dbe90595 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -4,8 +4,6 @@ {-# options_ghc -fno-warn-name-shadowing #-} --- 2021-11-09: NOTE: Please do not reduce explicit `"${" <> a <> "}"` types of wrappings - as they are readable and so analyzable at eyesight. HNix already has a difficult task of 100% matching the escaping of an unpstream project. - module Nix.Pretty where import Prelude hiding ( toList, group ) @@ -47,6 +45,14 @@ data NixDoc ann = NixDoc -- we can add brackets appropriately } +-- | Represent Nix antiquotes. +-- +-- > +-- > ${ expr } +-- > +antiquote :: NixDoc ann -> Doc ann +antiquote x = "${" <> getDoc x <> "}" + mkNixDoc :: OperatorInfo -> Doc ann -> NixDoc ann mkNixDoc o d = NixDoc { getDoc = d, rootOp = o, wasPath = False } @@ -108,7 +114,7 @@ wrapPath :: OperatorInfo -> NixDoc ann -> Doc ann wrapPath op sub = bool (precedenceWrap op sub) - ("\"${" <> getDoc sub <> "}\"") + ("\"" <> antiquote sub <> "\"") (wasPath sub) -- | Handle Output representation of the string escape codes. @@ -117,13 +123,7 @@ prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" where prettyPart (Plain t) = pretty $ escapeString t prettyPart EscapedNewline = "''\\n" - prettyPart (Antiquoted r) = "${" <> getDoc r <> "}" - escape '"' = "\\\"" - escape x = - maybe - (one x) - (('\\' :) . one) - (toEscapeCode x) + prettyPart (Antiquoted r) = antiquote r prettyString (Indented _ parts) = group $ nest 2 $ vcat ["''", content, "''"] where @@ -142,7 +142,7 @@ prettyString (Indented _ parts) = group $ nest 2 $ vcat prettyPart (Plain t) = pretty . replace "${" "''${" . replace "''" "'''" $ t prettyPart EscapedNewline = "\\n" - prettyPart (Antiquoted r) = "${" <> getDoc r <> "}" + prettyPart (Antiquoted r) = antiquote r prettyVarName :: VarName -> Doc ann prettyVarName = pretty @Text . coerce @@ -201,7 +201,7 @@ prettyKeyName (DynamicKey key) = runAntiquoted (DoubleQuoted $ one $ Plain "\n") prettyString - (\ x -> "${" <> getDoc x <> "}") + antiquote key prettySelector :: NAttrPath (NixDoc ann) -> Doc ann From 225c5ad2e18e7b791443f4cac99e8ee9274f531f Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 18:15:05 +0200 Subject: [PATCH 20/33] Pretty: prettyString: m layout --- src/Nix/Pretty.hs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index dbe90595..2c8cb184 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -119,24 +119,27 @@ wrapPath op sub = -- | Handle Output representation of the string escape codes. prettyString :: NString (NixDoc ann) -> Doc ann -prettyString (DoubleQuoted parts) = "\"" <> foldMap prettyPart parts <> "\"" +prettyString (DoubleQuoted parts) = + "\"" <> foldMap prettyPart parts <> "\"" where prettyPart (Plain t) = pretty $ escapeString t prettyPart EscapedNewline = "''\\n" prettyPart (Antiquoted r) = antiquote r -prettyString (Indented _ parts) = group $ nest 2 $ vcat - ["''", content, "''"] +prettyString (Indented _ parts) = + group $ nest 2 $ vcat ["''", content, "''"] where content = vsep . fmap prettyLine . stripLastIfEmpty . splitLines $ parts stripLastIfEmpty :: [[Antiquoted Text r]] -> [[Antiquoted Text r]] - stripLastIfEmpty = filter flt + stripLastIfEmpty = + filter flt where flt :: [Antiquoted Text r] -> Bool flt [Plain t] | Text.null (strip t) = False flt _ = True prettyLine :: [Antiquoted Text (NixDoc ann)] -> Doc ann - prettyLine = hcat . fmap prettyPart + prettyLine = + hcat . fmap prettyPart where prettyPart :: Antiquoted Text (NixDoc ann) -> Doc ann prettyPart (Plain t) = @@ -311,7 +314,7 @@ exprFNixDoc = \case group $ vsep [ "let" - , indent 2 (vsep (fmap prettyBind binds)) + , indent 2 (vsep $ fmap prettyBind binds) , "in " <> getDoc body ] NIf cond trueBody falseBody -> From 37f4d6ce0cb0f46f3cbeff50f58f4d3ea9a94a04 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 13:59:54 +0200 Subject: [PATCH 21/33] Pretty: add ValueOrigin, prettyProv --- src/Nix/Pretty.hs | 55 +++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 2c8cb184..2fe5282b 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -369,6 +369,35 @@ prettyNValue :: forall t f m ann . MonadDataContext f m => NValue t f m -> Doc ann prettyNValue = prettyNix . valueToExpr +-- | During the output, which can print only representation of value, +-- lazy thunks need to looked into & so - be evaluated (*sic) +-- This type is a simple manual witness "is the thunk gets shown". +data ValueOrigin = WasThunk | Value + deriving Eq + +prettyProv + :: forall t f m ann + . ( HasCitations m (NValue t f m) t + , HasCitations1 m (NValue t f m) f + , MonadThunk t m (NValue t f m) + , MonadDataContext f m + ) + => ValueOrigin -- ^ Was thunk? + -> NValue t f m + -> Doc ann +prettyProv wasThunk v = + list + id + (\ ps pv -> + fillSep + [ pv + , indent 2 $ + "(" <> ("thunk " `whenTrue` (wasThunk == WasThunk) <> "from: " <> fold (prettyExtractFromProvenance ps)) <> ")" + ] + ) + (citations @m @(NValue t f m) v) + (prettyNValue v) + prettyNValueProv :: forall t f m ann . ( HasCitations m (NValue t f m) t @@ -378,19 +407,8 @@ prettyNValueProv ) => NValue t f m -> Doc ann -prettyNValueProv v = - list - prettyNVal - (\ ps -> - fillSep - [ prettyNVal - , indent 2 $ - "(" <> fold (one "from: " <> prettyExtractFromProvenance ps) <> ")" - ] - ) - (citations @m @(NValue t f m) v) - where - prettyNVal = prettyNValue v +prettyNValueProv = + prettyProv Value prettyNThunk :: forall t f m ann @@ -402,16 +420,7 @@ prettyNThunk => t -> m (Doc ann) prettyNThunk t = - do - let ps = citations @m @(NValue t f m) @t t - v' <- prettyNValue <$> dethunk t - pure $ - fillSep - [ v' - , indent 2 $ - "(" <> fold (one "thunk from: " <> prettyExtractFromProvenance ps) <> ")" - ] - + prettyProv WasThunk <$> dethunk t -- | This function is used only by the testing code. printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text From f7543c7e896010eaea02e50ed401dbd025f2ab11 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 14:26:48 +0200 Subject: [PATCH 22/33] Expr.Types: m lint --- src/Nix/Expr/Types.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nix/Expr/Types.hs b/src/Nix/Expr/Types.hs index f87dbe3b..e3a5795b 100644 --- a/src/Nix/Expr/Types.hs +++ b/src/Nix/Expr/Types.hs @@ -776,9 +776,9 @@ getFreeVars e = (NAbs (ParamSet varname _ pset) expr) -> Set.difference -- Include all free variables from the expression and the default arguments - (getFreeVars expr <> (Set.unions $ getFreeVars <$> mapMaybe snd pset)) + (getFreeVars expr <> Set.unions (getFreeVars <$> mapMaybe snd pset)) -- But remove the argument name if existing, and all arguments in the parameter set - ((one `whenJust` varname) <> (Set.fromList $ fst <$> pset)) + ((one `whenJust` varname) <> Set.fromList (fst <$> pset)) (NLet bindings expr ) -> Set.difference (getFreeVars expr <> bindFreeVars bindings) From 49a185a5fb5ca17e159ffdfacda0dcff0983741b Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 14:27:21 +0200 Subject: [PATCH 23/33] Pretty: use `sep` for `[Doc]` --- src/Nix/Pretty.hs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 2fe5282b..247f73bd 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -195,11 +195,9 @@ prettyKeyName (StaticKey key) = id dquotes (HashSet.member key reservedNames) - varName + (prettyVarName key) ) (not $ Text.null $ coerce key) - where - varName = prettyVarName key prettyKeyName (DynamicKey key) = runAntiquoted (DoubleQuoted $ one $ Plain "\n") @@ -240,9 +238,10 @@ prettyOriginExpr = getDoc . go prettyExtractFromProvenance :: forall t f m ann . HasCitations1 m (NValue t f m) f - => [Provenance m (NValue t f m)] -> [Doc ann] + => [Provenance m (NValue t f m)] -> Doc ann prettyExtractFromProvenance = - fmap (prettyOriginExpr . getOriginExpr) + sep . + fmap (prettyOriginExpr . getOriginExpr) exprFNixDoc :: forall ann . NExprF (NixDoc ann) -> NixDoc ann exprFNixDoc = \case @@ -321,15 +320,15 @@ exprFNixDoc = \case leastPrecedence $ group $ nest 2 $ - sep $ - ifThenElse getDoc + ifThenElse getDoc where - ifThenElse :: (NixDoc ann -> Doc ann) -> [Doc ann] + ifThenElse :: (NixDoc ann -> Doc ann) -> Doc ann ifThenElse wp = - [ "if " <> wp cond - , align ("then " <> wp trueBody) - , align ("else " <> wp falseBody) - ] + sep + [ "if " <> wp cond + , align ("then " <> wp trueBody) + , align ("else " <> wp falseBody) + ] NWith scope body -> prettyAddScope "with " scope body NAssert cond body -> @@ -392,7 +391,7 @@ prettyProv wasThunk v = fillSep [ pv , indent 2 $ - "(" <> ("thunk " `whenTrue` (wasThunk == WasThunk) <> "from: " <> fold (prettyExtractFromProvenance ps)) <> ")" + "(" <> ("thunk " `whenTrue` (wasThunk == WasThunk) <> "from: " <> prettyExtractFromProvenance ps) <> ")" ] ) (citations @m @(NValue t f m) v) From d684e3362764a2b6b89ca8f6a34f8f6639ab7f5a Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 14:31:39 +0200 Subject: [PATCH 24/33] Expr.Strings: m org --- src/Nix/Expr/Strings.hs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index 4c636a4d..a027a613 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -114,10 +114,12 @@ escapeCodes = fromEscapeCode :: Char -> Maybe Char fromEscapeCode = (`lookup` (swap <$> escapeCodes)) -escapeMap :: [(Text, Text)] -escapeMap = [("\\", "\\\\"), ("${", "\\${"), ("\"", "\\\""), ("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t")] toEscapeCode :: Char -> Maybe Char toEscapeCode = (`lookup` escapeCodes) + +escapeMap :: [(Text, Text)] +escapeMap = [("\\", "\\\\"), ("${", "\\${"), ("\"", "\\\""), ("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t")] + escapeString :: Text -> Text escapeString = flip (foldl' (flip id)) (fmap (uncurry T.replace) escapeMap) From 417b511d3a03efd0f3b5b6eb4775aff7e16ef1d4 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 14:56:36 +0200 Subject: [PATCH 25/33] Utils: add applyAll; Expr.String: flip escapeMap --- src/Nix/Expr/Strings.hs | 5 +++-- src/Nix/Utils.hs | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index a027a613..59dec6d9 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -119,7 +119,8 @@ toEscapeCode :: Char -> Maybe Char toEscapeCode = (`lookup` escapeCodes) escapeMap :: [(Text, Text)] -escapeMap = [("\\", "\\\\"), ("${", "\\${"), ("\"", "\\\""), ("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t")] +escapeMap = + [("\n", "\\n"), ("\r", "\\r"), ("\t", "\\t"), ("\"", "\\\""), ("${", "\\${"), ("\\", "\\\\")] escapeString :: Text -> Text -escapeString = flip (foldl' (flip id)) (fmap (uncurry T.replace) escapeMap) +escapeString = applyAll (fmap (uncurry T.replace) escapeMap) diff --git a/src/Nix/Utils.hs b/src/Nix/Utils.hs index fb4ea466..63d9f721 100644 --- a/src/Nix/Utils.hs +++ b/src/Nix/Utils.hs @@ -13,6 +13,7 @@ module Nix.Utils , mapPair , iterateN , nestM + , applyAll , traverse2 , lifted @@ -153,6 +154,10 @@ nestM n f x = foldM (const . f) x $ replicate @() n mempty -- fuses. But also, can it be fix join? {-# inline nestM #-} +-- | In `foldr` order apply functions. +applyAll :: Foldable t => t (a -> a) -> a -> a +applyAll = flip (foldr id) + traverse2 :: ( Applicative m , Applicative n From 31a67d133ce27fb0db41c86fa016291055a39f1d Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 14:57:29 +0200 Subject: [PATCH 26/33] Expr.Strings: flip escapeCodes --- src/Nix/Expr/Strings.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs index 59dec6d9..d034ab5c 100644 --- a/src/Nix/Expr/Strings.hs +++ b/src/Nix/Expr/Strings.hs @@ -110,7 +110,7 @@ stripIndent xs = escapeCodes :: [(Char, Char)] escapeCodes = - [('\\', '\\'), ('$', '$'), ('"', '"'), ('\n', 'n'), ('\r', 'r'), ('\t', 't')] + [('\n', 'n'), ('\r', 'r'), ('\t', 't'), ('"', '"'), ('$', '$'), ('\\', '\\')] fromEscapeCode :: Char -> Maybe Char fromEscapeCode = (`lookup` (swap <$> escapeCodes)) From 03d7bf064d73e2e098caacf72c1d6f59366bbca7 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 16:25:21 +0200 Subject: [PATCH 27/33] Normal: normalizeValueF: m refactor --- src/Nix/Normal.hs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Nix/Normal.hs b/src/Nix/Normal.hs index cf32214d..00fd7064 100644 --- a/src/Nix/Normal.hs +++ b/src/Nix/Normal.hs @@ -100,7 +100,9 @@ normalizeValueF f = run . iterNValueM run (flip go) (fmap Free . sequenceNValue' (do i <- ask when (i > 2000) $ fail "Exceeded maximum normalization depth of 2000 levels" - lifted (lifted $ f t) $ local succ . k + (lifted . lifted) + (f t) + (local succ . k) ) (pure $ pure t) b From ae700e5d2626b4c32291153855c19f61917937d9 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 15:41:48 +0200 Subject: [PATCH 28/33] Pretty: use dquotes --- src/Nix/Pretty.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 247f73bd..c7aa40ef 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -114,13 +114,13 @@ wrapPath :: OperatorInfo -> NixDoc ann -> Doc ann wrapPath op sub = bool (precedenceWrap op sub) - ("\"" <> antiquote sub <> "\"") + (dquotes $ antiquote sub) (wasPath sub) -- | Handle Output representation of the string escape codes. prettyString :: NString (NixDoc ann) -> Doc ann prettyString (DoubleQuoted parts) = - "\"" <> foldMap prettyPart parts <> "\"" + dquotes $ foldMap prettyPart parts where prettyPart (Plain t) = pretty $ escapeString t prettyPart EscapedNewline = "''\\n" From 8e710dd0d68955fc6561ac9ca374bce8801e7a5e Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 16:24:27 +0200 Subject: [PATCH 29/33] Main: main': m layout --- main/Main.hs | 28 ++++++++++++++-------------- src/Nix/Pretty.hs | 3 ++- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/main/Main.hs b/main/Main.hs index 378fa468..e599437e 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -152,15 +152,15 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl | isEvaluate = if | isTrace -> evaluateExprWith nixTracingEvalExprLoc expr - | Just path <- getReduce -> evaluateExprWith (reduction path . coerce) expr - | null getArg || null getArgstr -> evaluateExprWith nixEvalExprLoc expr + | Just path <- getReduce -> evaluateExprWith (reduction path . coerce) expr + | null getArg || null getArgstr -> evaluateExprWith nixEvalExprLoc expr | otherwise -> processResult printer <=< nixEvalExprLoc (coerce mpath) $ expr | isXml = fail "Rendering expression trees to XML is not yet implemented" | isJson = fail "Rendering expression trees to JSON is not implemented" - | getVerbosity >= DebugInfo = liftIO . putStr . ppShow . stripAnnotation $ expr - | isCache , Just path <- mpath = liftIO . writeCache (replaceExtension path "nixc") $ expr - | isParseOnly = void . liftIO . Exception.evaluate . force $ expr - | otherwise = + | getVerbosity >= DebugInfo = liftIO . putStr . ppShow . stripAnnotation $ expr + | isCache , Just path <- mpath = liftIO . writeCache (replaceExtension path "nixc") $ expr + | isParseOnly = void . liftIO . Exception.evaluate . force $ expr + | otherwise = liftIO . renderIO stdout @@ -179,16 +179,16 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl | otherwise = printer' where printer' - | isXml = fun (ignoreContext . toXML) normalForm + | isXml = fun (ignoreContext . toXML) normalForm -- 2021-05-27: NOTE: With naive fix of the #941 -- This is overall a naive printer implementation, as options should interact/respect one another. -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI), -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys. - | isJson = fun (ignoreContext . mempty . toJSONNixString) normalForm - | isStrict = fun (show . prettyNValue) normalForm - | isValues = fun (show . prettyNValueProv) removeEffects - | otherwise = fun (show . prettyNValue) removeEffects + | isJson = fun (ignoreContext . mempty . toJSONNixString) normalForm + | isStrict = fun (show . prettyNValue) normalForm + | isValues = fun (show . prettyNValueProv) removeEffects + | otherwise = fun (show . prettyNValue) removeEffects where fun :: (b -> Text) @@ -238,9 +238,9 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl (forceEntry path nv) (descend && deferred - (const False) - (const True) - val + (const False) + (const True) + val ) ) (pure . pure . Free) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index c7aa40ef..ae4046a6 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -89,7 +89,8 @@ hasAttrOp = getSpecialOperator NHasAttrOp -- | Determine if to return doc wraped into parens, -- according the given operator. precedenceWrap :: OperatorInfo -> NixDoc ann -> Doc ann -precedenceWrap op sub = maybeWrap (getDoc sub) +precedenceWrap op sub = + maybeWrap (getDoc sub) where maybeWrap :: Doc ann -> Doc ann maybeWrap = From 991642131fc3f1e1b7aa3b6692b9449a0843998c Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 17:20:59 +0200 Subject: [PATCH 30/33] Main: main': printer: m org --- main/Main.hs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/main/Main.hs b/main/Main.hs index e599437e..e69d2c8e 100644 --- a/main/Main.hs +++ b/main/Main.hs @@ -178,24 +178,24 @@ main' opts@Options{..} = runWithBasicEffectsIO opts execContentsFilesOrRepl | isFinder = findAttrs <=< fromValue @(AttrSet StdVal) | otherwise = printer' where + -- 2021-05-27: NOTE: With naive fix of the #941 + -- This is overall a naive printer implementation, as options should interact/respect one another. + -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which + -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI), + -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys. printer' - | isXml = fun (ignoreContext . toXML) normalForm - -- 2021-05-27: NOTE: With naive fix of the #941 - -- This is overall a naive printer implementation, as options should interact/respect one another. - -- A nice question: "Should respect one another to what degree?": Go full combinator way, for which - -- old Nix CLI is nototrious for (and that would mean to reimplement the old Nix CLI), - -- OR: https://github.com/haskell-nix/hnix/issues/172 and have some sane standart/default behaviour for (most) keys. - | isJson = fun (ignoreContext . mempty . toJSONNixString) normalForm - | isStrict = fun (show . prettyNValue) normalForm - | isValues = fun (show . prettyNValueProv) removeEffects - | otherwise = fun (show . prettyNValue) removeEffects + | isXml = out (ignoreContext . toXML) normalForm + | isJson = out (ignoreContext . mempty . toJSONNixString) normalForm + | isStrict = out (show . prettyNValue) normalForm + | isValues = out (show . prettyNValueProv) removeEffects + | otherwise = out (show . prettyNValue) removeEffects where - fun + out :: (b -> Text) -> (a -> StandardIO b) -> a -> StdIO - fun g f = liftIO . Text.putStrLn . g <=< f + out transform val = liftIO . Text.putStrLn . transform <=< val findAttrs :: AttrSet StdVal From e6a4b88a1d5ead1c121cfd7114526207aba3d67b Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 17:33:40 +0200 Subject: [PATCH 31/33] Pretty: prettyParams: refactor --- src/Nix/Pretty.hs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index ae4046a6..0b2547c3 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -155,7 +155,7 @@ prettyParams :: Params (NixDoc ann) -> Doc ann prettyParams (Param n ) = prettyVarName n prettyParams (ParamSet mname variadic pset) = prettyParamSet variadic pset <> - toDoc `whenJust` mname + toDoc `whenJust` mname where toDoc :: VarName -> Doc ann toDoc (coerce -> name) = @@ -166,18 +166,12 @@ prettyParamSet variadic args = encloseSep "{ " (align " }") - sep + (align ", ") (fmap prettySetArg args <> one "..." `whenTrue` (variadic == Variadic)) where prettySetArg :: (VarName, Maybe (NixDoc ann)) -> Doc ann prettySetArg (n, maybeDef) = - maybe - varName - (\x -> varName <> " ? " <> getDoc x) - maybeDef - where - varName = prettyVarName n - sep = align ", " + (prettyVarName n <>) $ ((" ? " <>) . getDoc) `whenJust` maybeDef prettyBind :: Binding (NixDoc ann) -> Doc ann prettyBind (NamedVar n v _p) = From c14022269ebb5be8894f0908d224d8cb493a298b Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 18:25:32 +0200 Subject: [PATCH 32/33] Pretty: m clean-up --- src/Nix/Pretty.hs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 0b2547c3..207a2391 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -297,11 +297,11 @@ exprFNixDoc = \case "./" -> "./." "../" -> "../." ".." -> "../." - _txt -> + path -> bool - ("./" <> _txt) - _txt - (any (`isPrefixOf` coerce _txt) ["/", "~/", "./", "../"]) + ("./" <> path) + path + (any (`isPrefixOf` coerce path) ["/", "~/", "./", "../"]) NSym name -> simpleExpr $ prettyVarName name NLet binds body -> leastPrecedence $ @@ -418,10 +418,9 @@ prettyNThunk t = -- | This function is used only by the testing code. printNix :: forall t f m . MonadDataContext f m => NValue t f m -> Text -printNix = iterNValueByDiscardWith thk phi +printNix = + iterNValueByDiscardWith thunkStubText phi where - thk = thunkStubText - phi :: NValue' t f m Text -> Text phi (NVConstant' a ) = atomText a phi (NVStr' ns) = "\"" <> escapeString (ignoreContext ns) <> "\"" From 607e00f07a385decdb4f43a56dace7833a192018 Mon Sep 17 00:00:00 2001 From: Anton-Latukha Date: Tue, 11 Jan 2022 18:32:13 +0200 Subject: [PATCH 33/33] Pretty: precedenceWrap: m refactor --- src/Nix/Pretty.hs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Nix/Pretty.hs b/src/Nix/Pretty.hs index 207a2391..2a18ca37 100644 --- a/src/Nix/Pretty.hs +++ b/src/Nix/Pretty.hs @@ -89,8 +89,8 @@ hasAttrOp = getSpecialOperator NHasAttrOp -- | Determine if to return doc wraped into parens, -- according the given operator. precedenceWrap :: OperatorInfo -> NixDoc ann -> Doc ann -precedenceWrap op sub = - maybeWrap (getDoc sub) +precedenceWrap op subExpr = + maybeWrap $ getDoc subExpr where maybeWrap :: Doc ann -> Doc ann maybeWrap = @@ -98,16 +98,17 @@ precedenceWrap op sub = parens id needsParens + where + needsParens :: Bool + needsParens = + precedence root < precedence op + || ( precedence root == precedence op + && associativity root == associativity op + && associativity op /= NAssocNone + ) - root = rootOp sub + root = rootOp subExpr - needsParens :: Bool - needsParens = - precedence root < precedence op - || (precedence root == precedence op - && associativity root == associativity op - && associativity op /= NAssocNone - ) -- Used in the selector case to print a path in a selector as -- "${./abc}"