Closed tamasfe closed 2 years ago
I wonder what need to set the root module name is...
Since the user can do:
import "foo" as xyz;
xyz::some_function();
xyz:;bar::some_inner_function();
That would mean that the root name can be freely changed by the script.
Otherwise you'd need to force the user to always do module xyz;
at the beginning of the definition file. In that case, however, you'd lose the ability to reuse/share the definition files.
Alternatively, you can keep some form of a mapping dynamically, mapping xyz
to foo
(the root name in the definitions file). Whenever you see xyz::...
, you replace the root with the mapped root. Then Bob's your uncle!
These definitions are only for modules that are already loaded in the engine.
By using register_submodule("foo", some_module);
, you will always end up with a definition file that starts with module foo;
.
Ah OK. I understand.
However, in the examples, I see import "./bar.rhai" as bar;
which is importing a script file with a definition file...
I wonder what will happen if I change the import to import "./bar.rhai" as foo;
? I'll try it out and see...
EDIT: Ha! It works just fine!
It should work as you expect, otherwise file a bug.
I made a distinction between modules that are already loaded, and modules introduced by import statements.
Using import "foo" as xyz;
is the same as declaring xyz
in the engine. The "foo" part only addresses how to load the module and has nothing to do with its name. Afaik you can do this in both script and definition files, and it should work just fine.
The module xyz;
definition files are only needed for modules already registered in the engine, they could theoretically be rewritten as import "whatever" as xyz
. The only issue is with nesting, as currently nesting is only possible via import statements.
You can define the following module structure in rust:
#[exported_module]
mod foo {
mod bar {
pub fn baz() {}
}
}
The only way this can be expressed right now in definition files is the following:
module foo;
import "???" as bar;
/// bar
module "???";
fn baz();
This implies that bar
can be imported from somewhere and re-exported from foo
, which is not the case because it only ever exists under foo
itself.
As it looks like module definition files are likely going to be needed only for Rust-based modules, your solution of the module bar { ... }
syntax to declare a sub-module should work fine.
This only leaves one small issue of inconsistency...
Module definition files have their own syntax (sort of), and are used to document Rust-based functions and modules.
Rhai scripts will be parsed dynamically and documentation extracted from the scripts.
The inconsistency is that, in case that there is a definition file with the same name as a Rhai script, then the doc-comment on its top-most module
statement will be taken as the documentation of that Rhai script file itself -- with all other information in the definition file ignored, I suppose.
I wonder if there is a way to embed module comments directly into the Rhai script itself to avoid you having to do this.
Can you give an example?
Definitions for scripts and existing modules should never conflict.
You can write the following for your script definition:
// foo.d.rhai
module "./foo.rhai";
fn whatever();
// foo.rhai
fn whatever () {}
Then a foo
module from rust:
module foo;
fn whatever_from_rust();
The only way for these to conflict is doing
import "./foo.rhai" as foo;
At which point it's either a name conflict, or foo
from rust is redeclared using the import from foo.rhai
, I don't know how rhai handles these currently.
I think I didn't make myself clear. What I mean is... a script file internally has all the documentation, and the only reason why we need a definition file is to provide documentation on the script file itself as a module.
Therefore, if I find a way to include module documentation inside the script file itself, then script files should never need definition files as they are self-contained. In that case, we keep all definition files exclusively for use with Rust modules.
At which point it's either a name conflict, or
foo
from rust is redeclared using the import fromfoo.rhai
, I don't know how rhai handles these currently.
In this case, the import
overrides the static namespace.
I see, yeah the syntax //!
suggested earlier could help with this.
script files should never need definition files as they are self-contained
You currently need definitions for all type information, I think adding all of this to rhai should come after the definition format is fully tested and fleshed-out. I opened https://github.com/rhaiscript/rhai/issues/488 for type hints, but I don't think it should be rushed as it'd be a significant addition.
You currently need definitions for all type information,
Ah, got that. I see now. There is no way to get rid of definition files (unless I also embed type info into the script). Therefore, mind as well keep the current way of doing things then.
It is not simple to add a //!
syntax and I would prefer to avoid introducing it unless it serves a really good purpose. That is because it theoretically can only occur at the beginning of a script file, but script files can be merged and joined from pieces. Therefore, it is very easy to get //!
comments in the middle of a script.
Therefore, it is very easy to get //! comments in the middle of a script.
I don't think it's an issue, we can relax it to allow it anyhere and just merge them together, in fact we don't even need the support from Rhai in that case, and I can do it in the rowan-based parser alone.
I don't think it's an issue, we can relax it to allow it anyhere and just merge them together, in fact we don't even need the support from Rhai in that case, and I can do it in the rowan-based parser alone.
That would be the best, I think. Do it in the LSP, and Rhai will continue to treat it as normal comments.
In that case, the definition files for scripts will be to hold type declarations only. The script file's module doc can be obtained via //!
blocks inside the script.
This looks like a great solution.
I'll put //!
on Rhai example scripts from now on, in anticipation to this feature.
Inspired by your comment, I actually found an easy way to implement //!
documentation in Rhai!
In the new version, AST::doc()
would yield the script documentation.
AST::doc()
is available in the latest drop.
Solved in #69, and #70.
Currently it's not possible to define nested modules in definition files.
Nested modules can only come from import statements.
The solution is simple-ish without breaking the existing architecture.
We can define arbitrary modules within a module with the following syntax:
And then we flatten the inner modules and assign unique URIs to them, then treat them as usual afterwards.