Merge branch 'main' into feat-definitions
This commit is contained in:
commit
0bf7baa502
@ -17,6 +17,7 @@ New features
|
|||||||
|
|
||||||
* A new feature, `no_custom_syntax`, is added to remove custom syntax support from Rhai for applications that do not require it (which should be most).
|
* A new feature, `no_custom_syntax`, is added to remove custom syntax support from Rhai for applications that do not require it (which should be most).
|
||||||
* Comment lines beginning with `//!` (requires the `metadata` feature) are now collected as the script file's _module documentation_.
|
* Comment lines beginning with `//!` (requires the `metadata` feature) are now collected as the script file's _module documentation_.
|
||||||
|
* `AST` and `Module` have methods to access and manipulate documentation.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
@ -34,6 +35,7 @@ Enhancements
|
|||||||
* A new `range` function variant that takes an exclusive range with a step.
|
* A new `range` function variant that takes an exclusive range with a step.
|
||||||
* `as_string` is added to BLOB's to convert it into a string by interpreting it as a UTF-8 byte stream.
|
* `as_string` is added to BLOB's to convert it into a string by interpreting it as a UTF-8 byte stream.
|
||||||
* `FnAccess::is_private`, `FnAccess::is_public`, `FnNamespace::is_module_namespace` and `FnNameSpace::is_global_namespace` are added for convenience.
|
* `FnAccess::is_private`, `FnAccess::is_public`, `FnNamespace::is_module_namespace` and `FnNameSpace::is_global_namespace` are added for convenience.
|
||||||
|
* `Iterator<Item=T>` type for functions metadata is simplified to `Iterator<T>`.
|
||||||
|
|
||||||
|
|
||||||
Version 1.8.0
|
Version 1.8.0
|
||||||
|
@ -13,7 +13,7 @@ homepage = "https://rhai.rs"
|
|||||||
repository = "https://github.com/rhaiscript"
|
repository = "https://github.com/rhaiscript"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
include = ["/src/**/*.rs", "/Cargo.toml", "/README.md"]
|
include = ["/src/**/*", "/Cargo.toml", "/README.md", "LICENSE*"]
|
||||||
keywords = ["scripting", "scripting-engine", "scripting-language", "embedded"]
|
keywords = ["scripting", "scripting-engine", "scripting-language", "embedded"]
|
||||||
categories = ["no-std", "embedded", "wasm", "parser-implementations"]
|
categories = ["no-std", "embedded", "wasm", "parser-implementations"]
|
||||||
|
|
||||||
@ -82,6 +82,10 @@ name = "rhai-run"
|
|||||||
name = "rhai-dbg"
|
name = "rhai-dbg"
|
||||||
required-features = ["debugging"]
|
required-features = ["debugging"]
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "serde"
|
||||||
|
required-features = ["serde"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "definitions"
|
name = "definitions"
|
||||||
required-features = ["metadata"]
|
required-features = ["metadata"]
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
//! An example showing how to register a Rust type and use it with arrays.
|
//! An example showing how to register a Rust type and use it with arrays.
|
||||||
|
|
||||||
|
#[cfg(any(feature = "no_index", feature = "no_object"))]
|
||||||
|
fn main() {
|
||||||
|
panic!("This example does not run under 'no_index' or 'no_object'.")
|
||||||
|
}
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult};
|
use rhai::{Engine, EvalAltResult};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
@ -60,8 +65,3 @@ fn main() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "no_index", feature = "no_object"))]
|
|
||||||
fn main() {
|
|
||||||
panic!("This example does not run under 'no_index' or 'no_object'.")
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
//! An example showing how to register a Rust type and methods/getters/setters for it.
|
//! An example showing how to register a Rust type and methods/getters/setters for it.
|
||||||
|
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
fn main() {
|
||||||
|
panic!("This example does not run under 'no_object'.");
|
||||||
|
}
|
||||||
|
|
||||||
use rhai::{Engine, EvalAltResult};
|
use rhai::{Engine, EvalAltResult};
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
@ -61,8 +66,3 @@ fn main() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "no_object")]
|
|
||||||
fn main() {
|
|
||||||
panic!("This example does not run under 'no_object'.");
|
|
||||||
}
|
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
//! Implementation of the Event Handler With State Pattern - JS Style
|
//! Implementation of the Event Handler With State Pattern - JS Style
|
||||||
use rhai::{Dynamic, Engine, Scope, AST};
|
|
||||||
|
|
||||||
|
#[cfg(any(feature = "no_function", feature = "no_object"))]
|
||||||
|
pub fn main() {
|
||||||
|
panic!("This example does not run under 'no_function' or 'no_object'.")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use rhai::Map;
|
pub fn main() {
|
||||||
|
use rhai::{Dynamic, Engine, Map, Scope, AST};
|
||||||
|
use std::io::{stdin, stdout, Write};
|
||||||
|
|
||||||
use std::io::{stdin, stdout, Write};
|
const SCRIPT_FILE: &str = "event_handler_js/script.rhai";
|
||||||
|
|
||||||
const SCRIPT_FILE: &str = "event_handler_js/script.rhai";
|
#[derive(Debug)]
|
||||||
|
struct Handler {
|
||||||
#[derive(Debug)]
|
|
||||||
struct Handler {
|
|
||||||
pub engine: Engine,
|
pub engine: Engine,
|
||||||
pub scope: Scope<'static>,
|
pub scope: Scope<'static>,
|
||||||
pub states: Dynamic,
|
pub states: Dynamic,
|
||||||
pub ast: AST,
|
pub ast: AST,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_scope(scope: &Scope) {
|
fn print_scope(scope: &Scope) {
|
||||||
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
||||||
@ -33,11 +38,8 @@ fn print_scope(scope: &Scope) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
pub fn main() {
|
|
||||||
println!("Events Handler Example - JS Style");
|
println!("Events Handler Example - JS Style");
|
||||||
println!("==================================");
|
println!("==================================");
|
||||||
|
|
||||||
@ -158,8 +160,3 @@ pub fn main() {
|
|||||||
|
|
||||||
println!("Bye!");
|
println!("Bye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "no_function", feature = "no_object"))]
|
|
||||||
pub fn main() {
|
|
||||||
panic!("This example does not run under 'no_function' or 'no_object'.")
|
|
||||||
}
|
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
//! Implementation of the Event Handler With State Pattern - Main Style
|
//! Implementation of the Event Handler With State Pattern - Main Style
|
||||||
use rhai::{Dynamic, Engine, Scope, AST};
|
|
||||||
|
|
||||||
use std::io::{stdin, stdout, Write};
|
#[cfg(feature = "no_function")]
|
||||||
|
pub fn main() {
|
||||||
|
panic!("This example does not run under 'no_function'.")
|
||||||
|
}
|
||||||
|
|
||||||
const SCRIPT_FILE: &str = "event_handler_main/script.rhai";
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
pub fn main() {
|
||||||
|
use rhai::{Dynamic, Engine, Scope, AST};
|
||||||
|
use std::io::{stdin, stdout, Write};
|
||||||
|
|
||||||
#[derive(Debug)]
|
const SCRIPT_FILE: &str = "event_handler_main/script.rhai";
|
||||||
struct Handler {
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Handler {
|
||||||
pub engine: Engine,
|
pub engine: Engine,
|
||||||
pub scope: Scope<'static>,
|
pub scope: Scope<'static>,
|
||||||
pub ast: AST,
|
pub ast: AST,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_scope(scope: &Scope) {
|
fn print_scope(scope: &Scope) {
|
||||||
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
||||||
@ -29,10 +36,8 @@ fn print_scope(scope: &Scope) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
pub fn main() {
|
|
||||||
println!("Events Handler Example - Main Style");
|
println!("Events Handler Example - Main Style");
|
||||||
println!("===================================");
|
println!("===================================");
|
||||||
|
|
||||||
@ -130,8 +135,3 @@ pub fn main() {
|
|||||||
|
|
||||||
println!("Bye!");
|
println!("Bye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "no_function")]
|
|
||||||
pub fn main() {
|
|
||||||
panic!("This example does not run under 'no_function'.")
|
|
||||||
}
|
|
||||||
|
@ -1,21 +1,26 @@
|
|||||||
//! Implementation of the Event Handler With State Pattern - Map Style
|
//! Implementation of the Event Handler With State Pattern - Map Style
|
||||||
use rhai::{Dynamic, Engine, Scope, AST};
|
|
||||||
|
|
||||||
|
#[cfg(any(feature = "no_function", feature = "no_object"))]
|
||||||
|
pub fn main() {
|
||||||
|
panic!("This example does not run under 'no_function' or 'no_object'.")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
use rhai::Map;
|
pub fn main() {
|
||||||
|
use rhai::{Dynamic, Engine, Map, Scope, AST};
|
||||||
|
use std::io::{stdin, stdout, Write};
|
||||||
|
|
||||||
use std::io::{stdin, stdout, Write};
|
const SCRIPT_FILE: &str = "event_handler_map/script.rhai";
|
||||||
|
|
||||||
const SCRIPT_FILE: &str = "event_handler_map/script.rhai";
|
#[derive(Debug)]
|
||||||
|
struct Handler {
|
||||||
#[derive(Debug)]
|
|
||||||
struct Handler {
|
|
||||||
pub engine: Engine,
|
pub engine: Engine,
|
||||||
pub scope: Scope<'static>,
|
pub scope: Scope<'static>,
|
||||||
pub ast: AST,
|
pub ast: AST,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_scope(scope: &Scope) {
|
fn print_scope(scope: &Scope) {
|
||||||
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
|
||||||
@ -32,11 +37,8 @@ fn print_scope(scope: &Scope) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_function"))]
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
pub fn main() {
|
|
||||||
println!("Events Handler Example - Map Style");
|
println!("Events Handler Example - Map Style");
|
||||||
println!("==================================");
|
println!("==================================");
|
||||||
|
|
||||||
@ -147,8 +149,3 @@ pub fn main() {
|
|||||||
|
|
||||||
println!("Bye!");
|
println!("Bye!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(feature = "no_function", feature = "no_object"))]
|
|
||||||
pub fn main() {
|
|
||||||
panic!("This example does not run under 'no_function' or 'no_object'.")
|
|
||||||
}
|
|
||||||
|
@ -1,22 +1,12 @@
|
|||||||
//! An example to serialize and deserialize Rust types.
|
//! An example to serialize and deserialize Rust types.
|
||||||
|
|
||||||
#[cfg(any(not(feature = "serde"), feature = "no_object"))]
|
#[cfg(feature = "no_object")]
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("This example requires the 'serde' feature to run.");
|
panic!("This example does not run under 'no_object'.")
|
||||||
println!("Try: cargo run --features serde --example serde");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
example::ser();
|
|
||||||
println!();
|
|
||||||
example::de();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
|
||||||
mod example {
|
|
||||||
use rhai::serde::{from_dynamic, to_dynamic};
|
use rhai::serde::{from_dynamic, to_dynamic};
|
||||||
use rhai::{Dynamic, Engine, Map};
|
use rhai::{Dynamic, Engine, Map};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -89,4 +79,8 @@ mod example {
|
|||||||
);
|
);
|
||||||
println!("Deserialized to struct: {:#?}", x);
|
println!("Deserialized to struct: {:#?}", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ser();
|
||||||
|
println!();
|
||||||
|
de();
|
||||||
}
|
}
|
||||||
|
@ -222,10 +222,10 @@ impl Engine {
|
|||||||
self.token_mapper.as_ref().map(<_>::as_ref),
|
self.token_mapper.as_ref().map(<_>::as_ref),
|
||||||
);
|
);
|
||||||
let mut state = ParseState::new(self, scope, tokenizer_control);
|
let mut state = ParseState::new(self, scope, tokenizer_control);
|
||||||
let mut ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
let mut _ast = self.parse(&mut stream.peekable(), &mut state, optimization_level)?;
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n"));
|
_ast.set_doc(state.tokenizer_control.borrow().global_comments.join("\n"));
|
||||||
Ok(ast)
|
Ok(_ast)
|
||||||
}
|
}
|
||||||
/// Compile a string containing an expression into an [`AST`],
|
/// Compile a string containing an expression into an [`AST`],
|
||||||
/// which can be used later for evaluation.
|
/// which can be used later for evaluation.
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
#![cfg(not(feature = "no_optimize"))]
|
#![cfg(not(feature = "no_optimize"))]
|
||||||
|
|
||||||
use crate::{Engine, OptimizationLevel, Scope, AST};
|
use crate::{Engine, OptimizationLevel, Scope, AST};
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Control whether and how the [`Engine`] will optimize an [`AST`] after compilation.
|
/// Control whether and how the [`Engine`] will optimize an [`AST`] after compilation.
|
||||||
@ -60,7 +59,7 @@ impl Engine {
|
|||||||
.map(|f| f.func.get_script_fn_def().unwrap().clone())
|
.map(|f| f.func.get_script_fn_def().unwrap().clone())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut new_ast = crate::optimizer::optimize_into_ast(
|
let mut _new_ast = crate::optimizer::optimize_into_ast(
|
||||||
self,
|
self,
|
||||||
scope,
|
scope,
|
||||||
ast.take_statements(),
|
ast.take_statements(),
|
||||||
@ -70,8 +69,8 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
new_ast.set_doc(mem::take(ast.doc_mut()));
|
_new_ast.set_doc(std::mem::take(ast.doc_mut()));
|
||||||
|
|
||||||
new_ast
|
_new_ast
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Module defining the AST (abstract syntax tree).
|
//! Module defining the AST (abstract syntax tree).
|
||||||
|
|
||||||
use super::{ASTFlags, Expr, FnAccess, Stmt, StmtBlock, StmtBlockContainer};
|
use super::{ASTFlags, Expr, FnAccess, Stmt, StmtBlock, StmtBlockContainer};
|
||||||
use crate::{Dynamic, FnNamespace, Identifier, Position, SmartString};
|
use crate::{Dynamic, FnNamespace, Identifier, Position};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{
|
use std::{
|
||||||
@ -23,7 +23,7 @@ pub struct AST {
|
|||||||
source: Identifier,
|
source: Identifier,
|
||||||
/// [`AST`] documentation.
|
/// [`AST`] documentation.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: SmartString,
|
doc: crate::SmartString,
|
||||||
/// Global statements.
|
/// Global statements.
|
||||||
body: StmtBlock,
|
body: StmtBlock,
|
||||||
/// Script-defined functions.
|
/// Script-defined functions.
|
||||||
@ -76,7 +76,7 @@ impl AST {
|
|||||||
Self {
|
Self {
|
||||||
source: Identifier::new_const(),
|
source: Identifier::new_const(),
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: SmartString::new_const(),
|
doc: crate::SmartString::new_const(),
|
||||||
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: functions.into(),
|
lib: functions.into(),
|
||||||
@ -96,7 +96,7 @@ impl AST {
|
|||||||
Self {
|
Self {
|
||||||
source: Identifier::new_const(),
|
source: Identifier::new_const(),
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: SmartString::new_const(),
|
doc: crate::SmartString::new_const(),
|
||||||
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: functions.into(),
|
lib: functions.into(),
|
||||||
@ -146,7 +146,7 @@ impl AST {
|
|||||||
Self {
|
Self {
|
||||||
source: Identifier::new_const(),
|
source: Identifier::new_const(),
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
doc: SmartString::new_const(),
|
doc: crate::SmartString::new_const(),
|
||||||
body: StmtBlock::NONE,
|
body: StmtBlock::NONE,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: crate::Module::new().into(),
|
lib: crate::Module::new().into(),
|
||||||
@ -195,6 +195,7 @@ impl AST {
|
|||||||
/// Leading white-spaces are stripped, and each line always starts with `//!`.
|
/// Leading white-spaces are stripped, and each line always starts with `//!`.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[must_use]
|
||||||
pub fn doc(&self) -> &str {
|
pub fn doc(&self) -> &str {
|
||||||
&self.doc
|
&self.doc
|
||||||
}
|
}
|
||||||
@ -211,7 +212,8 @@ impl AST {
|
|||||||
/// Only available under `metadata`.
|
/// Only available under `metadata`.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn doc_mut(&mut self) -> &mut SmartString {
|
#[must_use]
|
||||||
|
pub(crate) fn doc_mut(&mut self) -> &mut crate::SmartString {
|
||||||
&mut self.doc
|
&mut self.doc
|
||||||
}
|
}
|
||||||
/// Set the documentation.
|
/// Set the documentation.
|
||||||
@ -219,7 +221,7 @@ impl AST {
|
|||||||
/// Only available under `metadata`.
|
/// Only available under `metadata`.
|
||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn set_doc(&mut self, doc: impl Into<SmartString>) {
|
pub(crate) fn set_doc(&mut self, doc: impl Into<crate::SmartString>) {
|
||||||
self.doc = doc.into();
|
self.doc = doc.into();
|
||||||
}
|
}
|
||||||
/// Get the statements.
|
/// Get the statements.
|
||||||
|
@ -260,7 +260,7 @@ impl RangeCase {
|
|||||||
Self::InclusiveInt(..) => true,
|
Self::InclusiveInt(..) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the index to the [`ConditionalStmtBlock`].
|
/// Get the index to the [`ConditionalExpr`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn index(&self) -> usize {
|
pub fn index(&self) -> usize {
|
||||||
@ -268,7 +268,7 @@ impl RangeCase {
|
|||||||
Self::ExclusiveInt(.., n) | Self::InclusiveInt(.., n) => *n,
|
Self::ExclusiveInt(.., n) | Self::InclusiveInt(.., n) => *n,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Set the index to the [`ConditionalStmtBlock`].
|
/// Set the index to the [`ConditionalExpr`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_index(&mut self, index: usize) {
|
pub fn set_index(&mut self, index: usize) {
|
||||||
match self {
|
match self {
|
||||||
|
@ -275,8 +275,8 @@ pub use tokenizer::{get_next_token, parse_string_literal};
|
|||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
pub use tokenizer::{
|
pub use tokenizer::{
|
||||||
InputStream, MultiInputsStream, Span, Token, TokenIterator, TokenizeState, TokenizerControl,
|
is_valid_function_name, is_valid_identifier, InputStream, MultiInputsStream, Span, Token,
|
||||||
TokenizerControlBlock,
|
TokenIterator, TokenizeState, TokenizerControl, TokenizerControlBlock,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
|
@ -250,6 +250,9 @@ pub struct Module {
|
|||||||
/// ID identifying the module.
|
/// ID identifying the module.
|
||||||
/// No ID if string is empty.
|
/// No ID if string is empty.
|
||||||
id: Identifier,
|
id: Identifier,
|
||||||
|
/// Module documentation.
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
doc: crate::SmartString,
|
||||||
/// Is this module internal?
|
/// Is this module internal?
|
||||||
pub(crate) internal: bool,
|
pub(crate) internal: bool,
|
||||||
/// Is this module part of a standard library?
|
/// Is this module part of a standard library?
|
||||||
@ -290,31 +293,27 @@ impl fmt::Debug for Module {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let mut d = f.debug_struct("Module");
|
let mut d = f.debug_struct("Module");
|
||||||
|
|
||||||
if !self.id.is_empty() {
|
d.field("id", &self.id)
|
||||||
d.field("id", &self.id);
|
.field(
|
||||||
}
|
|
||||||
if !self.modules.is_empty() {
|
|
||||||
d.field(
|
|
||||||
"modules",
|
"modules",
|
||||||
&self
|
&self
|
||||||
.modules
|
.modules
|
||||||
.keys()
|
.keys()
|
||||||
.map(|m| m.as_str())
|
.map(|m| m.as_str())
|
||||||
.collect::<BTreeSet<_>>(),
|
.collect::<BTreeSet<_>>(),
|
||||||
);
|
)
|
||||||
}
|
.field("vars", &self.variables)
|
||||||
if !self.variables.is_empty() {
|
.field(
|
||||||
d.field("vars", &self.variables);
|
|
||||||
}
|
|
||||||
if !self.functions.is_empty() {
|
|
||||||
d.field(
|
|
||||||
"functions",
|
"functions",
|
||||||
&self
|
&self
|
||||||
.iter_fn()
|
.iter_fn()
|
||||||
.map(|f| f.func.to_string())
|
.map(|f| f.func.to_string())
|
||||||
.collect::<BTreeSet<_>>(),
|
.collect::<BTreeSet<_>>(),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
d.field("doc", &self.doc);
|
||||||
|
|
||||||
d.finish()
|
d.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,6 +362,8 @@ impl Module {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: Identifier::new_const(),
|
id: Identifier::new_const(),
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
doc: crate::SmartString::new_const(),
|
||||||
internal: false,
|
internal: false,
|
||||||
standard: false,
|
standard: false,
|
||||||
custom_types: CustomTypesCollection::new(),
|
custom_types: CustomTypesCollection::new(),
|
||||||
@ -423,6 +424,7 @@ impl Module {
|
|||||||
self.id = id.into();
|
self.id = id.into();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the ID of the [`Module`].
|
/// Clear the ID of the [`Module`].
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
@ -441,10 +443,69 @@ impl Module {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the documentation of the [`Module`], if any.
|
||||||
|
/// Exported under the `metadata` feature only.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use rhai::Module;
|
||||||
|
/// let mut module = Module::new();
|
||||||
|
/// module.set_doc("//! This is my special module.");
|
||||||
|
/// assert_eq!(module.doc(), "//! This is my special module.");
|
||||||
|
/// ```
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn doc(&self) -> &str {
|
||||||
|
&self.doc
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the documentation of the [`Module`].
|
||||||
|
/// Exported under the `metadata` feature only.
|
||||||
|
///
|
||||||
|
/// If the string is empty, it is equivalent to clearing the documentation.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use rhai::Module;
|
||||||
|
/// let mut module = Module::new();
|
||||||
|
/// module.set_doc("//! This is my special module.");
|
||||||
|
/// assert_eq!(module.doc(), "//! This is my special module.");
|
||||||
|
/// ```
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn set_doc(&mut self, doc: impl Into<crate::SmartString>) -> &mut Self {
|
||||||
|
self.doc = doc.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear the documentation of the [`Module`].
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use rhai::Module;
|
||||||
|
/// let mut module = Module::new();
|
||||||
|
/// module.set_doc("//! This is my special module.");
|
||||||
|
/// assert_eq!(module.doc(), "//! This is my special module.");
|
||||||
|
/// module.clear_doc();
|
||||||
|
/// assert_eq!(module.doc(), "");
|
||||||
|
/// ```
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn clear_doc(&mut self) -> &mut Self {
|
||||||
|
self.doc.clear();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Clear the [`Module`].
|
/// Clear the [`Module`].
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.id.clear();
|
self.id.clear();
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
self.doc.clear();
|
||||||
self.internal = false;
|
self.internal = false;
|
||||||
self.standard = false;
|
self.standard = false;
|
||||||
self.custom_types.clear();
|
self.custom_types.clear();
|
||||||
@ -1563,6 +1624,15 @@ impl Module {
|
|||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
self.contains_indexed_global_functions = false;
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
if !other.doc.is_empty() {
|
||||||
|
if !self.doc.is_empty() {
|
||||||
|
self.doc.push('\n');
|
||||||
|
}
|
||||||
|
self.doc.push_str(&other.doc);
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,6 +1654,15 @@ impl Module {
|
|||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
self.contains_indexed_global_functions = false;
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
if !other.doc.is_empty() {
|
||||||
|
if !self.doc.is_empty() {
|
||||||
|
self.doc.push('\n');
|
||||||
|
}
|
||||||
|
self.doc.push_str(&other.doc);
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1614,6 +1693,15 @@ impl Module {
|
|||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
self.contains_indexed_global_functions = false;
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
if !other.doc.is_empty() {
|
||||||
|
if !self.doc.is_empty() {
|
||||||
|
self.doc.push('\n');
|
||||||
|
}
|
||||||
|
self.doc.push_str(&other.doc);
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1667,6 +1755,15 @@ impl Module {
|
|||||||
self.all_type_iterators.clear();
|
self.all_type_iterators.clear();
|
||||||
self.indexed = false;
|
self.indexed = false;
|
||||||
self.contains_indexed_global_functions = false;
|
self.contains_indexed_global_functions = false;
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
if !other.doc.is_empty() {
|
||||||
|
if !self.doc.is_empty() {
|
||||||
|
self.doc.push('\n');
|
||||||
|
}
|
||||||
|
self.doc.push_str(&other.doc);
|
||||||
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1978,6 +2075,9 @@ impl Module {
|
|||||||
|
|
||||||
module.set_id(ast.source_raw().clone());
|
module.set_id(ast.source_raw().clone());
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
module.set_doc(ast.doc());
|
||||||
|
|
||||||
module.build_index();
|
module.build_index();
|
||||||
|
|
||||||
Ok(module)
|
Ok(module)
|
||||||
|
@ -248,7 +248,7 @@ macro_rules! reg_range {
|
|||||||
$lib.update_fn_metadata_with_comments(_hash, [
|
$lib.update_fn_metadata_with_comments(_hash, [
|
||||||
concat!("from: ", stringify!($y)),
|
concat!("from: ", stringify!($y)),
|
||||||
concat!("to: ", stringify!($y)),
|
concat!("to: ", stringify!($y)),
|
||||||
concat!("Iterator<Item=", stringify!($y), ">"),
|
concat!("Iterator<", stringify!($y), ">"),
|
||||||
], [
|
], [
|
||||||
"/// Return an iterator over the exclusive range of `from..to`.",
|
"/// Return an iterator over the exclusive range of `from..to`.",
|
||||||
"/// The value `to` is never included.",
|
"/// The value `to` is never included.",
|
||||||
@ -282,7 +282,7 @@ macro_rules! reg_range {
|
|||||||
concat!("from: ", stringify!($y)),
|
concat!("from: ", stringify!($y)),
|
||||||
concat!("to: ", stringify!($y)),
|
concat!("to: ", stringify!($y)),
|
||||||
concat!("step: ", stringify!($y)),
|
concat!("step: ", stringify!($y)),
|
||||||
concat!("Iterator<Item=", stringify!($y), ">")
|
concat!("Iterator<", stringify!($y), ">")
|
||||||
], [
|
], [
|
||||||
"/// Return an iterator over the exclusive range of `from..to`, each iteration increasing by `step`.",
|
"/// Return an iterator over the exclusive range of `from..to`, each iteration increasing by `step`.",
|
||||||
"/// The value `to` is never included.",
|
"/// The value `to` is never included.",
|
||||||
@ -312,7 +312,7 @@ macro_rules! reg_range {
|
|||||||
$lib.update_fn_metadata_with_comments(_hash, [
|
$lib.update_fn_metadata_with_comments(_hash, [
|
||||||
concat!("range: Range<", stringify!($y), ">"),
|
concat!("range: Range<", stringify!($y), ">"),
|
||||||
concat!("step: ", stringify!($y)),
|
concat!("step: ", stringify!($y)),
|
||||||
concat!("Iterator<Item=", stringify!($y), ">")
|
concat!("Iterator<", stringify!($y), ">")
|
||||||
], [
|
], [
|
||||||
"/// Return an iterator over an exclusive range, each iteration increasing by `step`.",
|
"/// Return an iterator over an exclusive range, each iteration increasing by `step`.",
|
||||||
"///",
|
"///",
|
||||||
@ -388,7 +388,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &str", &range_type, "Iterator<Item=char>"],
|
["string: &str", &range_type, "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over an exclusive range of characters in the string.",
|
"/// Return an iterator over an exclusive range of characters in the string.",
|
||||||
"///",
|
"///",
|
||||||
@ -410,7 +410,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &str", &range_inclusive_type, "Iterator<Item=char>"],
|
["string: &str", &range_inclusive_type, "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over an inclusive range of characters in the string.",
|
"/// Return an iterator over an inclusive range of characters in the string.",
|
||||||
"///",
|
"///",
|
||||||
@ -428,7 +428,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &str", "start: INT", "len: INT", "Iterator<Item=char>"],
|
["string: &str", "start: INT", "len: INT", "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over a portion of characters in the string.",
|
"/// Return an iterator over a portion of characters in the string.",
|
||||||
"///",
|
"///",
|
||||||
@ -452,7 +452,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &str", "from: INT", "Iterator<Item=char>"],
|
["string: &str", "from: INT", "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over the characters in the string starting from the `start` position.",
|
"/// Return an iterator over the characters in the string starting from the `start` position.",
|
||||||
"///",
|
"///",
|
||||||
@ -474,7 +474,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &str", "Iterator<Item=char>"],
|
["string: &str", "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over the characters in the string.",
|
"/// Return an iterator over the characters in the string.",
|
||||||
"///",
|
"///",
|
||||||
@ -494,7 +494,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["string: &mut ImmutableString", "Iterator<Item=char>"],
|
["string: &mut ImmutableString", "Iterator<char>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over all the characters in the string.",
|
"/// Return an iterator over all the characters in the string.",
|
||||||
"///",
|
"///",
|
||||||
@ -520,7 +520,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: INT", &range_type, "Iterator<Item=bool>"],
|
["value: INT", &range_type, "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over an exclusive range of bits in the number.",
|
"/// Return an iterator over an exclusive range of bits in the number.",
|
||||||
"///",
|
"///",
|
||||||
@ -544,7 +544,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: INT", &range_inclusive_type, "Iterator<Item=bool>"],
|
["value: INT", &range_inclusive_type, "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over an inclusive range of bits in the number.",
|
"/// Return an iterator over an inclusive range of bits in the number.",
|
||||||
"///",
|
"///",
|
||||||
@ -564,7 +564,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: INT", "from: INT", "len: INT", "Iterator<Item=bool>"],
|
["value: INT", "from: INT", "len: INT", "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over a portion of bits in the number.",
|
"/// Return an iterator over a portion of bits in the number.",
|
||||||
"///",
|
"///",
|
||||||
@ -588,7 +588,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: INT", "from: INT", "Iterator<Item=bool>"],
|
["value: INT", "from: INT", "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over the bits in the number starting from the specified `start` position.",
|
"/// Return an iterator over the bits in the number starting from the specified `start` position.",
|
||||||
"///",
|
"///",
|
||||||
@ -610,7 +610,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: INT", "Iterator<Item=bool>"],
|
["value: INT", "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over all the bits in the number.",
|
"/// Return an iterator over all the bits in the number.",
|
||||||
"///",
|
"///",
|
||||||
@ -632,7 +632,7 @@ def_package! {
|
|||||||
#[cfg(feature = "metadata")]
|
#[cfg(feature = "metadata")]
|
||||||
lib.update_fn_metadata_with_comments(
|
lib.update_fn_metadata_with_comments(
|
||||||
_hash,
|
_hash,
|
||||||
["value: &mut INT", "Iterator<Item=bool>"],
|
["value: &mut INT", "Iterator<bool>"],
|
||||||
[
|
[
|
||||||
"/// Return an iterator over all the bits in the number.",
|
"/// Return an iterator over all the bits in the number.",
|
||||||
"///",
|
"///",
|
||||||
|
@ -174,6 +174,17 @@ fn collect_fn_metadata(
|
|||||||
.collect::<Array>()
|
.collect::<Array>()
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
if !func.comments.is_empty() {
|
||||||
|
map.insert(
|
||||||
|
dict.get("comments").expect(DICT).clone(),
|
||||||
|
func.comments
|
||||||
|
.iter()
|
||||||
|
.map(|s| Into::into(&**s))
|
||||||
|
.collect::<Array>()
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
@ -188,6 +199,8 @@ fn collect_fn_metadata(
|
|||||||
"private",
|
"private",
|
||||||
"is_anonymous",
|
"is_anonymous",
|
||||||
"params",
|
"params",
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
"comments",
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&s| s.into())
|
.map(|&s| s.into())
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#![cfg(feature = "metadata")]
|
#![cfg(feature = "metadata")]
|
||||||
|
|
||||||
use crate::module::{calc_native_fn_hash, FuncInfo};
|
use crate::module::{calc_native_fn_hash, FuncInfo};
|
||||||
use crate::{calc_fn_hash, Engine, AST};
|
use crate::{calc_fn_hash, Engine, SmartString, AST};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -158,6 +158,9 @@ impl<'a> From<&'a FuncInfo> for FnMetadata<'a> {
|
|||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct ModuleMetadata<'a> {
|
struct ModuleMetadata<'a> {
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
#[serde(skip_serializing_if = "SmartString::is_empty")]
|
||||||
|
pub doc: SmartString,
|
||||||
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
|
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
|
||||||
pub modules: BTreeMap<&'a str, Self>,
|
pub modules: BTreeMap<&'a str, Self>,
|
||||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
@ -168,6 +171,8 @@ impl ModuleMetadata<'_> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
doc: SmartString::new_const(),
|
||||||
modules: BTreeMap::new(),
|
modules: BTreeMap::new(),
|
||||||
functions: Vec::new(),
|
functions: Vec::new(),
|
||||||
}
|
}
|
||||||
@ -180,6 +185,7 @@ impl<'a> From<&'a crate::Module> for ModuleMetadata<'a> {
|
|||||||
functions.sort();
|
functions.sort();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
doc: module.doc().into(),
|
||||||
modules: module
|
modules: module
|
||||||
.iter_sub_modules()
|
.iter_sub_modules()
|
||||||
.map(|(name, m)| (name, m.as_ref().into()))
|
.map(|(name, m)| (name, m.as_ref().into()))
|
||||||
@ -240,6 +246,11 @@ impl Engine {
|
|||||||
|
|
||||||
global.functions.sort();
|
global.functions.sort();
|
||||||
|
|
||||||
|
#[cfg(feature = "metadata")]
|
||||||
|
{
|
||||||
|
global.doc = ast.doc().into();
|
||||||
|
}
|
||||||
|
|
||||||
serde_json::to_string_pretty(&global)
|
serde_json::to_string_pretty(&global)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2179,7 +2179,7 @@ fn get_identifier(
|
|||||||
Some((Token::Identifier(identifier.into()), start_pos))
|
Some((Token::Identifier(identifier.into()), start_pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is this keyword allowed as a function?
|
/// Is a keyword allowed as a function?
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_keyword_function(name: &str) -> bool {
|
pub fn is_keyword_function(name: &str) -> bool {
|
||||||
@ -2194,7 +2194,8 @@ pub fn is_keyword_function(name: &str) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is a text string a valid identifier?
|
/// _(internals)_ Is a text string a valid identifier?
|
||||||
|
/// Exported under the `internals` feature only.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
|
pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
|
||||||
let mut first_alphabetic = false;
|
let mut first_alphabetic = false;
|
||||||
@ -2212,7 +2213,8 @@ pub fn is_valid_identifier(name: impl Iterator<Item = char>) -> bool {
|
|||||||
first_alphabetic
|
first_alphabetic
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is a text string a valid script-defined function name?
|
/// _(internals)_ Is a text string a valid script-defined function name?
|
||||||
|
/// Exported under the `internals` feature only.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_valid_function_name(name: &str) -> bool {
|
pub fn is_valid_function_name(name: &str) -> bool {
|
||||||
|
Loading…
Reference in New Issue
Block a user