Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dune & Jbuild validation for atoms #891

Merged
merged 9 commits into from
Jun 20, 2018

Conversation

rgrinberg
Copy link
Member

Atoms can now be constructed and pretty printed with a syntax = Jbuild | Dune.
The syntax controls validation that will be used to make sure we are printing
something/reading valid

An issue here is that I'm hard coding the dune syntax in a couple of places where we should probably be flexible - like the sub systems file. But it seems to work.

@rgrinberg rgrinberg requested a review from a user June 19, 2018 09:02
let rec jbuild s i len =
i = len ||
match String.unsafe_get s i with
| '"' | '(' | ')' | ';' | '\000'..'\032' | '\127'..'\255' -> false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to get back the old function here. The one that was checking for |# and #| as well

@rgrinberg
Copy link
Member Author

rgrinberg commented Jun 19, 2018 via email

@ghost
Copy link

ghost commented Jun 19, 2018

Yes, we might as well do it now.

@rgrinberg
Copy link
Member Author

@diml I improved the checks in the jbuild atom validator

@@ -140,7 +140,7 @@ parse {|"$bar%foo%"|}

parse {|\%{foo}|}
[%%expect{|
- : parse_result = Same (Ok [\%{foo}])
Exception: Invalid_argument "'\\%{foo}' is not a valid dune atom".
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you also modify parse so that Invalid_argument exceptions are captured? So that we can see if the behavior is different or not.

@ghost
Copy link

ghost commented Jun 19, 2018

BTW, following the conversation on slack, I assumed that of_string wouldn't do the validation anymore and it would be done in the pretty-printer. In particular we shouldn't need to pass Dune or Jbuild to Atom.of_string.

@rgrinberg
Copy link
Member Author

rgrinberg commented Jun 19, 2018 via email

@rgrinberg rgrinberg force-pushed the atom-jbuild-dune branch 2 times, most recently from 958ac68 to 260591c Compare June 20, 2018 08:18
@rgrinberg
Copy link
Member Author

@diml this is now rebased on master. PS, we should probably get rid of Invalid_argument in the sexp library as well, but for that we'll need to invert the dependency of stdlib and usexp first.

@rgrinberg
Copy link
Member Author

@diml taht failure from camomile is concerning:

# opam-version 1.2.2
# os           linux
# command      jbuilder build -p camomile -j 4
# path         /home/travis/.opam/system/build/camomile.1.0.1
# compiler     system (4.05.0)
# exit-code    1
# env-file     /home/travis/.opam/system/build/camomile.1.0.1/camomile-4431-ecffd3.env
# stdout-file  /home/travis/.opam/system/build/camomile.1.0.1/camomile-4431-ecffd3.out
# stderr-file  /home/travis/.opam/system/build/camomile.1.0.1/camomile-4431-ecffd3.err
### stderr ###
# File "Camomile/charmaps/jbuild.inc", line 5, characters 11-12:
# Error: Invalid atom character '%'

Is it because we aren't setting the version properly in include?

@rgrinberg
Copy link
Member Author

Wondering how should we version include. I suppose we could just make it use the same syntax as the file it's used in.

match String.unsafe_get s i with
| '#' -> disallow_next '|' s (i + 1) len
| '|' -> disallow_next '#' s (i + 1) len
| '"' | '(' | ')' | ';' | '\000'..'\032' | '\127'..'\255' -> false
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of these characters where allowed in jbuild syntax. Let's just restore the old function:

let is_valid str =
  let len = String.length str in
  len > 0 &&
  let rec loop ix =
    match str.[ix] with
    | '"' | '(' | ')' | ';' -> true
    | '|' -> ix > 0 && let next = ix - 1 in str.[next] = '#' || loop next
    | '#' -> ix > 0 && let next = ix - 1 in str.[next] = '|' || loop next
    | ' ' | '\t' | '\n' | '\012' | '\r' -> true
    | _ -> ix > 0 && loop (ix - 1)
  in
  not (loop (len - 1))

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old function was this:

 let is_valid =
   let rec loop s i len =
     i = len ||
     match String.unsafe_get s i with
     | '"' | '(' | ')' | ';' | '\000'..'\032' | '\127'..'\255' -> false
     | _ -> loop s (i + 1) len
   in
   fun s ->
     let len = String.length s in
     len > 0 && loop s 0 len

I'll use your definition however.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant from before #837


val of_string : string -> t

val to_string : t -> syntax -> string
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think to_string should do the validation. to_string should just return the contents of the atom. For instance I think that's why the build of camomile is broken in travis.

The validation should be done by a separate printing function.

@@ -23,13 +23,14 @@ let () =
| Atom _ -> true
| _ -> false
in
if Usexp.Atom.is_valid s <> parser_recognizes_as_atom then begin
let valid_dune_atom = Usexp.Atom.is_valid_dune s in
if valid_dune_atom <> parser_recognizes_as_atom then begin
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you update this test so that it runs for both the jbuild and Dune syntax? For instance it would have caught the issue related to is_valid_jbuild

@ghost
Copy link

ghost commented Jun 20, 2018

The camomile failure is because Of_sexp.string validates the atom using Dune syntax. Includes currently reuse the same syntax as the file they are included from.

@@ -7,20 +7,18 @@ module Atom : sig
(** Acceptable atoms are composed of chars in the range ['!' .. '~'] excluding
[' ' '"' '(' ')' ';' '\\'], and must be nonempty. *)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is no longer valid BTW, we can just remove it.

Different
{jbuild =
Ok
[<printer pp_sexp_ast raised an exception: Invalid_argument("atom '\\%{foo}' cannot be in dune syntax")>];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should do #remove_printer pp_sexp_ast before these tests, it took me a while to understand what was going on here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I think we should print the atoms unambigiously instead. Otherwise it sucks that we can't pp some of these ast's for debugging.

@rgrinberg
Copy link
Member Author

The last commit prints Sexp ast in a clearer way for debugging. Atoms are expanded out using an (atom <payload>) constructor.

Atoms can now be constructed and pretty printed with a syntax = Jbuild | Dune.
The syntax controls validation that will be used to make sure we are printing
something/reading valid

Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
And make the tests reflect back Invalid_argument

Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
@rgrinberg rgrinberg merged commit 411552e into ocaml:master Jun 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant