Skip to content

Commit 711ee2b

Browse files
Gabriella439sjakobi
authored andcommitted
Add dhall lint support for fixing parent-anchored paths (#1531)
* Add `dhall lint` support for fixing parent-anchored paths * Fix haddocks to be consistent ... as caught by @sjakobi Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
1 parent 5580981 commit 711ee2b

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

dhall/src/Dhall/Lint.hs

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
1-
{-# LANGUAGE RecordWildCards #-}
1+
{-# LANGUAGE NamedFieldPuns #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE PatternGuards #-}
4+
{-# LANGUAGE RecordWildCards #-}
25

36
-- | This module contains the implementation of the @dhall lint@ command
47

58
module Dhall.Lint
69
( -- * Lint
710
lint
811
, removeUnusedBindings
12+
, fixAssert
13+
, fixParentPath
914
) where
1015

1116
import Control.Applicative ((<|>))
12-
import Dhall.Syntax (Binding(..), Expr(..), Import, Var(..), subExpressions)
1317

18+
import Dhall.Syntax
19+
( Binding(..)
20+
, Directory(..)
21+
, Expr(..)
22+
, File(..)
23+
, FilePrefix(..)
24+
, Import(..)
25+
, ImportHashed(..)
26+
, ImportType(..)
27+
, Var(..)
28+
, subExpressions
29+
)
30+
31+
import qualified Data.List.NonEmpty as NonEmpty
1432
import qualified Dhall.Core
1533
import qualified Dhall.Optics
1634
import qualified Lens.Family
@@ -22,12 +40,13 @@ import qualified Lens.Family
2240
* removes unused @let@ bindings with 'removeUnusedBindings'.
2341
* fixes @let a = x ≡ y@ to be @let a = assert : x ≡ y@
2442
* consolidates nested @let@ bindings to use a multiple-@let@ binding with 'removeLetInLet'
43+
* fixes paths of the form @.\/..\/foo@ to @..\/foo@
2544
-}
2645
lint :: Expr s Import -> Expr t Import
2746
lint =
2847
Dhall.Optics.rewriteOf
2948
subExpressions
30-
(\e -> fixAsserts e <|> removeUnusedBindings e)
49+
(\e -> fixAssert e <|> removeUnusedBindings e <|> fixParentPath e)
3150
. removeLetInLet
3251

3352
-- | Remove unused `Let` bindings.
@@ -40,15 +59,42 @@ removeUnusedBindings (Let (Binding _ a _ _ _ _) d)
4059
Just (Dhall.Core.shift (-1) (V a 0) d)
4160
removeUnusedBindings _ = Nothing
4261

43-
-- Fix `Let` bindings that the user probably meant to be `assert`s
44-
fixAsserts :: Expr s a -> Maybe (Expr s a)
45-
fixAsserts (Let (Binding { value = Equivalent x y, ..}) body) =
62+
-- | Fix `Let` bindings that the user probably meant to be `assert`s
63+
fixAssert :: Expr s a -> Maybe (Expr s a)
64+
fixAssert (Let (Binding { value = Equivalent x y, ..}) body) =
4665
Just (Let (Binding { value = Assert (Equivalent x y), .. }) body)
47-
fixAsserts (Let binding (Equivalent x y)) =
66+
fixAssert (Let binding (Equivalent x y)) =
4867
Just (Let binding (Assert (Equivalent x y)))
49-
fixAsserts _ =
68+
fixAssert _ =
5069
Nothing
5170

71+
-- | This transforms @.\/..\/foo@ into @..\/foo@
72+
fixParentPath :: Expr s Import -> Maybe (Expr s Import)
73+
fixParentPath (Embed oldImport) = do
74+
let Import{..} = oldImport
75+
76+
let ImportHashed{..} = importHashed
77+
78+
case importType of
79+
Local Here File{ directory = Directory { components }, .. }
80+
| Just nonEmpty <- NonEmpty.nonEmpty components
81+
, NonEmpty.last nonEmpty == ".." -> do
82+
let newDirectory =
83+
Directory { components = NonEmpty.init nonEmpty }
84+
85+
let newImportType =
86+
Local Parent File{ directory = newDirectory, .. }
87+
88+
let newImportHashed =
89+
ImportHashed { importType = newImportType, .. }
90+
91+
let newImport = Import { importHashed = newImportHashed, .. }
92+
93+
Just (Embed newImport)
94+
_ ->
95+
Nothing
96+
fixParentPath _ = Nothing
97+
5298
isOrContainsAssert :: Expr s a -> Bool
5399
isOrContainsAssert (Assert _) = True
54100
isOrContainsAssert e = Lens.Family.anyOf subExpressions isOrContainsAssert e

0 commit comments

Comments
 (0)