Commit Graph

234 Commits

Author SHA1 Message Date
Simon Jakobi
88d6671e38
Enable the fixed potPourri test (#1144)
Context: https://github.com/dhall-lang/dhall-lang/pull/655
2019-07-21 15:21:20 +02:00
Gabriel Gonzalez
0120f2650d Document that normalize is partial (#1140)
* Document that `normalize` is partial

Fixes https://github.com/dhall-lang/dhall-haskell/issues/1138

* Document other partial functions

... as suggested by @sjakobi
2019-07-20 20:14:52 +00:00
Gabriel Gonzalez
0c61b0d048 Forbid invalid codepoints (#1104)
* 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
2019-07-20 19:41:18 +00:00
Simon Jakobi
0ee6ce6f6f Implement "Generalize empty list annotations" (#1112)
…as standardized in https://github.com/dhall-lang/dhall-lang/pull/630

Also:

* Update the dhall-lang submodule to the state of
  https://github.com/dhall-lang/dhall-lang/pull/654.

* Skip the nonCharacter test for now.

Fixes #414.
Fixes #770.
2019-07-20 18:05:23 +00:00
Gabriel Gonzalez
cbd6a6543d Support lens-family-core-2.0.0 (#1141)
Related to https://github.com/commercialhaskell/stackage/issues/4725
2019-07-20 12:18:49 +00:00
Simon Jakobi
8aa8add453 Catch errors in normalizeWithM when testing it (#1139)
Context: #1138
2019-07-20 04:30:42 +00:00
Simon Jakobi
482984eb6d Allow only valid HTTP(S) reg-names (#1124)
Corresponding change to the standard:
https://github.com/dhall-lang/dhall-lang/pull/627

The potPourri parser test remains disabled due to
https://github.com/dhall-lang/dhall-lang/pull/655.

Fixes https://github.com/dhall-lang/dhall-haskell/issues/1110.
2019-07-20 00:54:27 +00:00
Simon Jakobi
e40e847730 Always typecheck the type annotation on 'toMap' (#1132)
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.
2019-07-19 23:14:01 +00:00
Gabriel Gonzalez
f0d017d7c5 Fix test suite to accept expected decoding failures (#1136)
This will be necessary for https://github.com/dhall-lang/dhall-lang/pull/640
2019-07-19 21:11:22 +00:00
Gabriel Gonzalez
a440c6cd28 Improve error message for missing constructor (#1137)
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1130
2019-07-19 20:17:14 +00:00
Frederik Ramcke
7e9728f0e9 dhall-lsp-server: Freezing imports (#1123)
* 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
2019-07-19 17:24:11 +00:00
Simon Jakobi
b4f71b2aa2 Check normalizeWithM for consistency with normalize (#1126)
* 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.
2019-07-19 15:33:59 +00:00
quasicomputational
0df6362a9d Make the tests build with GHC 7.10. (#1134) 2019-07-18 23:11:51 +00:00
Simon Jakobi
40ec83743d Make isNormalized consistent with normalize (#1115)
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.
2019-07-17 22:19: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
Simon Jakobi
e044b4ab68
toMap normalization: Misc improvements (#1116)
…addressing my own comments on
https://github.com/dhall-lang/dhall-haskell/pull/1041.
2019-07-15 23:50:40 +02:00
Simon Jakobi
3856612763
Sort the fields of a record projection during normalization (#1111)
…as standardized in https://github.com/dhall-lang/dhall-lang/pull/625.
2019-07-15 20:55:00 +02: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
Simon Jakobi
b2cbc8227f Remove usage of legacy Optional syntax (#1091)
* Remove usage of legacy Optional syntax

* Dhall.JSON: Use multilet in examples

* Update dhall-json/src/Dhall/JSON.hs

Co-Authored-By: Gabriel Gonzalez <Gabriel439@gmail.com>

* Update dhall-json/src/Dhall/JSON.hs

Co-Authored-By: Gabriel Gonzalez <Gabriel439@gmail.com>

* Update dhall-json/src/Dhall/JSON.hs

Co-Authored-By: Gabriel Gonzalez <Gabriel439@gmail.com>

* Update dhall-nix/src/Dhall/Nix.hs

Co-Authored-By: Gabriel Gonzalez <Gabriel439@gmail.com>

* Update dhall-nix/src/Dhall/Nix.hs

Co-Authored-By: Gabriel Gonzalez <Gabriel439@gmail.com>

* Revert changes to travis.yml

* Lint travis.dhall
2019-07-14 18:36:41 +00:00
Gabriel Gonzalez
90b62ee9d7 Replace dhall-to-text with dhall text subcommand (#1090)
Fixes #1087
2019-07-08 17:18:09 +00: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
635a4489d2 Fix unexpected decoding successes in tests (#1088)
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
2019-07-07 17:22:53 +00:00
Simon Jakobi
f1234c4efa Don't typecheck the head of a list twice. (#1085) 2019-07-07 16:50:06 +00:00
Simon Jakobi
e40d0bc624 Simplify typechecking of Combine and CombineTypes (#1067)
Also add Dhall.Map.outerJoin, inspired by Semialign.align.
2019-07-07 16:00:25 +00:00
Simon Jakobi
d7114a32de Simplify normalization of record projection (#1071)
…via new functions Dhall.Map.{keysSet,restrictKeys} and
Dhall.Set.fromSet.

Also apply these functions in a few more cases.
2019-07-07 14:33:07 +00:00
Gabriel Gonzalez
462f82a0f8 Build against optparse-applicative-0.15 (#1081)
Related to https://github.com/commercialhaskell/stackage/issues/4693
2019-07-07 11:49:11 +00:00
Simon Jakobi
f873b0d66e Increase coverage of acceptance tests (#1072)
* dhall:tasty: Unskip a few tests

These remain broken:

- tests/parser/failure/annotation
- tests/parser/failure/missingSpace
- tests/parser/failure/unit/ImportEnvWrongEscape
- tests/parser/failure/unit/ListLitEmptyAnnotation
- tests/parser/failure/unit/ListLitEmptyPrecedence
- tests/parser/success/unit/MergeParenAnnotation

* Typo

* Add binary-decode failure tests

A few pass, but these are broken:

- tests/binary-decode/failure/unit/ApplyNoArgs
- tests/binary-decode/failure/unit/LambdaExplicitlyNamedUnderscore
- tests/binary-decode/failure/unit/NaturalNegativeOne
- tests/binary-decode/failure/unit/PiExplicitlyNamedUnderscore
- tests/binary-decode/failure/unit/VariableExplicitlyNamedUnderscore

* dhall:tasty: Add semantic-hash tests
2019-07-07 11:00:55 +00:00
Simon Jakobi
3b4f826eda Dhall.Map: Remove the keys list when sorting (#1066)
Also add the unorderedSingleton and unorderedFromList functions.

This speeds up the "issue 412" benchmark by ~9% and "union performance"
by ~2%.
2019-07-07 07:21:04 +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
Simon Jakobi
76efe630b2 Remove cruft related to the removed 'constructors' keyword (#1077) 2019-07-06 22:38:02 +00:00
Simon Jakobi
9a2e25b92d Dhall.Map.fromList: Fix docs (#1078)
Closes #1052.
2019-07-06 20:58:32 +00:00
Simon Jakobi
28fc9e1870 Dhall.Eval.eqMapsBy: Compare map sizes before contents (#1065)
Data.Map.size is O(1), so we expose it via Dhall.Map.
2019-07-05 04:04:08 +00:00
Simon Jakobi
c7e48bf497 Skip re-typechecking the first non-empty union alternative (#1057)
For the deep-nested-large-record benchmark, this results in a
speedup of about 0.5–1%.
2019-07-03 16:57:05 +00:00
Simon Jakobi
e061f35c4c Simplify Dhall.Parser.Combinators.toMap (#1053)
This changes the parsing error for some cases.

Previously:

    ⊢ {b=1, a=1, b=1, a=1}

    Error: Invalid input

    (stdin):1:20:
      |
    1 | {b=1, a=1, b=1, a=1}
      |                    ^
    duplicate field: b

Now:

    ⊢ {b=1, a=1, b=1, a=1}

    Error: Invalid input

    (stdin):1:20:
      |
    1 | {b=1, a=1, b=1, a=1}
      |                    ^
    duplicate field: a

Also add a new function to Dhall.Map: fromListWithKey
2019-07-03 15:46:13 +00:00
Gabriel Gonzalez
af0e77ce00
Consistently format multi-line strings (#1056)
Fixes #973

The formatter was behaving inconsistently for multi-line strings
depending on whether or not they were at the top level or nested as
a subexpression.  For example, the same multi-line string would be
rendered in multi-line form if it was at the top level and rendered
compactly if nested within another expression.

The root cause was that the pretty-printing logic was missing a top-level
`Pretty.group` call (which is the function responsible for enabling
compact representations if they fit), which this change fixes.
2019-07-02 13:54:54 -07:00
Simon Jakobi
51a020e3e4
Dhall.Map: Reflect original key ordering in Ord instance (#1050) 2019-07-02 19:44:33 +02:00
Gabriel Gonzalez
f5819dd6d6 Improve performance of type-checking record literals (#1048)
While benchmarking the example from #769 I saw that a significant
amount of time was spent benchmarking record literals.  When I looked
at the code more closely I saw that the first key in the record literal
was being type-checked twice (once to figure out the record's associated
type-checking constant and once as part of the `process` loop).

This change fixes that, which speeds up interpretation of the large
example by 9%:

Before:

```
time                 18.13 s    (18.11 s .. 18.16 s)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 18.09 s    (18.07 s .. 18.11 s)
std dev              21.92 ms   (10.66 ms .. 29.76 ms)
variance introduced by outliers: 19% (moderately inflated)
```

After:

```
time                 16.53 s    (16.49 s .. 16.60 s)
                     1.000 R²   (1.000 R² .. 1.000 R²)
mean                 16.59 s    (16.56 s .. 16.64 s)
std dev              43.65 ms   (6.227 ms .. 56.35 ms)
variance introduced by outliers: 19% (moderately inflated)
```
2019-07-02 18:42:05 +02:00
Simon Jakobi
0057901e58 Dhall.Map: Change Foldable and Traversable instances to respect the key ordering (#1051) 2019-07-02 07:47:41 -07:00
Gabriel Gonzalez
92bdd56a34
Switch Var to use an Int (#1044)
Related to: https://github.com/dhall-lang/dhall-haskell/issues/1039

We'll probably never see indices that exceed the space of an `Int` and
the interpreter would probably not be able to handle 9223372036854775807
nested binders anyway.
2019-07-01 17:24:13 -07:00
Simon Jakobi
15e981f61c
Fix benchmarks, run them on AppVeyor (#1033)
Since we only want to ensure that the benchmarks continue to
work, we use the following benchmark arguments to run them
as quickly as possible:

- `--quick` ensures that gauge runs only a single sample.
- `--min-duration=0` sets the number of iterations per sample to 1.
- `--include-first-iter` causes gauge to accept that one iteration
  instead of discarding it and running a second one.

This also removes the dhall-command benchmark:

This was a non-standard benchmark that failed when run
without input from stdin. To replace this profiling tool,
I have added instructions for profiling the main executables
to the README.
2019-07-01 12:52:43 +02:00
Fabrizio Ferrai
04d82120a4 Implement importing as Location (#1019) 2019-06-30 22:00:14 -07:00
Simon Jakobi
7647adba1a
Speed up Dhall.Map.unorderedTraverseWithKey_ (#1036)
This reduces the runtime of the `deep-nested-large-record` benchmark by about 50%.

Note that previously, contrary to its name and documentation, this function traversed a Dhall.Map in insertion order due to its use of Dhall.Map.toList! With this change, the traversal is changed to ascending key order.

Also:
- Fix the deep-nested-large-record benchmark

- Remove the map-operations benchmark: This benchmark actually reports a ~20% loss of performance for the unorderedTraverseWithKey_ change.  Since we eventually care about dhall's performance we it's better not to be mislead by a questionable micro-benchmark.
2019-06-30 19:54:13 +02:00
Dmitry Dolgov
0bf4e41020 Fix appveyor tests (#1037)
Fixes #1034

Fixes the `import/success/hashFromCache`  test on Windows

Disables currently broken dhall-lsp-server tests
2019-06-30 14:35:55 +02:00
Gabriel Gonzalez
bb365dd0f3
Remove prettyDiff internal helper (#1038)
... as suggested by @sjakobi in https://github.com/dhall-lang/dhall-haskell/pull/1027#issuecomment-506516607

After some internal refactors, `prettyDiff` is now just an
alias for `Dhall.Diff.diffNormalized`, so it's no longer
necessary.
2019-06-28 07:30:15 -07:00
Gabriel Gonzalez
250fdfc348
Reject record projection when there is a field type mismatch (#1027)
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1020

This also includes small fixes to the `MissingField` error message,
which I found along the way.
2019-06-27 21:55:09 -07:00
Gabriel Gonzalez
09016735fa
Use vertical bars for the left margin of source spans (#1030)
This separates the source from the line numbers using vertical bars
instead of colons.  The main reason for this is to more clearly
delimit the two and to also prevent the old colon from being confused
as a type annotation.
2019-06-27 20:37:10 -07:00
Gabriel Gonzalez
484182b74e
Remove the InvalidField error constructor (#1026)
Fixes https://github.com/dhall-lang/dhall-haskell/issues/1025

There were two error constructors related to invalid field types:

* `InvalidField`: for field types whose types were invalid type-checking
  constants
* `InvalidFieldType`: for all other invalid field types

As @sjakobi noted, there are no invalid field types for the former
category, so we can remove that category of error entirely.

Note that `InvalidField` was still being used in a few places, but each
of those uses should actually have been using `InvalidFieldType`
instead, which this change also fixes.
2019-06-27 13:19:16 -07:00
Simon Jakobi
57aab91241 Replace criterion with gauge (#1035)
This reduces build times for the benchmarks.
2019-06-27 09:41:42 -07:00