-
Notifications
You must be signed in to change notification settings - Fork 407
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
Lowercase builtin vars #956
Conversation
b6b13c2
to
806b80c
Compare
$ dune runtest --root dune-upper | ||
Entering directory 'dune-upper' | ||
File "dune", line 3, characters 41-46: | ||
Error: Uppercase variables are removed in dune files. Use: %{make} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed in #948, what do you think about the following error message:
Error: Uppercase variables are removed in dune files.
Hint: Did you mean %{make} instead?
Error: Uppercase variables are removed in dune files. Use: %{make} | ||
[1] | ||
|
||
jbuilder retains the old names: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's about the file syntax rather than the tool, I think this should say "jbuild files" (and the commands can use dune runtest
).
@rgrinberg could you make the mechanism a bit more generic? We might want to add, remove or rename more variables in the future and we'll need support to do that. What about replacing
|
Actually, I can just introduce this change here and change the other stuff to use this later. It's not as straightforward to change the other stuff as they aren't really using maps yet (I hope to change that). |
Indeed. One possibility would be to enrich a bit the
|
Possibly |
806b80c
to
a34430f
Compare
@diml actually, ROOT can be handled using the old scheme we discussed before. By introducing a I'm not sure we should add deps or targets in there btw. Those expansions aren't available everywhere so it might be confusing to remember not to expand if a corresponding value has been found. |
That seems good, yes.
Well it's a two stage expansion, once we get to the module Var : sig
module Info : sig
type t =
| Nothing
| Since of Syntax.t * Syntax.Version.t
| Renamed_in of Syntax.t * Syntax.Version.t * string
| Deleted_in of Syntax.t * Syntax.Version.t
end
module Kind : sig
type t =
| Values of Value.t list
| Project_root
| Deps
| Targets
end
module Form : sig
type t =
| Exe
| Dep
| Bin
| Lib
| ...
| Read_lines
| ...
end
type 'a t =
{ kind : 'a
; info : Info.t
}
end
type t =
{ ...
; vars : Var.Kind.t Var.t String.Map.t
; forms : Var.Form.t Var.t String.Map.t
...
} This would allow to completely factorize the versioning code for variables and |
What is the point of the Also, do we need a Syntax.t yet? We're only using the dune syntax for now. But we can indeed add this parameter once we have other syntaxes to consider. EDIT: Ah ok I see, nvm |
e216b6b
to
14c3fb5
Compare
The last commit implements a rough version of the scheme @diml was talking about. One thing that I decided to change was not to attached values to renamed variables. The reasoning behind this is that it's yet another thing to make sure we sync correctly between the different names. The cost here is of course the extra lookup for these renamed vars. But since users are expected to transition, this cost will not be paid for long. In any case, if we switch the variable maps to be tables, the lookup will be much faster. Also, there might be some type system game we could play to avoid those |
I added a commit that removes a few assert false clauses at the expense of a lot GADT boilerplate. It's more of a joke than a serious improvement so I'm leaning towards reverting it :) |
By the way, we could just include the Kind inside the info and all these problems will go away:
|
5b1db1f
to
f68df16
Compare
And this is what I did. The code looks a lot cleaner. Switching to a hash table was fairly easy as well. @diml I'm wondering if we should make variable names interned. Seems like there will be some performance benefit and we'll have a distinct type for these kinds of strings. |
90d7157
to
7c44bfc
Compare
src/super_context.ml
Outdated
@@ -33,6 +33,245 @@ module Env_node = struct | |||
} | |||
end | |||
|
|||
module Var : sig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This module is big enough, let's put it in its own file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree, but this module is really private to super contexts. Can you think of a good name for this? Longer term, I'm thinking of renaming String_with_vars
to Template
and then it will be possible to have a Var
module.
By the way, this really highlights the need to have sub library like modules that we've talked about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So for now I'll create make var.ml
for this module.
src/super_context.ml
Outdated
else | ||
String_with_vars.Var.fail var ~f:(fun var -> | ||
sprintf "Variable %s is available in since version %s. \ | ||
Current version is %s" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you factorize these error messages between syntax.ml
and here? They'll be more consistent this way.
src/super_context.ml
Outdated
(Syntax.Version.to_string syntax_version)) | ||
| Renamed_in (in_version, new_name) -> begin | ||
if syntax_version >= in_version then | ||
String_with_vars.Var.fail var ~f:(fun old_name -> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't find Var.fail
particularly clear. I think this code would be clearer if we stick to Loc.fail (String_with_vars.Var.loc var) "..."
src/super_context.ml
Outdated
|
||
let rec expand t ~syntax_version ~var = | ||
let name = | ||
match String_with_vars.Var.destruct var with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is complicated version of var.name
, let's add Var.name : t -> string
src/super_context.ml
Outdated
end | ||
|
||
type 'a t = | ||
| Nothing of 'a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the name Nothing
was meant to mean no information
. Nothing of 'a
looks a bit odd, maybe just T of 'a
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed it to No_info
. T
is already our convention for open types.
src/super_context.ml
Outdated
begin match String_with_vars.Var.destruct var with | ||
| Single _ -> () | ||
| Pair (_, _) -> | ||
Exn.code_error "expand_vars can't expand forms" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this error can leak to the user. For instance if they write %{read:...}
in (flags ...)
or (copy_files ...)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You sure about that? We're making sure to call this on the right map. I.e. the one that contains only forms or only single variables.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a test with a %{read:...}
inside a copy_files
just to be sure?
src/super_context.ml
Outdated
@@ -84,26 +324,39 @@ let installed_libs t = t.installed_libs | |||
let find_scope_by_dir t dir = Scope.DB.find_by_dir t.scopes dir | |||
let find_scope_by_name t name = Scope.DB.find_by_name t.scopes name | |||
|
|||
let expand_var_no_root t var = String.Map.find t.vars var | |||
let expand_vars t ~syntax_version ~var : Var.Kind.t option = | |||
begin match String_with_vars.Var.destruct var with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add Var.is_form : t -> bool
. This should make this code slightly clearer.
src/super_context.ml
Outdated
match targets_written_by_user with | ||
| Infer -> Loc.fail loc "You cannot use %s with inferred rules." var | ||
| Alias -> Loc.fail loc "You cannot use %s in aliases." var | ||
| Static l -> Some (Value.L.dirs l) (* XXX hack to signal no dep *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The targets
function is used only once, I think it'll be clearer if it's inlined. It took me a while to understand why we needed a hack for instance.
@@ -3,8 +3,7 @@ We are dropping support for findlib in dune | |||
$ dune build --root in-dune target.txt | |||
Entering directory 'in-dune' | |||
File "dune", line 2, characters 25-37: | |||
Error: The findlib special variable is not supported in jbuild files, please use lib instead: | |||
%{lib:pkg} in dune files | |||
Error: Variable %{findlib:pkg} has been renamed to %{lib:pkg} since 1.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep the term variable for variables without payload. These should be called forms, so:
Error: The %{findlib:...} form has been renamed to %{lib:...} since version 1.0 of the dune language.
Note: we need to make sure to not print the actual payload in such error messages. If we include the payload (pkg
in thie case), then we are talking about this instance of the form. If we print ...
, we are talking about the form in general, which is what we want here.
This is a lot cleaner indeed and it's nice to see this code being cleanup! it dates from the origin of jbuilder... @rgrinberg I'm not sure we should use a hash table here. In the future we might want to locally extend the environment and using a mutable data structure will make that difficult. Regarding interning variables, I'm pretty sure the difference wouldn't be noticeable; I can only count about 1500 variables in the jbuild files of the whole dune-universe. |
Not necessarily. I was thinking that it should be possible to extend an environment by chaining the lookup. Which of course will also require a different representation. It's just that I thought we're paying for the map keys to be in sorted order, and I don't ever really see that being useful. I'll bring back the maps as it's really simple to swap the implementation.
Yeah, I didn't really expect it to be a huge gain either. We can revisit this if variables become more common place. |
Have another look @diml. I think I've addressed all your comments, but there were quite a few. So let me know if I missed anything. |
BTW, some of the terminology (
|
I'm having a look now |
src/var.ml
Outdated
let name = String_with_vars.Var.name var in | ||
Option.bind (String.Map.find t name) ~f:(fun v -> | ||
let what var = | ||
sprintf "Variable %s" (String_with_vars.Var.to_string var) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should check here if var
is a form or variable In order to display a different error message. If it's a form we should display: The %{<var-name>:...} form
, i.e. with the payload replaced by ...
so that it's clear we are talking about the form in general and not just this particular instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes. Makes sense. I only made this fix for a particular error message.
@@ -51,6 +53,5 @@ This form does not exist, but displays an hint: | |||
$ dune build --root jbuild-invalid @test-dep | |||
Entering directory 'jbuild-invalid' | |||
File "jbuild", line 5, characters 16-37: | |||
Error: ${dep:generated-file} is not supported in jbuild files. | |||
Hint: Did you mean ${path:generated-file} instead? | |||
Error: Variable ${dep:generated-file} is only available since version 0.0 of the dune language |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks odd. Shouldn't this say since version 1.0
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, I just substituted the wrong version.
Alright fixed those comments. I've renamed a few things to use the new naming convention now. There's probably more at the moment, but I'm not sure if it all needs to be in this PR. |
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Remove all gatd's and the extra record type 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>
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>
Don't include the payload in these messages 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>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
7a400a5
to
bfd246c
Compare
Agreed. Looks good, could you just add a test with something like |
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
This is a temporary hack until we have a real sexp type Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
Good call on adding such a test. Not only you were right about the error message, but also we caught a bug with respect to our pretty printing of errors themselves. I've added only a temporary fix for the printing of error messages for now. The real fix will come once we have a better type for errors. |
Signed-off-by: Rudi Grinberg <rudi.grinberg@gmail.com>
nice, that's good that we caught this other issue now |
SCOPE_ROOT and ROOT are still remaining as uppercased but those still need to be renamed.