Commit Graph

51 Commits

Author SHA1 Message Date
Javier Neira 640913f8d2
Fix default cache handling in windows (#1272)
* Ignore all stack*.yaml.lock files
* Use `$LOCALAPPDATA` environment variable in windows
2019-09-16 09:51:00 +02:00
Simon Jakobi fddce0b8cf Adjust type-checking test setup (#1275)
… in response to https://github.com/dhall-lang/dhall-lang/pull/723.
2019-09-15 02:56:16 +00:00
Patrick Mylund Nielsen c29b128339
Improve GHCJS support (cabal build, SHA256 hashing) (#1311) 2019-09-13 11:42:55 -04:00
Simon Jakobi 37f819c8bb
Add --no-cache flag (#1290)
When enabled, we handle protected imports as if the semantic cache was
empty:
  * Protected imports are resolved again, downloaded or read from
    the filesystem as necessary.
  * Protected imports are β-normalized, not αβ-normalized.
  * Protected imports are checked against their SHA256 hashes,
    failing to resolve if they don't match.

Context:
https://github.com/dhall-lang/dhall-haskell/pull/1275#issuecomment-528847192
2019-09-09 22:37:30 +02:00
quasicomputational a5c77b1db7 `Binding` docs + combinators for 1.26 (#1291)
* Add a haddock to explain the various `Binding` fields.

* Add combinators to make dealing with `Binding` less awkward.

With all of the source information flying around, manually
deconstructing and reconstructing `Binding`s is a pain. These
combinators cover some very common cases.

* Use `bindingExprs` to simplify `subExpressions`.

* Use bindingExprs and chunkExprs to simplify another traversal.
2019-09-08 21:15:18 +00:00
Gabriel Gonzalez 96921f03ab
Fix `dhall format` to preserve `let` comments (#1273)
Related to https://github.com/dhall-lang/dhall-haskell/issues/145

Note that this also refactors `Let` to use `Binding` in order
to avoid having to duplicate `Src`-related fields in two
places.
2019-09-04 23:41:44 -05:00
Simon Jakobi 72fd2ac983
Treat multi-lets as syntactic sugar (#1242)
Closes #1185.

This mostly reverts "Add support for multi-`let` (#675)" /
8a5bfaa3b9.

Also:

* Add fields for Src
  This is useful for to make 'Note's less noisy during debugging:

      first srcText expr
2019-08-31 18:31:24 +02:00
Ollie Charles 4a93c255db Remove Dhall.X and replace with Data.Void (#1172)
* Remove Dhall.X and replace with Data.Void

This commit removes the Dhall.X module and the Dhall.X.X type,
preferring the use of Data.Void.Void. As I'm sure a lot of people are
actually using X, I've added a type-alias type X = Void. However,
pattern matching on X would be a breaking change.

Fixes #1120.

* Restore unsafeCoerce

* Fix regression

* Unused

* Reorganise exports

* Fix dhall-nix

* Another fix

* Fix Dhall.LSP.Backend.Typing

* Fix dhall-bash
2019-08-05 13:00:59 +00:00
Gabriel Gonzalez 7f2f57f975
Add support for dependent types (#1164) 2019-08-03 21:38:01 -07:00
Simon Jakobi 1700fa72d8 Fix import logic with --file for dhall-to-{json,yaml} (#1191)
Fixes #1183.
2019-08-03 11:03:42 +00:00
Ollie Charles 1b683295fc Implement Natural/subtract (#1133)
* Implement Natural/truncatedSubtract

* Restore commented out code

* Add pretty printing for Natural/truncatedSubtract

* Flip the order of the arguments

* truncatedSubtract -> subtract

* Whitespace

* Whitespace

* Whitespace

* Whitespace

* Remove a try

* Fix Core.hs

* Add a case in Arbitrary (Expr s a)

* Fix Dhall.JSON

* lift2 -> lift0

* Update Dhall.Diff

* Add extra reduction rules

* Fix

* Update Core.hs

* Update dhall-lang submodule

* Updated dhall-lang

* Try rolling back the dhall-lang revision

* Correct isNormalized

* Add more isNormalized rules

* Update dhall-nix
2019-08-02 00:12:43 +00:00
Simon Jakobi beb1e7ba6f
Remove old union literal syntax (#1176)
…as standardized in https://github.com/dhall-lang/dhall-lang/pull/573.

Fixes #1175.
2019-07-31 04:44:36 +02:00
Gabriel Gonzalez a81c75fc5b Remove most uses of `StandardVersion` from the API (#1169)
* Remove most uses of `StandardVersion` from the API

We no longer support multiple versions of the standard, except for
supporting old integrity checks, so this change removes all inessential
uses of `StandardVersion` from the API and command-line interface.

* Fix `dhall-lsp-server` build
2019-07-31 01:49:53 +00:00
Gabriel Gonzalez 7a88cdf481 Change `ImportSemantics` to not necessarily be α-normalized (#1162)
The motivation for this change is to avoid α-normalizing all imported
expressions.

For example, before this change you would get the following behavior
beginning with an empty cache

```
$ cat ./example.dhall
λ(a : Type) → a

$ dhall <<< './example.dhall'
λ(_ : Type) → _
```

The reason why is that the current code α-normalizes all imported
expressions, even when returning them fresh.

To fix this, I changed the `ImportSemantics` type to not require that
expressions are α-normalized.  Instead, the α-normalization only
happens at the last minute when interacting with the semantic cache, but
nowhere else.

I figured that this change would also be fine from the perspective of
the semi-semantic cache because false-negatives for this cache are
fine.  In particular, we probably don't mind if we get a cache miss for
the semi-semantic cache if the user renames a variable.

After this change imports are no longer α-normalized, whether loaded
from a hot or cold cache:

```
$ cat ./example.dhall
λ(a : Type) → a

$ dhall <<< './example.dhall'
λ(a : Type) → a

$ dhall <<< './example.dhall'
λ(a : Type) → a
```
2019-07-28 14:30:01 +00:00
Frederik Ramcke fd8683216d Fix tests without `with-http` flag (#1159)
* Allow customization of remote import resolution

Makes the `Status` type more general; previously support for
`Network.HTTP.Client` was hardcoded. In short:

```
data Status = Status
    { _stack :: NonEmpty Chained
    [...]
--  , _manager :: Maybe Dynamic
--  --   importing the same expression twice with different values
++  , _remote :: URL -> StateT Status IO Data.Text.Text
++  -- ^ The remote resolver, fetches the content at the given URL.

    [...]
    }

```

* Simplify and expose `toHeaders`

`toHeaders` will be needed for mock http testing

* Fix compilation without `with-http` flag

* Fix compilation with `with-http` flag

* Fix tests without `with-http` flag

Implements a mock http client that handles requests to:
- `https://raw.githubusercontent.com/dhall-lang/dhall-lang/master/`
- `https://test.dhall-lang.org/Bool/package.dhall`
- `https://httpbin.org/user-agent`

This allows tests involving remote imports to succeed even when compiled
without the `with-http` flag.

* Build `dhall` with HTTP support compiled out in CI

... to prevent regressions from occurring in the future
2019-07-27 02:59:25 +00:00
Frederik Ramcke 5bb84cbd94 Fix compilation without `with-http` flag (#1157)
* Fix compilation without `with-http` flag

* Fix compilation with `with-http` flag
2019-07-27 02:03:47 +00:00
Frederik Ramcke 76a0d4159b Implement semi-semantic caching (#1154)
* Tag ImportSemantics with their semantic hashes

This is in preparation for semi-semantic caching.

* Collect the list of imports during import resolution

The final step needed in preparation for semi-semantic caching!

* Implement semi-semantic caching

This completes the implementation of the "semi-semantic caching"
proposal (issue #1098).

We compute the semi-semantic hash of a dhall import/file/expression as
follows:

- Parse the input;
- compute the semantic hashes of all imports referenced in the AST, i.e.
the hashes of their normal forms;
- compute the syntactic hash of the input (hashing the parsed AST);
- concatenate the syntactic hash of the input with the semantic hashes
of its imports and hash the result.

The "semi-semantic" cache (normal forms, indexed by semi-semantic
hashes) has the following properties:

- For a given input we can quickly find out if it is in the cache: we
only need to parse the input – we don't need to typecheck or normalise
it!
- The cache stays consistent, that is, we don't need to ‘invalidate’ old
cache entries if their dependencies change!

* Simplify semi-semantic hash

As suggested by @Gabriel439.

* Simplify code

We don't actually need to carry the list of imports around when loading.

* Restore `load`
2019-07-26 13:45:18 +00:00
Frederik Ramcke 36379cec2e Fix import alternatives to recover from type errors (#1152)
Previously, `BAD="0 0" dhall <<< "env:BAD ? 0"` resulted in the
following error:
```
↳ env:BAD

Error: Not a function

1│ 0 0

BAD:1:1
```

According to the standard the above expression was supposed to evaluate
successfully to `0`. See #1146 for further discussion.
2019-07-25 18:05:55 -07:00
Frederik Ramcke 4faf25bbbe Load imports recursively (#1128)
* Load imports recursively

This is the big change that enables us to implement 'semi-semantic'
caching.

* Use `throwM` instead of `liftIO . throwIO`

* Fix build with __GHCJS__

* Fix exceptions in Dhall.Import

* Fix dhall-lsp-server

* Revert exception behaviour on typecheck errors

This is one for a separate pull request!

* Make sure loadImportFresh returns alpha-normal expression

As caught by @Gabriel439, `loadImportFresh` violated the invariant that
`ImportSemantics` should be alpha-beta-normal. This fix also means that
we don't have to alpha-normalise again in `loadImportWithSemanticCache`.

* Remove old comment

* Fix regression test for issue 216

Turns out the test was testing the wrong thing, because it was
pretty-printing an import. This worked previously because when importing
uncached expressions we would not alpha-normalise them.

* Restore `dhall freeze` bevhaviour

Newly frozen imports should also be present in the cache.
2019-07-23 16:11:33 +00:00
Simon Jakobi c8a0df3748 Specialize Expr's ToTerm instance to (Expr X a) (#1143)
* This simplifies pattern matching during encoding.
2019-07-21 15:17:41 +00:00
Frederik Ramcke d5d0224bc3 Preparing `Dhall.Import` for "Semi-semantic" caching (#1113)
* 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`
2019-07-17 15:20:48 +00:00
Frederik Ramcke 6534ce85ed Fix incorrect `Canonicalize` law (#1118)
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)
2019-07-17 13:13:40 +00:00
Frederik Ramcke 33ebf7ee71 dhall-lsp-server: Turn imports into clickable links (#1121)
* 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
2019-07-17 08:54:56 +00:00
Mario 8aa2ac3ce9 Implementation of toMap (#1041)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/610
2019-07-15 08:28:29 -07:00
Frederik Ramcke 8ae7b603fe
dhall-lsp-server: Fix cache to correctly invalidate transitive dependencies (#1069)
* 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
2019-07-08 10:55:15 +00:00
Gabriel Gonzalez c116207663 Update to latest `dhall-lang` (#1084)
* Update to latest `dhall-lang`

The main updates are to support the following two changes to the
standard:

* https://github.com/dhall-lang/dhall-lang/pull/604
* https://github.com/dhall-lang/dhall-lang/pull/611

* `s/fields/fails/`

... as caught by @sjakobi

Co-Authored-By: Simon Jakobi <simon.jakobi@gmail.com>
2019-07-07 06:08:58 +00:00
Fabrizio Ferrai 04d82120a4 Implement importing `as Location` (#1019) 2019-06-30 22:00:14 -07:00
Gabriel Gonzalez 154d1c52cf
Remove support for old-style `List`-like `Optional` literals (#1002)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/572
2019-06-13 17:59:49 -07:00
Gabriel Gonzalez e8ac5e3bd0
Add new `--cache` flag to `dhall freeze` (#980)
Part of https://github.com/dhall-lang/dhall-lang/issues/563

This flag freezes imports in the same way as the Prelude by providing a
fallback unprotected import without an integrity check.  The primary use
case for this is caching imports with a graceful fallback, which is why
the flag is named `--cache`
2019-06-01 09:44:01 -07:00
Gabriel Gonzalez 8dc52fa3d2
Add support for improved `using` behavior (#967)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/560
2019-06-01 08:27:26 -07:00
Gabriel Gonzalez 3c08c627e8
Support projection by record type (#958)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/499
2019-05-27 20:54:42 -07:00
Gabriel Gonzalez 21da6f2b7f
Update to latest test suite (#903)
This requires implementing the following changes to the standard:

* https://github.com/dhall-lang/dhall-lang/pull/481
* https://github.com/dhall-lang/dhall-lang/pull/488
* https://github.com/dhall-lang/dhall-lang/pull/489
* https://github.com/dhall-lang/dhall-lang/pull/497
2019-04-25 15:05:02 -07:00
Gabriel Gonzalez 7d31506be4
Automatically discover tests (#897)
This adds a new `Dhall.Test.Util.discover` utility for auto-generating
a `TestTree` from a directory tree.  This simplifies keeping up to date
with changes to the standard test suite.
2019-04-24 13:01:46 -07:00
AndrasKovacs fcca883e00 Add a new environment machine normalizer (#876)
- Dhall.Eval: new evaluator, conversion checker and normalizer.
  There is no standalone alpha normalizer yet.
- There is a new option "new-normalize" for dhall executable, which uses
  the new normalizer.
- Type checker is unchanged.
- new implementation: alphaNormalize, judgmentallyEqual, normalize
- normalizeWith takes a Maybe ReifiedNormalizer argument now, and switches to
  the new evaluator whenever the input normalizer is Nothing
- QuickCheck test for isNormalized removed, because we don't support evaluation
  of ill-typed terms, which the test would require.
2019-04-17 16:41:04 -07:00
Gabriel Gonzalez 2a78ac06b7
Define expression equality as CBOR equality (#866)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/426

This adds two new `ToTerm`/`FromTerm` classes in order to minimize
code disruption.  The main disruption is due to renaming the old
`encode`/`decode` to `encodeExpression`/`decodeExpression`
2019-03-27 18:26:02 -07:00
Gabriel Gonzalez a2ab6a59ec
Add support for empty alternatives (#863)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/438

This also adds `dhall-json` support for empty alternatives

In particular, this translates empty alternatives to strings encoding the alternative name

```haskell
-- ./example.dhall

let Role = < Wizard | Fighter | Rogue >

in  [ Role.Wizard, Role.Fighter ]
```

```
$ dhall-to-json <<< './example.dhall'
["Wizard","Fighter"]
```
2019-03-27 15:29:10 -07:00
Gabriel Gonzalez 4b7bdd458c
Add CORS support (#846)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/411
2019-03-12 18:36:38 -07:00
Gabriel Gonzalez 05d9405d29
Simplify import resolution logic (#833)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/391

This also updates the `loadWith` judgment to more closely match the variable
names used in the standard
2019-03-04 19:11:25 -08:00
Gabriel Gonzalez 36f0e55a5f
Remove the `constructors` keyword (#829)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/385
2019-02-27 21:44:36 -08:00
Gabriel Gonzalez e3dde9dfa7
Implement `Text/show` (#811)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/365
2019-02-12 18:42:48 -08:00
Gabriel Gonzalez 112efa7df7
Fix import source locations (#815)
.. as caught by @Profpatsch in:

https://github.com/dhall-lang/dhall-haskell/pull/812#issuecomment-462134701

Before this change the location was always being reported as `(stdin):1:1`
because the `SourcedException` kept getting modified with a broader
source location in the `Note` branch of `loadWith`.

This was originally done so that alternative imports would show the entire
source span, but it mistakenly just kept bubbling up regardless of whether or
not there were alternative imports.

Instead, this includes an approximate source span for alternative imports.
The source span bounds are correct but the contents just show which imports
were alternated, even if they might have been buried in a larger expression.

For example, if the original expression had been:

```haskell
Some ./x ? None ./y
```

... then the source span for the error message would display just:

```haskell
./x ? ./y
```

... which is probably as good as it will get for now.
2019-02-12 09:04:32 -08:00
Gabriel Gonzalez 98497e44ec
Add source position information for missing imports (#812)
Related to #561

This adds source position information to missing imports

Before:

```
$ dhall <<< './foo'

↳ ./foo

Error: Missing file …/foo
```

After:

```
$ dhall <<< './foo'

↳ ./foo

Error: Missing file …/foo

(stdin):1:1
```
2019-02-08 07:32:00 -08:00
Gabriel Gonzalez 04ec45803d
Remove version tag from encoded expressions (#805)
* Remove version tag from encoded expressions

... as standardized in https://github.com/dhall-lang/dhall-lang/pull/362

This includes backwards compatibility for older encoded expressions
2019-02-03 21:17:41 -08:00
Gabriel Gonzalez 095ee6db61
Don't fail if `$HOME` environment variable is unset (#789)
Fixes https://github.com/dhall-lang/dhall-haskell/issues/788

This removes the dependency on the `directory` library's utility
functions (which require `HOME` to be set)
2019-01-21 08:22:16 -08:00
Gabriel Gonzalez abdd442814
Restore `Parent` constructor for `Local` (#718)
This is essentially a revert of 25d86e8e5d

The primary motivation for this is so that paths beginning with `../`
don't get reformatted to begin `./../`.

The secondary motivation for this is to more closely match the standard.
There are fewer special cases in the logic if there is a dedicated
constructor for the `Parent` case.
2018-11-28 19:30:38 -08:00
Gabriel Gonzalez 653932e112
Simplify import error handling logic (#711)
The first two cases of the `handler₀` function are just special cases
of the last case
2018-11-26 23:36:46 -08:00
Basile Henry c8dc585430
Generate dot graph to visualize import graph (#698)
* Add dotgen as a dependency

Signed-off-by: Basile Henry <bjm.henry@gmail.com>

* Build up dot graph while resolving imports

Signed-off-by: Basile Henry <bjm.henry@gmail.com>

* Add --dot option to resolve in CLI

Signed-off-by: Basile Henry <bjm.henry@gmail.com>

* Handle diamond dependencies in dot graph

* Refactor dot graph generation
2018-11-26 07:24:20 +02:00
Gabriel Gonzalez 99fabea38a
Fix import caching (#702)
This fixes an apparently very old bug in import caching caught by @basile-henry

Before this change the import resolution algorithm was:

1. Retrieving the cache
2. Transitively resolving all imports
3. Setting the new cache to be current import insert into the cache retrieved in
   step 1

The bug is that all of the transitive imports resolved in step 2 added
entries of their own to the cache and those new cache entries were being
clobbered by step 3.

The fix is simple: don't use the cache retrieved in step 1 to compute
the updated cache in step 3.  Rather, use `modify` instead of `put` to
create the new cache so that we preserve newly-added cache entries.
2018-11-24 08:52:30 -08:00
Gabriel Gonzalez 8bc595be7f
Add support for quoted path components (#690)
... as standardized in https://github.com/dhall-lang/dhall-lang/pull/293
2018-11-20 18:08:43 -08:00
Gabriel Gonzalez 8a5bfaa3b9
Add support for multi-`let` (#675)
... as standardized in: https://github.com/dhall-lang/dhall-lang/pull/266

This also adds `dhall lint` support for consolidating nested `let` expressions
2018-11-13 08:01:59 -08:00