Allow omitting the alias in import statement.

This commit is contained in:
Stephen Chung 2020-08-05 23:23:53 +08:00
parent bb2c9f7c59
commit ffe52bf437
3 changed files with 19 additions and 15 deletions

View File

@ -7,10 +7,17 @@ Import a Module
`import` Statement `import` Statement
----------------- -----------------
A module can be _imported_ via the `import` statement, and its members are accessed via '`::`' similar to C++. A module can be _imported_ via the `import` statement, and be given a name.
Its members can be accessed via '`::`' similar to C++.
A module that is only `import`-ed but not under any module name is commonly used for initialization purposes,
where the module script contains initialization statements that puts the functions registered with the
[`Engine`] into a particular state.
```rust ```rust
import "crypto" as lock; // import the script file 'crypto.rhai' as a module named 'lock' import "crypto_init"; // run the script file 'crypto_init.rhai' without creating an imported module
import "crypto" as lock; // run the script file 'crypto.rhai' and import it as a module named 'lock'
lock::encrypt(secret); // use functions defined under the module via '::' lock::encrypt(secret); // use functions defined under the module via '::'

View File

@ -1806,7 +1806,7 @@ impl Engine {
// Import statement // Import statement
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
Stmt::Import(x) => { Stmt::Import(x) => {
let (expr, (name, _pos), _) = x.as_ref(); let (expr, alias, _pos) = x.as_ref();
// Guard against too many modules // Guard against too many modules
#[cfg(not(feature = "unchecked"))] #[cfg(not(feature = "unchecked"))]
@ -1820,8 +1820,11 @@ impl Engine {
{ {
if let Some(resolver) = &self.module_resolver { if let Some(resolver) = &self.module_resolver {
let mut module = resolver.resolve(self, &path, expr.position())?; let mut module = resolver.resolve(self, &path, expr.position())?;
if let Some((name, _)) = alias {
module.index_all_sub_modules(); module.index_all_sub_modules();
mods.push((name.clone().into(), module)); mods.push((name.clone().into(), module));
}
state.modules += 1; state.modules += 1;

View File

@ -568,7 +568,7 @@ pub enum Stmt {
ReturnWithVal(Box<((ReturnType, Position), Option<Expr>, Position)>), ReturnWithVal(Box<((ReturnType, Position), Option<Expr>, Position)>),
/// import expr as module /// import expr as module
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
Import(Box<(Expr, (String, Position), Position)>), Import(Box<(Expr, Option<(String, Position)>, Position)>),
/// expr id as name, ... /// expr id as name, ...
#[cfg(not(feature = "no_module"))] #[cfg(not(feature = "no_module"))]
Export( Export(
@ -2685,14 +2685,8 @@ fn parse_import(
let expr = parse_expr(input, state, lib, settings.level_up())?; let expr = parse_expr(input, state, lib, settings.level_up())?;
// import expr as ... // import expr as ...
match input.next().unwrap() { if !match_token(input, Token::As)? {
(Token::As, _) => (), return Ok(Stmt::Import(Box::new((expr, None, token_pos))));
(_, pos) => {
return Err(
PERR::MissingToken(Token::As.into(), "in this import statement".into())
.into_err(pos),
)
}
} }
// import expr as name ... // import expr as name ...
@ -2709,7 +2703,7 @@ fn parse_import(
Ok(Stmt::Import(Box::new(( Ok(Stmt::Import(Box::new((
expr, expr,
(name, settings.pos), Some((name, settings.pos)),
token_pos, token_pos,
)))) ))))
} }