* Forbid invalid codepoints
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/640
* Don't validate code points outside of escape sequences
... as suggested by @sjakobi
It's not necessary (since the `text` package forbids invalid UTF8) and
slows down performance as verified by the `dhall-parser` comment parsing
benchmarks
* Restore `nonCharacter` parsing test
Previously, ill-typed expressions like this one got into normalization:
toMap {=} : <>.x
Also:
* Tweak Expr's Arbitrary instance:
- Boring nullary constructors don't need to be so frequent.
- Large NaturalLits can cause normalization to OOM, which we don't
want when running the testsuite.
* Add property test to check that all well-typed expressions can be
normalized.
* Implement dhall.freezeImport and dhall.freezeAllImports
* Remove old (broken) test suite
* Rename `relativePosition` to `subtractPosition`
as suggested by @Gabriel439
* Add doctest for `subtractPosition`
as suggested by @Gabriel439
* Simplify getImportHashPosition
As spotted by @Gabriel439
* Use `forM` instead of `mapM` for prettier code
As suggested by @Gabriel439
* Check normalizeWithM for consistency with normalize
* Implements constant folding of Natural/fold applications normalizeWithM.
* Changes the Arbitrary Var instance to generate only non-negative indices.
Otherwise failures like this one would pop up:
normalizeWithM should be consistent with normalize: FAIL (8.51s)
*** Failed! Falsified (after 318133 tests and 6 shrinks):
Let (Binding {variable = "", annotation = Nothing, value = List} :| []) (Var (V "" (-1)))
Var (V "" (-1)) /= Var (V "" (-2))
Use --quickcheck-replay=180244 to reproduce.
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1114.
* QuickCheck tests: Specialize the 'natural' Gen to Naturals
Previously it could produce about any number, not just non-negative
ones.
* Add `--file` option to `dhall-json` executables
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1096
* s/JSON/expression/
... as caught by @sjakobi
Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
* s/expression/YAML expression/
... as caught by @sjakobi
Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
* Change the program descriptions for `{json,yaml}-to-dhall`
... as suggested by @sjakobi
To be more precise (citing the haddocks):
Given a well-typed expression e, (isNormalized e) is equivalent to
(e == normalize e).
Given an ill-typed expression, isNormalized may return True or False.
An even closer correspondence between isNormalized and 'normalize' is
currently tricky to achieve as 'normalize' returns errors only for some
ill-typed expressions. Once 'normalize' is more principled in this
regard, isNormalized could be changed to return a (Maybe Bool).
This re-enables a property test checking this consistency. Since
'normalize' returns errors for some ill-typed expressions, we
catch have to catch these, which requires an NFData for Expr.
* Fix misleading comment
* Add `Chained` type to capture fully chained imports
Until now we used `Import` two mean two different things:
- The syntactic construct; e.g. `./a.dhall` corresponds to the following
AST:
```
Embed
(Import
(ImportHashed Nothing (Local Here (Directory ["."]) "a.dhall"))
Code)
```
- The physical location the import is pointing to, computed by
'chaining' the syntactical import with the the 'physical' parent import.
For example the syntactic import `./a.dhall` might actually refer to the
remote file `http://host/directory/a.dhall`.
This commit adds a `Chained` newtype on top of `Import` to make this
distinction explicit at type level.
* Use `HTTPHeaders` alias for binary headers
I claim that `HTTPHeaders` is more readable and informative than the
unfolded type `(CI ByteString, ByteString)`.
* Typecheck and normalise http headers earlier
Previously we would typecheck and normalise http headers in
`exprFromImport`, i.e. while loading the import. This commit adds the
invariant that any headers in 'Chained' imports are already typechecked
and normalised, and moves this step into `loadWith` accordingly.
This causes a subtle difference in behaviour when importing remote files
with headers `as Location`: previously, nonsensical expressions like
`http://a using 0 0 as Location` were valid, while they would now cause
a type error.
* Fix dhall-lsp-server
* Fix Dhall.Import API regarding `Chained` imports
Do not expose the `Chained` constructor; we don't want external code
breaking our invariants! Also further clarifies the comment describing
the `Chained` type.
* Fix dhall-lsp-server
Since we are no longer able to construct `Chained` imports directly we
need to export a few additional helper functions from Dhall.Import.
Furthermore, since VSCode (and presumably the other editors out there
implementing the LSP protocol) does not support opening remote files
anyway we can get rid of some complications by dropping support for
remote files entirely on the back-end.
* Generalise decodeExpression, fixes TODO
* Fix tests
* Fix benchmarks
* Remove Travis cache for `~/.local/bin`
* Fix copy-pasted comment
Thanks to @Gabriel439 for spotting this!
* Add clarifying comment to `toHeaders`
It is not the case that
canonicalize (a <> b) = canonicalize a <> canonicalize b.
For example
canonicalize (Directory ["asd"] <> Directory [".."])
= Directory [],
but
canonicalize (Directory ["asd"]) <> canonicalize (Directory [".."])
= Directory ["..", "asd"].
The law we want instead is:
canonicalize (a <> b)
= canonicalize (canonicalize a <> canonicalize b)
* Expose `localToPath` in Dhall.Import
Also modifies `localToPath` to return a relative path if the input was
relative, rather than resolving relative paths by appending the current
directory.
* Turn imports into clickable links
This implements a handler for 'Document Link' requests. As a result,
imports are now clickable!
* Recover original behaviour
The main improvements are:
* Add one-line summary of what Dhall is
This is based on user feedback that some people could not tell what
Dhall was based on the home page
* Replace "Tough on messes" section with "Integration friendly" section
This is based on user feedback that the nethack example wasn't working
for them and also because of a large number of questions in online
discussions about how to integrate Dhall
* Fix tutorial examples to put public/private keys under `~/.ssh`
* Link to newly-added Wiki pages
* Move "Dot" import graph generation to Dhall.Main
Previously `Dhall.Import` would generate the import graph in "dot"
format while resolving imports. This change simplifies `Dhall.Import` to
only keep track of the adjacency list representing the import graph,
moving the logic for generating "dot" files to Dhall.Main.
This change will allow us to implement proper cache invalidation for
`dhall-lsp-server`.
* Correctly invalidate transitive dependencies
Fixes dhall-lsp-server`s caching behaviour to correctly invalidate
cached imports that (possibly indirectly) depend on the changed file.
Example:
Suppose we have the following three files:
{- In A.dhall -} 2 : ./B.dhall
{- In B.dhall -} ./C.dhall
{- In C.dhall -} Natural
Previously, changing C.dhall to `Text` would not cause `A.dhall` to stop
type-checking, since the old version of `B.dhall` (which evaluated to
`Natural`) would still have been in the cache. This change fixes that
behaviour.
* Make edges of import graph self-documenting
As suggested by @Gabriel439
* Don't cache expressions manually
After computing the diagnostics for a given file we added its normal
form to the cache, but forgot to add its dependencies to the dependency
graph. This bug points out that keeping the import graph consistent
manually is probably not a good idea. With this commit we never mess
with the import cache manually; this means that files are only cached
once they are depended upon by some other file, potentially causing us
to duplicate work (but no more than once).
* Fix left-overs from previous commit
* Handle empty alternatives when converting from JSON
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1074
`dhall-to-{json,yaml}` treat empty alternatives as strings of the
same name, but `{json,yaml}-to-dhall` were missing the corresponding
logic to decode strings to empty alternatives, which this change
fixes.
This also ensures that the conversion logic contains no more
`undefined`s, by making the union conversion branch total.
* Clarify successful cases for union handling
Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
* Add missing trailing newline
... as caught by @sjakobi
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1082
All of the successes are due to accepting expressions that would not
have been produced by a compliant encoder, such as:
* Expressions that use a variable name of `_` that could have been
encoded more compactly
* An expression tagged as a `Natural` number storing a negative number
* An expression encoding a function appled to 0 arguments
* Fix `dhall-json`'s support for preserving alternative names
... as caught by @sjakobi in the course of #1077
The code has to be updated to reflect the new normal forms for
union literals
* Add tests
... as suggested by @sjakobi
* Improve type-on-hover behaviour over binders
Dhall's parser does not generate `Src` annotations for the names in
binders, which means that it's not quite as straight-forward to check
whether the user meant to hover over it and see its type as one would
hope. As a result, the current "naive" implementation sometimes behaves
slightly unintuitively and returns the type of the entire expression,
rather than the type of the bound variable. E.g.
let x = 2 in "text"
~
would result in the type `Text` being displayed, rather than `Natural`
as one would expect. Since the language server also marks the expression
whose type is being displayed, the behaviour isn't quite that bad in
practice (we aren't falsely led to believe that `x` has type `Text`).
This change recovers the `Src` information describing the bound variable
names and handles those cases in a way that should be more in line with
the expectations of the user.
* Fix exprAt not handling multi-lets correctly
* Fix merge left-overs
* Normalize types before displaying them to the user
Previously, the type displayed when hovering over the arrow in a lambda
(or forall) binder would not always be normal, e.g.
\(n : {Left = Natural, Right = Natural}.Left) -> n + n
~
would result in
forall (n : {Left = Natural, Right = Natural}.Left) -> Natural
being displayed.
The (expected) normal type would be:
forall (n : Natural) -> Natural
This fix normalises types before displaying them to the user (fixes both
the type-on-hover and annotate-let behaviour).
* Move normalisation from typeAt' to typeAt
This way we only have to worry about it one place, rather than in each
clause of `typeAt'`.