commit
91963d10dc
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- plugins
|
||||||
pull_request: {}
|
pull_request: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -76,3 +77,25 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
command: build
|
command: build
|
||||||
args: --manifest-path=no_std/no_std_test/Cargo.toml ${{matrix.flags}}
|
args: --manifest-path=no_std/no_std_test/Cargo.toml ${{matrix.flags}}
|
||||||
|
codegen_build:
|
||||||
|
name: Codegen Build
|
||||||
|
runs-on: ${{matrix.os}}
|
||||||
|
continue-on-error: ${{matrix.experimental}}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- {toolchain: nightly, os: ubuntu-latest, experimental: false, flags: ""}
|
||||||
|
- {toolchain: nightly, os: windows-latest, experimental: false, flags: ""}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Setup Toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: ${{matrix.toolchain}}
|
||||||
|
override: true
|
||||||
|
- name: Build Project
|
||||||
|
uses: actions-rs/cargo@v1
|
||||||
|
with:
|
||||||
|
command: test
|
||||||
|
args: --manifest-path=codegen/Cargo.toml ${{matrix.flags}}
|
||||||
|
@ -17,8 +17,8 @@ keywords = [ "scripting" ]
|
|||||||
categories = [ "no-std", "embedded", "wasm", "parser-implementations" ]
|
categories = [ "no-std", "embedded", "wasm", "parser-implementations" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
num-traits = { version = "0.2.11", default-features = false }
|
|
||||||
smallvec = { version = "1.4.1", default-features = false }
|
smallvec = { version = "1.4.1", default-features = false }
|
||||||
|
rhai_codegen = { version = "0.1", path = "codegen" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
#default = ["unchecked", "sync", "no_optimize", "no_float", "only_i32", "no_index", "no_object", "no_function", "no_module"]
|
#default = ["unchecked", "sync", "no_optimize", "no_float", "only_i32", "no_index", "no_object", "no_function", "no_module"]
|
||||||
@ -51,6 +51,11 @@ version = "0.2.1"
|
|||||||
default_features = false
|
default_features = false
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.num-traits]
|
||||||
|
version = "0.2.11"
|
||||||
|
default-features = false
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dependencies.core-error]
|
[dependencies.core-error]
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
default_features = false
|
default_features = false
|
||||||
|
@ -17,6 +17,7 @@ Supported targets and builds
|
|||||||
* All common CPU targets for Windows, Linux and MacOS.
|
* All common CPU targets for Windows, Linux and MacOS.
|
||||||
* WebAssembly (WASM)
|
* WebAssembly (WASM)
|
||||||
* `no-std`
|
* `no-std`
|
||||||
|
* Minimum Rust version 1.45
|
||||||
|
|
||||||
Standard features
|
Standard features
|
||||||
-----------------
|
-----------------
|
||||||
@ -37,6 +38,7 @@ Standard features
|
|||||||
* Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature).
|
* Serialization/deserialization support via [serde](https://crates.io/crates/serde) (requires the `serde` feature).
|
||||||
* Scripts are [optimized](https://schungx.github.io/rhai/engine/optimize.html) (useful for template-based machine-generated scripts) for repeated evaluations.
|
* Scripts are [optimized](https://schungx.github.io/rhai/engine/optimize.html) (useful for template-based machine-generated scripts) for repeated evaluations.
|
||||||
* Support for [minimal builds](https://schungx.github.io/rhai/start/builds/minimal.html) by excluding unneeded language [features](https://schungx.github.io/rhai/start/features.html).
|
* Support for [minimal builds](https://schungx.github.io/rhai/start/builds/minimal.html) by excluding unneeded language [features](https://schungx.github.io/rhai/start/features.html).
|
||||||
|
* Easy custom API development via [plugins](https://schungx.github.io/rhai/plugins/index.html) system powered by procedural macros.
|
||||||
|
|
||||||
Protection against attacks
|
Protection against attacks
|
||||||
--------------------------
|
--------------------------
|
||||||
|
18
RELEASES.md
18
RELEASES.md
@ -1,6 +1,15 @@
|
|||||||
Rhai Release Notes
|
Rhai Release Notes
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
Version 0.19.0
|
||||||
|
==============
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Plugins support via procedural macros.
|
||||||
|
|
||||||
|
|
||||||
Version 0.18.3
|
Version 0.18.3
|
||||||
==============
|
==============
|
||||||
|
|
||||||
@ -12,6 +21,15 @@ Bug fixes
|
|||||||
* Closures that capture now work under `no_object`.
|
* Closures that capture now work under `no_object`.
|
||||||
|
|
||||||
|
|
||||||
|
Version 0.18.2
|
||||||
|
==============
|
||||||
|
|
||||||
|
New features
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Adds `Module::combine_flatten` to combine two modules while flattening to the root level.
|
||||||
|
|
||||||
|
|
||||||
Version 0.18.2
|
Version 0.18.2
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
21
codegen/Cargo.toml
Normal file
21
codegen/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "rhai_codegen"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
authors = ["jhwgh1968", "Stephen Chung"]
|
||||||
|
description = "Proceducral macro support package for Rhai, a scripting language for Rust"
|
||||||
|
homepage = "https://github.com/jonathandturner/rhai"
|
||||||
|
repository = "https://github.com/jonathandturner/rhai"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
rhai = { path = ".." }
|
||||||
|
trybuild = "1"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1"
|
||||||
|
syn = { version = "1", features = ["full", "parsing", "printing", "proc-macro", "extra-traits"] }
|
||||||
|
quote = "1"
|
117
codegen/src/attrs.rs
Normal file
117
codegen/src/attrs.rs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
use syn::{parse::ParseStream, parse::Parser, spanned::Spanned};
|
||||||
|
|
||||||
|
pub trait ExportedParams: Sized {
|
||||||
|
fn parse_stream(args: ParseStream) -> syn::Result<Self>;
|
||||||
|
fn no_attrs() -> Self;
|
||||||
|
fn from_info(info: ExportInfo) -> syn::Result<Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AttrItem {
|
||||||
|
pub key: proc_macro2::Ident,
|
||||||
|
pub value: Option<syn::LitStr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ExportInfo {
|
||||||
|
pub item_span: proc_macro2::Span,
|
||||||
|
pub items: Vec<AttrItem>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_attr_items(args: ParseStream) -> syn::Result<ExportInfo> {
|
||||||
|
if args.is_empty() {
|
||||||
|
return Ok(ExportInfo { item_span: args.span(), items: Vec::new()});
|
||||||
|
}
|
||||||
|
let arg_list = args
|
||||||
|
.call(syn::punctuated::Punctuated::<syn::Expr, syn::Token![,]>::parse_separated_nonempty)?;
|
||||||
|
|
||||||
|
parse_punctuated_items(arg_list)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_punctuated_items(
|
||||||
|
arg_list: syn::punctuated::Punctuated<syn::Expr, syn::Token![,]>,
|
||||||
|
) -> syn::Result<ExportInfo> {
|
||||||
|
let list_span = arg_list.span();
|
||||||
|
|
||||||
|
let mut attrs: Vec<AttrItem> = Vec::new();
|
||||||
|
for arg in arg_list {
|
||||||
|
let (key, value) = match arg {
|
||||||
|
syn::Expr::Assign(syn::ExprAssign {
|
||||||
|
ref left,
|
||||||
|
ref right,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
|
let attr_name: syn::Ident = match left.as_ref() {
|
||||||
|
syn::Expr::Path(syn::ExprPath {
|
||||||
|
path: attr_path, ..
|
||||||
|
}) => attr_path.get_ident().cloned().ok_or_else(|| {
|
||||||
|
syn::Error::new(attr_path.span(), "expecting attribute name")
|
||||||
|
})?,
|
||||||
|
x => return Err(syn::Error::new(x.span(), "expecting attribute name")),
|
||||||
|
};
|
||||||
|
let attr_value = match right.as_ref() {
|
||||||
|
syn::Expr::Lit(syn::ExprLit {
|
||||||
|
lit: syn::Lit::Str(string),
|
||||||
|
..
|
||||||
|
}) => string.clone(),
|
||||||
|
x => return Err(syn::Error::new(x.span(), "expecting string literal")),
|
||||||
|
};
|
||||||
|
(attr_name, Some(attr_value))
|
||||||
|
}
|
||||||
|
syn::Expr::Path(syn::ExprPath {
|
||||||
|
path: attr_path, ..
|
||||||
|
}) => attr_path
|
||||||
|
.get_ident()
|
||||||
|
.cloned()
|
||||||
|
.map(|a| (a, None))
|
||||||
|
.ok_or_else(|| syn::Error::new(attr_path.span(), "expecting attribute name"))?,
|
||||||
|
x => return Err(syn::Error::new(x.span(), "expecting identifier")),
|
||||||
|
};
|
||||||
|
attrs.push(AttrItem { key, value });
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ExportInfo { item_span: list_span, items: attrs })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn outer_item_attributes<T: ExportedParams>(
|
||||||
|
args: proc_macro2::TokenStream,
|
||||||
|
_attr_name: &str,
|
||||||
|
) -> syn::Result<T> {
|
||||||
|
if args.is_empty() {
|
||||||
|
return Ok(T::no_attrs());
|
||||||
|
}
|
||||||
|
|
||||||
|
let parser = syn::punctuated::Punctuated::<syn::Expr, syn::Token![,]>::parse_separated_nonempty;
|
||||||
|
let arg_list = parser.parse2(args)?;
|
||||||
|
|
||||||
|
let export_info = parse_punctuated_items(arg_list)?;
|
||||||
|
T::from_info(export_info)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn inner_item_attributes<T: ExportedParams>(
|
||||||
|
attrs: &mut Vec<syn::Attribute>,
|
||||||
|
attr_name: &str,
|
||||||
|
) -> syn::Result<T> {
|
||||||
|
// Find the #[rhai_fn] attribute which will turn be read for the function parameters.
|
||||||
|
if let Some(rhai_fn_idx) = attrs
|
||||||
|
.iter()
|
||||||
|
.position(|a| a.path.get_ident().map(|i| *i == attr_name).unwrap_or(false))
|
||||||
|
{
|
||||||
|
let rhai_fn_attr = attrs.remove(rhai_fn_idx);
|
||||||
|
rhai_fn_attr.parse_args_with(T::parse_stream)
|
||||||
|
} else {
|
||||||
|
Ok(T::no_attrs())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn deny_cfg_attr(attrs: &Vec<syn::Attribute>) -> syn::Result<()> {
|
||||||
|
if let Some(cfg_attr) = attrs
|
||||||
|
.iter()
|
||||||
|
.find(|a| a.path.get_ident().map(|i| *i == "cfg").unwrap_or(false))
|
||||||
|
{
|
||||||
|
Err(syn::Error::new(
|
||||||
|
cfg_attr.span(),
|
||||||
|
"cfg attributes not allowed on this item",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
1050
codegen/src/function.rs
Normal file
1050
codegen/src/function.rs
Normal file
File diff suppressed because it is too large
Load Diff
172
codegen/src/lib.rs
Normal file
172
codegen/src/lib.rs
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
//!
|
||||||
|
//! This crate contains procedural macros to make creating Rhai modules much easier.
|
||||||
|
//!
|
||||||
|
//! # Exporting a Macro to Rhai
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use rhai::{EvalAltResult, FLOAT};
|
||||||
|
//! use rhai::plugin::*;
|
||||||
|
//! use rhai::module_resolvers::*;
|
||||||
|
//!
|
||||||
|
//! #[rhai::export_module]
|
||||||
|
//! pub mod advanced_math {
|
||||||
|
//! use rhai::FLOAT;
|
||||||
|
//!
|
||||||
|
//! pub const MYSTIC_NUMBER: FLOAT = 42.0 as FLOAT;
|
||||||
|
//!
|
||||||
|
//! pub fn euclidean_distance(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
|
||||||
|
//! ((y2 - y1).abs().powf(2.0) + (x2 -x1).abs().powf(2.0)).sqrt()
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
//! let mut engine = Engine::new();
|
||||||
|
//! let m = rhai::exported_module!(advanced_math);
|
||||||
|
//! let mut r = StaticModuleResolver::new();
|
||||||
|
//! r.insert("Math::Advanced".to_string(), m);
|
||||||
|
//! engine.set_module_resolver(Some(r));
|
||||||
|
//!
|
||||||
|
//! assert_eq!(engine.eval::<FLOAT>(
|
||||||
|
//! r#"import "Math::Advanced" as math;
|
||||||
|
//! let m = math::MYSTIC_NUMBER;
|
||||||
|
//! let x = math::euclidean_distance(0.0, 1.0, 0.0, m);
|
||||||
|
//! x"#)?, 41.0);
|
||||||
|
//! Ok(())
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! # Exporting a Function to a Rhai Module
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use rhai::{EvalAltResult, FLOAT, Module, RegisterFn};
|
||||||
|
//! use rhai::plugin::*;
|
||||||
|
//! use rhai::module_resolvers::*;
|
||||||
|
//!
|
||||||
|
//! #[rhai::export_fn]
|
||||||
|
//! pub fn distance_function(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
|
||||||
|
//! ((y2 - y1).abs().powf(2.0) + (x2 -x1).abs().powf(2.0)).sqrt()
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
//!
|
||||||
|
//! let mut engine = Engine::new();
|
||||||
|
//! engine.register_fn("get_mystic_number", || { 42 as FLOAT });
|
||||||
|
//! let mut m = Module::new();
|
||||||
|
//! rhai::set_exported_fn!(m, "euclidean_distance", distance_function);
|
||||||
|
//! let mut r = StaticModuleResolver::new();
|
||||||
|
//! r.insert("Math::Advanced".to_string(), m);
|
||||||
|
//! engine.set_module_resolver(Some(r));
|
||||||
|
//!
|
||||||
|
//! assert_eq!(engine.eval::<FLOAT>(
|
||||||
|
//! r#"import "Math::Advanced" as math;
|
||||||
|
//! let m = get_mystic_number();
|
||||||
|
//! let x = math::euclidean_distance(0.0, 1.0, 0.0, m);
|
||||||
|
//! x"#)?, 41.0);
|
||||||
|
//! Ok(())
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! # Exporting a Function to an Engine
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use rhai::{EvalAltResult, FLOAT, Module, RegisterFn};
|
||||||
|
//! use rhai::plugin::*;
|
||||||
|
//! use rhai::module_resolvers::*;
|
||||||
|
//!
|
||||||
|
//! #[rhai::export_fn]
|
||||||
|
//! pub fn distance_function(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
|
||||||
|
//! ((y2 - y1).abs().powf(2.0) + (x2 -x1).abs().powf(2.0)).sqrt()
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
//!
|
||||||
|
//! let mut engine = Engine::new();
|
||||||
|
//! engine.register_fn("get_mystic_number", || { 42 as FLOAT });
|
||||||
|
//! rhai::register_exported_fn!(engine, "euclidean_distance", distance_function);
|
||||||
|
//!
|
||||||
|
//! assert_eq!(engine.eval::<FLOAT>(
|
||||||
|
//! r#"let m = get_mystic_number();
|
||||||
|
//! let x = euclidean_distance(0.0, 1.0, 0.0, m);
|
||||||
|
//! x"#)?, 41.0);
|
||||||
|
//! Ok(())
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
|
||||||
|
use quote::quote;
|
||||||
|
use syn::parse_macro_input;
|
||||||
|
|
||||||
|
mod attrs;
|
||||||
|
mod function;
|
||||||
|
mod module;
|
||||||
|
mod register;
|
||||||
|
mod rhai_module;
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn export_fn(
|
||||||
|
args: proc_macro::TokenStream,
|
||||||
|
input: proc_macro::TokenStream,
|
||||||
|
) -> proc_macro::TokenStream {
|
||||||
|
let mut output = proc_macro2::TokenStream::from(input.clone());
|
||||||
|
|
||||||
|
let parsed_params = match crate::attrs::outer_item_attributes(args.into(), "export_fn") {
|
||||||
|
Ok(args) => args,
|
||||||
|
Err(err) => return proc_macro::TokenStream::from(err.to_compile_error()),
|
||||||
|
};
|
||||||
|
let mut function_def = parse_macro_input!(input as function::ExportedFn);
|
||||||
|
if let Err(e) = function_def.set_params(parsed_params) {
|
||||||
|
return e.to_compile_error().into();
|
||||||
|
}
|
||||||
|
|
||||||
|
output.extend(function_def.generate());
|
||||||
|
proc_macro::TokenStream::from(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro_attribute]
|
||||||
|
pub fn export_module(
|
||||||
|
_args: proc_macro::TokenStream,
|
||||||
|
input: proc_macro::TokenStream,
|
||||||
|
) -> proc_macro::TokenStream {
|
||||||
|
let module_def = parse_macro_input!(input as module::Module);
|
||||||
|
let tokens = module_def.generate();
|
||||||
|
proc_macro::TokenStream::from(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn exported_module(module_path: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
let module_path = parse_macro_input!(module_path as syn::Path);
|
||||||
|
let tokens = quote::quote! {
|
||||||
|
#module_path::rhai_module_generate()
|
||||||
|
};
|
||||||
|
proc_macro::TokenStream::from(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn register_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
let (engine_expr, export_name, rust_modpath) = match crate::register::parse_register_macro(args)
|
||||||
|
{
|
||||||
|
Ok(triple) => triple,
|
||||||
|
Err(e) => return e.to_compile_error().into(),
|
||||||
|
};
|
||||||
|
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
||||||
|
let tokens = quote! {
|
||||||
|
#engine_expr.register_result_fn(&(#export_name), #gen_mod_path::dynamic_result_fn);
|
||||||
|
};
|
||||||
|
proc_macro::TokenStream::from(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn set_exported_fn(args: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
let (module_expr, export_name, rust_modpath) = match crate::register::parse_register_macro(args)
|
||||||
|
{
|
||||||
|
Ok(triple) => triple,
|
||||||
|
Err(e) => return e.to_compile_error().into(),
|
||||||
|
};
|
||||||
|
let gen_mod_path = crate::register::generated_module_path(&rust_modpath);
|
||||||
|
let tokens = quote! {
|
||||||
|
#module_expr.set_fn(#export_name, FnAccess::Public,
|
||||||
|
#gen_mod_path::token_input_types().as_ref(),
|
||||||
|
#gen_mod_path::token_callable());
|
||||||
|
};
|
||||||
|
proc_macro::TokenStream::from(tokens)
|
||||||
|
}
|
1538
codegen/src/module.rs
Normal file
1538
codegen/src/module.rs
Normal file
File diff suppressed because it is too large
Load Diff
49
codegen/src/register.rs
Normal file
49
codegen/src/register.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use quote::{quote, quote_spanned};
|
||||||
|
use syn::{parse::Parser, spanned::Spanned};
|
||||||
|
|
||||||
|
pub(crate) fn generated_module_path(
|
||||||
|
fn_path: &syn::Path,
|
||||||
|
) -> syn::punctuated::Punctuated<syn::PathSegment, syn::Token![::]> {
|
||||||
|
let mut g = fn_path.clone().segments;
|
||||||
|
g.pop();
|
||||||
|
let ident = syn::Ident::new(
|
||||||
|
&format!("rhai_fn_{}", fn_path.segments.last().unwrap().ident),
|
||||||
|
fn_path.span(),
|
||||||
|
);
|
||||||
|
g.push_value(syn::PathSegment {
|
||||||
|
ident,
|
||||||
|
arguments: syn::PathArguments::None,
|
||||||
|
});
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterMacroInput = (syn::Expr, proc_macro2::TokenStream, syn::Path);
|
||||||
|
pub fn parse_register_macro(
|
||||||
|
args: proc_macro::TokenStream,
|
||||||
|
) -> Result<RegisterMacroInput, syn::Error> {
|
||||||
|
let parser = syn::punctuated::Punctuated::<syn::Expr, syn::Token![,]>::parse_separated_nonempty;
|
||||||
|
let args = parser.parse(args).unwrap();
|
||||||
|
let arg_span = args.span();
|
||||||
|
let mut items: Vec<syn::Expr> = args.into_iter().collect();
|
||||||
|
if items.len() != 3 {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
arg_span,
|
||||||
|
"this macro requires three arguments",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let export_name = match &items[1] {
|
||||||
|
syn::Expr::Lit(litstr) => quote_spanned!(items[1].span()=>
|
||||||
|
#litstr.to_string()),
|
||||||
|
expr => quote! { #expr },
|
||||||
|
};
|
||||||
|
let rust_modpath = if let syn::Expr::Path(ref path) = &items[2] {
|
||||||
|
path.path.clone()
|
||||||
|
} else {
|
||||||
|
return Err(syn::Error::new(
|
||||||
|
items[2].span(),
|
||||||
|
"third argument must be a function name",
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let module = items.remove(0);
|
||||||
|
Ok((module, export_name, rust_modpath))
|
||||||
|
}
|
208
codegen/src/rhai_module.rs
Normal file
208
codegen/src/rhai_module.rs
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use quote::{quote, ToTokens};
|
||||||
|
|
||||||
|
use crate::function::ExportedFn;
|
||||||
|
use crate::module::Module;
|
||||||
|
|
||||||
|
pub(crate) type ExportedConst = (String, syn::Expr);
|
||||||
|
|
||||||
|
pub(crate) fn generate_body(
|
||||||
|
fns: &[ExportedFn],
|
||||||
|
consts: &[ExportedConst],
|
||||||
|
submodules: &[Module],
|
||||||
|
) -> proc_macro2::TokenStream {
|
||||||
|
let mut set_fn_stmts: Vec<syn::Stmt> = Vec::new();
|
||||||
|
let mut set_const_stmts: Vec<syn::Stmt> = Vec::new();
|
||||||
|
let mut add_mod_blocks: Vec<syn::ExprBlock> = Vec::new();
|
||||||
|
let str_type_path = syn::parse2::<syn::Path>(quote! { str }).unwrap();
|
||||||
|
|
||||||
|
for (const_name, const_expr) in consts {
|
||||||
|
let const_literal = syn::LitStr::new(&const_name, proc_macro2::Span::call_site());
|
||||||
|
set_const_stmts.push(
|
||||||
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
|
m.set_var(#const_literal, #const_expr);
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for itemmod in submodules {
|
||||||
|
if itemmod.skipped() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let module_name: &syn::Ident = itemmod.module_name().unwrap();
|
||||||
|
let exported_name: syn::LitStr = if let Some(name) = itemmod.exported_name() {
|
||||||
|
syn::LitStr::new(&name, proc_macro2::Span::call_site())
|
||||||
|
} else {
|
||||||
|
syn::LitStr::new(&module_name.to_string(), proc_macro2::Span::call_site())
|
||||||
|
};
|
||||||
|
let cfg_attrs: Vec<&syn::Attribute> = itemmod
|
||||||
|
.attrs()
|
||||||
|
.unwrap()
|
||||||
|
.iter()
|
||||||
|
.filter(|&a| a.path.get_ident().map(|i| *i == "cfg").unwrap_or(false))
|
||||||
|
.collect();
|
||||||
|
add_mod_blocks.push(
|
||||||
|
syn::parse2::<syn::ExprBlock>(quote! {
|
||||||
|
#(#cfg_attrs)* {
|
||||||
|
m.set_sub_module(#exported_name, self::#module_name::rhai_module_generate());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: these are token streams, because reparsing messes up "> >" vs ">>"
|
||||||
|
let mut gen_fn_tokens: Vec<proc_macro2::TokenStream> = Vec::new();
|
||||||
|
for function in fns {
|
||||||
|
if function.skipped() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let fn_token_name = syn::Ident::new(
|
||||||
|
&format!("{}_token", function.name().to_string()),
|
||||||
|
function.name().span(),
|
||||||
|
);
|
||||||
|
let reg_name = function
|
||||||
|
.params()
|
||||||
|
.name
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_else(|| function.name().to_string());
|
||||||
|
let fn_literal = syn::LitStr::new(®_name, proc_macro2::Span::call_site());
|
||||||
|
let fn_input_types: Vec<syn::Expr> = function
|
||||||
|
.arg_list()
|
||||||
|
.map(|fnarg| match fnarg {
|
||||||
|
syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"),
|
||||||
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
||||||
|
let arg_type = match ty.as_ref() {
|
||||||
|
syn::Type::Reference(syn::TypeReference {
|
||||||
|
mutability: None,
|
||||||
|
ref elem,
|
||||||
|
..
|
||||||
|
}) => match elem.as_ref() {
|
||||||
|
syn::Type::Path(ref p) if p.path == str_type_path => {
|
||||||
|
syn::parse2::<syn::Type>(quote! {
|
||||||
|
ImmutableString })
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
_ => panic!("internal error: non-string shared reference!?"),
|
||||||
|
},
|
||||||
|
syn::Type::Reference(syn::TypeReference {
|
||||||
|
mutability: Some(_),
|
||||||
|
ref elem,
|
||||||
|
..
|
||||||
|
}) => match elem.as_ref() {
|
||||||
|
syn::Type::Path(ref p) => syn::parse2::<syn::Type>(quote! {
|
||||||
|
#p })
|
||||||
|
.unwrap(),
|
||||||
|
_ => panic!("internal error: non-string shared reference!?"),
|
||||||
|
},
|
||||||
|
t => t.clone(),
|
||||||
|
};
|
||||||
|
syn::parse2::<syn::Expr>(quote! {
|
||||||
|
core::any::TypeId::of::<#arg_type>()})
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
set_fn_stmts.push(
|
||||||
|
syn::parse2::<syn::Stmt>(quote! {
|
||||||
|
m.set_fn(#fn_literal, FnAccess::Public, &[#(#fn_input_types),*],
|
||||||
|
CallableFunction::from_plugin(#fn_token_name()));
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
gen_fn_tokens.push(quote! {
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
struct #fn_token_name();
|
||||||
|
});
|
||||||
|
gen_fn_tokens.push(function.generate_impl(&fn_token_name.to_string()));
|
||||||
|
gen_fn_tokens.push(function.generate_callable(&fn_token_name.to_string()));
|
||||||
|
gen_fn_tokens.push(function.generate_input_types(&fn_token_name.to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut generate_fncall = syn::parse2::<syn::ItemMod>(quote! {
|
||||||
|
pub mod generate_info {
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use super::*;
|
||||||
|
#[allow(unused_mut)]
|
||||||
|
pub fn rhai_module_generate() -> Module {
|
||||||
|
let mut m = Module::new();
|
||||||
|
#(#set_fn_stmts)*
|
||||||
|
#(#set_const_stmts)*
|
||||||
|
#(#add_mod_blocks)*
|
||||||
|
m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let (_, generate_call_content) = generate_fncall.content.take().unwrap();
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#(#generate_call_content)*
|
||||||
|
#(#gen_fn_tokens)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
|
||||||
|
let mut renames = HashMap::<String, proc_macro2::Span>::new();
|
||||||
|
let mut names = HashMap::<String, proc_macro2::Span>::new();
|
||||||
|
for itemfn in fns.iter() {
|
||||||
|
if let Some(ref name) = itemfn.params().name {
|
||||||
|
let current_span = itemfn.params().span.as_ref().unwrap();
|
||||||
|
let key = itemfn.arg_list().fold(name.clone(), |mut argstr, fnarg| {
|
||||||
|
let type_string: String = match fnarg {
|
||||||
|
syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"),
|
||||||
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
||||||
|
ty.as_ref().to_token_stream().to_string()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
argstr.push('.');
|
||||||
|
argstr.push_str(&type_string);
|
||||||
|
argstr
|
||||||
|
});
|
||||||
|
if let Some(other_span) = renames.insert(key, *current_span) {
|
||||||
|
let mut err = syn::Error::new(
|
||||||
|
*current_span,
|
||||||
|
format!("duplicate Rhai signature for '{}'", &name),
|
||||||
|
);
|
||||||
|
err.combine(syn::Error::new(
|
||||||
|
other_span,
|
||||||
|
format!("duplicated function renamed '{}'", &name),
|
||||||
|
));
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let ident = itemfn.name();
|
||||||
|
if let Some(other_span) = names.insert(ident.to_string(), ident.span()) {
|
||||||
|
let mut err = syn::Error::new(
|
||||||
|
ident.span(),
|
||||||
|
format!("duplicate function '{}'", ident.to_string()),
|
||||||
|
);
|
||||||
|
err.combine(syn::Error::new(
|
||||||
|
other_span,
|
||||||
|
format!("duplicated function '{}'", ident.to_string()),
|
||||||
|
));
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (new_name, attr_span) in renames.drain() {
|
||||||
|
let new_name = new_name.split('.').next().unwrap();
|
||||||
|
if let Some(fn_span) = names.get(new_name) {
|
||||||
|
let mut err = syn::Error::new(
|
||||||
|
attr_span,
|
||||||
|
format!("duplicate Rhai signature for '{}'", &new_name),
|
||||||
|
);
|
||||||
|
err.combine(syn::Error::new(
|
||||||
|
*fn_span,
|
||||||
|
format!("duplicated function '{}'", &new_name),
|
||||||
|
));
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
202
codegen/tests/test_functions.rs
Normal file
202
codegen/tests/test_functions.rs
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
use rhai::module_resolvers::*;
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::{Engine, EvalAltResult, Module, RegisterFn, FLOAT};
|
||||||
|
|
||||||
|
pub mod raw_fn {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn distance_function(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
|
||||||
|
((y2 - y1).abs().powf(2.0) + (x2 - x1).abs().powf(2.0)).sqrt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_fn_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.register_fn("get_mystic_number", || 42 as FLOAT);
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai::set_exported_fn!(
|
||||||
|
m,
|
||||||
|
"euclidean_distance".to_string(),
|
||||||
|
raw_fn::distance_function
|
||||||
|
);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let x = math::euclidean_distance(0.0, 1.0, 0.0, get_mystic_number()); x"#
|
||||||
|
)?,
|
||||||
|
41.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod raw_fn_mut {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn add_in_place(f1: &mut FLOAT, f2: FLOAT) {
|
||||||
|
*f1 += f2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_fn_mut_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.register_fn("get_mystic_number", || 42 as FLOAT);
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai::set_exported_fn!(m, "add_in_place", raw_fn_mut::add_in_place);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let x = get_mystic_number();
|
||||||
|
math::add_in_place(x, 1.0);
|
||||||
|
x"#
|
||||||
|
)?,
|
||||||
|
43.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod raw_fn_str {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn write_out_str(message: &str) -> bool {
|
||||||
|
eprintln!("{}", message);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_fn_str_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.register_fn("get_mystic_number", || 42 as FLOAT);
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai::set_exported_fn!(m, "write_out_str", raw_fn_str::write_out_str);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Host::IO".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<bool>(
|
||||||
|
r#"import "Host::IO" as io;
|
||||||
|
let x = io::write_out_str("hello world!");
|
||||||
|
x"#
|
||||||
|
)?,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod mut_opaque_ref {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::INT;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StatusMessage {
|
||||||
|
os_code: Option<INT>,
|
||||||
|
message: String,
|
||||||
|
is_ok: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn new_message(is_ok: bool, message: &str) -> StatusMessage {
|
||||||
|
StatusMessage {
|
||||||
|
is_ok,
|
||||||
|
os_code: None,
|
||||||
|
message: message.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn new_os_message(is_ok: bool, os_code: INT) -> StatusMessage {
|
||||||
|
StatusMessage {
|
||||||
|
is_ok,
|
||||||
|
os_code: Some(os_code),
|
||||||
|
message: format!("OS Code {}", os_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn write_out_message(message: &mut StatusMessage) -> bool {
|
||||||
|
eprintln!("{}", message.message);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mut_opaque_ref_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai::set_exported_fn!(m, "new_message", mut_opaque_ref::new_message);
|
||||||
|
rhai::set_exported_fn!(m, "new_os_message", mut_opaque_ref::new_os_message);
|
||||||
|
rhai::set_exported_fn!(m, "write_out_message", mut_opaque_ref::write_out_message);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Host::Msg".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<bool>(
|
||||||
|
r#"import "Host::Msg" as msg;
|
||||||
|
let message1 = msg::new_message(true, "it worked");
|
||||||
|
let ok1 = msg::write_out_message(message1);
|
||||||
|
let message2 = msg::new_os_message(true, 0);
|
||||||
|
let ok2 = msg::write_out_message(message2);
|
||||||
|
ok1 && ok2"#
|
||||||
|
)?,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod raw_returning_fn {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
pub fn distance_function(
|
||||||
|
x1: FLOAT,
|
||||||
|
y1: FLOAT,
|
||||||
|
x2: FLOAT,
|
||||||
|
y2: FLOAT,
|
||||||
|
) -> Result<rhai::Dynamic, Box<rhai::EvalAltResult>> {
|
||||||
|
Ok(Dynamic::from(
|
||||||
|
((y2 - y1).abs().powf(2.0) + (x2 - x1).abs().powf(2.0)).sqrt(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_returning_fn_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.register_fn("get_mystic_number", || 42 as FLOAT);
|
||||||
|
let mut m = Module::new();
|
||||||
|
rhai::set_exported_fn!(
|
||||||
|
m,
|
||||||
|
"euclidean_distance".to_string(),
|
||||||
|
raw_returning_fn::distance_function
|
||||||
|
);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let x = math::euclidean_distance(0.0, 1.0, 0.0, get_mystic_number()); x"#
|
||||||
|
)?,
|
||||||
|
41.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
223
codegen/tests/test_modules.rs
Normal file
223
codegen/tests/test_modules.rs
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
use rhai::module_resolvers::*;
|
||||||
|
use rhai::{Array, Engine, EvalAltResult, RegisterFn, FLOAT, INT};
|
||||||
|
|
||||||
|
pub mod empty_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod EmptyModule {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn empty_module_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::empty_module::EmptyModule);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Module::Empty".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<INT>(r#"import "Module::Empty" as m; 42"#)?,
|
||||||
|
42
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod one_fn_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod advanced_math {
|
||||||
|
use rhai::FLOAT;
|
||||||
|
pub fn get_mystic_number() -> FLOAT {
|
||||||
|
42.0 as FLOAT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_fn_module_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::one_fn_module::advanced_math);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let m = math::get_mystic_number();
|
||||||
|
m"#
|
||||||
|
)?,
|
||||||
|
42.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod one_fn_and_const_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod advanced_math {
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
pub const MYSTIC_NUMBER: FLOAT = 42.0 as FLOAT;
|
||||||
|
|
||||||
|
pub fn euclidean_distance(x1: FLOAT, y1: FLOAT, x2: FLOAT, y2: FLOAT) -> FLOAT {
|
||||||
|
((y2 - y1).abs().powf(2.0) + (x2 - x1).abs().powf(2.0)).sqrt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_fn_and_const_module_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::one_fn_and_const_module::advanced_math);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let m = math::MYSTIC_NUMBER;
|
||||||
|
let x = math::euclidean_distance(0.0, 1.0, 0.0, m);
|
||||||
|
x"#
|
||||||
|
)?,
|
||||||
|
41.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod raw_fn_str_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod host_io {
|
||||||
|
pub fn write_out_str(message: &str) -> bool {
|
||||||
|
eprintln!("{}", message);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn raw_fn_str_module_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::raw_fn_str_module::host_io);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Host::IO".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<bool>(
|
||||||
|
r#"import "Host::IO" as io;
|
||||||
|
let x = io::write_out_str("hello world!");
|
||||||
|
x"#
|
||||||
|
)?,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod mut_opaque_ref_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::INT;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct StatusMessage {
|
||||||
|
os_code: Option<INT>,
|
||||||
|
message: String,
|
||||||
|
is_ok: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod host_msg {
|
||||||
|
use super::{StatusMessage, INT};
|
||||||
|
|
||||||
|
pub fn new_message(is_ok: bool, message: &str) -> StatusMessage {
|
||||||
|
StatusMessage {
|
||||||
|
is_ok,
|
||||||
|
os_code: None,
|
||||||
|
message: message.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_os_message(is_ok: bool, os_code: INT) -> StatusMessage {
|
||||||
|
StatusMessage {
|
||||||
|
is_ok,
|
||||||
|
os_code: Some(os_code),
|
||||||
|
message: format!("OS Code {}", os_code),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_out_message(message: &mut StatusMessage) -> bool {
|
||||||
|
eprintln!("{}", message.message);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mut_opaque_ref_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::mut_opaque_ref_module::host_msg);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Host::Msg".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<bool>(
|
||||||
|
r#"import "Host::Msg" as msg;
|
||||||
|
let success = "it worked";
|
||||||
|
let message1 = msg::new_message(true, success);
|
||||||
|
let ok1 = msg::write_out_message(message1);
|
||||||
|
let message2 = msg::new_os_message(true, 0);
|
||||||
|
let ok2 = msg::write_out_message(message2);
|
||||||
|
ok1 && ok2"#
|
||||||
|
)?,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
mod duplicate_fn_rename {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
#[export_module]
|
||||||
|
pub mod my_adds {
|
||||||
|
use rhai::{FLOAT, INT};
|
||||||
|
|
||||||
|
#[rhai_fn(name = "add")]
|
||||||
|
pub fn add_float(f1: FLOAT, f2: FLOAT) -> FLOAT {
|
||||||
|
f1 + f2
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rhai_fn(name = "add")]
|
||||||
|
pub fn add_int(i1: INT, i2: INT) -> INT {
|
||||||
|
i1 + i2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn duplicate_fn_rename_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.register_fn("get_mystic_number", || 42 as FLOAT);
|
||||||
|
let m = rhai::exported_module!(crate::duplicate_fn_rename::my_adds);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
let output_array = engine.eval::<Array>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let fx = get_mystic_number();
|
||||||
|
let fy = math::add(fx, 1.0);
|
||||||
|
let ix = 42;
|
||||||
|
let iy = math::add(ix, 1);
|
||||||
|
[fy, iy]
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
assert_eq!(&output_array[0].as_float().unwrap(), &43.0);
|
||||||
|
assert_eq!(&output_array[1].as_int().unwrap(), &43);
|
||||||
|
Ok(())
|
||||||
|
}
|
72
codegen/tests/test_nested.rs
Normal file
72
codegen/tests/test_nested.rs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
use rhai::module_resolvers::*;
|
||||||
|
use rhai::{Engine, EvalAltResult, RegisterFn, FLOAT, INT};
|
||||||
|
|
||||||
|
pub mod one_fn_module_nested_attr {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod advanced_math {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[rhai_fn(return_raw)]
|
||||||
|
pub fn get_mystic_number() -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
Ok(Dynamic::from(42.0 as FLOAT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_fn_module_nested_attr_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::one_fn_module_nested_attr::advanced_math);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let m = math::get_mystic_number();
|
||||||
|
m"#
|
||||||
|
)?,
|
||||||
|
42.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod one_fn_submodule_nested_attr {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod advanced_math {
|
||||||
|
#[rhai_mod(name = "constants")]
|
||||||
|
pub mod my_module {
|
||||||
|
use rhai::plugin::*;
|
||||||
|
use rhai::FLOAT;
|
||||||
|
#[rhai_fn(return_raw)]
|
||||||
|
pub fn get_mystic_number() -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
|
Ok(Dynamic::from(42.0 as FLOAT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn one_fn_submodule_nested_attr_test() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
let m = rhai::exported_module!(crate::one_fn_submodule_nested_attr::advanced_math);
|
||||||
|
let mut r = StaticModuleResolver::new();
|
||||||
|
r.insert("Math::Advanced".to_string(), m);
|
||||||
|
engine.set_module_resolver(Some(r));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
engine.eval::<FLOAT>(
|
||||||
|
r#"import "Math::Advanced" as math;
|
||||||
|
let m = math::constants::get_mystic_number();
|
||||||
|
m"#
|
||||||
|
)?,
|
||||||
|
42.0
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
8
codegen/tests/ui_tests.rs
Normal file
8
codegen/tests/ui_tests.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#![cfg(test)]
|
||||||
|
mod ui_tests {
|
||||||
|
#[test]
|
||||||
|
fn all() {
|
||||||
|
let t = trybuild::TestCases::new();
|
||||||
|
t.compile_fail("ui_tests/*.rs");
|
||||||
|
}
|
||||||
|
}
|
24
codegen/ui_tests/export_fn_bad_attr.rs
Normal file
24
codegen/ui_tests/export_fn_bad_attr.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(unknown = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_bad_attr.stderr
Normal file
11
codegen/ui_tests/export_fn_bad_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: unknown attribute 'unknown'
|
||||||
|
--> $DIR/export_fn_bad_attr.rs:9:13
|
||||||
|
|
|
||||||
|
9 | #[export_fn(unknown = "thing")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_bad_attr.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_bad_value.rs
Normal file
24
codegen/ui_tests/export_fn_bad_value.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(name = true)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_bad_value.stderr
Normal file
11
codegen/ui_tests/export_fn_bad_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting string literal
|
||||||
|
--> $DIR/export_fn_bad_value.rs:9:20
|
||||||
|
|
|
||||||
|
9 | #[export_fn(name = true)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_bad_value.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
25
codegen/ui_tests/export_fn_cfg.rs
Normal file
25
codegen/ui_tests/export_fn_cfg.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "foo"))]
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_cfg.stderr
Normal file
11
codegen/ui_tests/export_fn_cfg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cfg attributes not allowed on this item
|
||||||
|
--> $DIR/export_fn_cfg.rs:9:1
|
||||||
|
|
|
||||||
|
9 | #[cfg(not(feature = "foo"))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_cfg.rs:20:8
|
||||||
|
|
|
||||||
|
20 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_extra_value.rs
Normal file
24
codegen/ui_tests/export_fn_extra_value.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(return_raw = "yes")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_extra_value.stderr
Normal file
11
codegen/ui_tests/export_fn_extra_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: extraneous value
|
||||||
|
--> $DIR/export_fn_extra_value.rs:9:26
|
||||||
|
|
|
||||||
|
9 | #[export_fn(return_raw = "yes")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_extra_value.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_junk_arg.rs
Normal file
24
codegen/ui_tests/export_fn_junk_arg.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn("wheeeee")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_junk_arg.stderr
Normal file
11
codegen/ui_tests/export_fn_junk_arg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting identifier
|
||||||
|
--> $DIR/export_fn_junk_arg.rs:9:13
|
||||||
|
|
|
||||||
|
9 | #[export_fn("wheeeee")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_junk_arg.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_missing_value.rs
Normal file
24
codegen/ui_tests/export_fn_missing_value.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(name)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_missing_value.stderr
Normal file
11
codegen/ui_tests/export_fn_missing_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: requires value
|
||||||
|
--> $DIR/export_fn_missing_value.rs:9:13
|
||||||
|
|
|
||||||
|
9 | #[export_fn(name)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_missing_value.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_path_attr.rs
Normal file
24
codegen/ui_tests/export_fn_path_attr.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(rhai::name = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_path_attr.stderr
Normal file
11
codegen/ui_tests/export_fn_path_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting attribute name
|
||||||
|
--> $DIR/export_fn_path_attr.rs:9:13
|
||||||
|
|
|
||||||
|
9 | #[export_fn(rhai::name = "thing")]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_path_attr.rs:19:8
|
||||||
|
|
|
||||||
|
19 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
25
codegen/ui_tests/export_fn_raw_noreturn.rs
Normal file
25
codegen/ui_tests/export_fn_raw_noreturn.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
pub fn test_fn(input: &mut Point) {
|
||||||
|
input.x += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
test_fn(&mut n);
|
||||||
|
if n.x >= 10.0 {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_fn_raw_noreturn.stderr
Normal file
11
codegen/ui_tests/export_fn_raw_noreturn.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: return_raw functions must return Result<T>
|
||||||
|
--> $DIR/export_fn_raw_noreturn.rs:10:5
|
||||||
|
|
|
||||||
|
10 | pub fn test_fn(input: &mut Point) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/export_fn_raw_noreturn.rs:19:5
|
||||||
|
|
|
||||||
|
19 | test_fn(&mut n);
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/export_fn_raw_return.rs
Normal file
24
codegen/ui_tests/export_fn_raw_return.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn(return_raw)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
21
codegen/ui_tests/export_fn_raw_return.stderr
Normal file
21
codegen/ui_tests/export_fn_raw_return.stderr
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/export_fn_raw_return.rs:10:8
|
||||||
|
|
|
||||||
|
9 | #[export_fn(return_raw)]
|
||||||
|
| ------------------------ expected `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>` because of return type
|
||||||
|
10 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `bool`
|
||||||
|
|
|
||||||
|
= note: expected enum `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>`
|
||||||
|
found type `bool`
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/export_fn_raw_return.rs:10:33
|
||||||
|
|
|
||||||
|
9 | #[export_fn(return_raw)]
|
||||||
|
| ------------------------ expected `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>` because of return type
|
||||||
|
10 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^ expected enum `std::result::Result`, found `bool`
|
||||||
|
|
|
||||||
|
= note: expected enum `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>`
|
||||||
|
found type `bool`
|
27
codegen/ui_tests/export_mod_bad_attr.rs
Normal file
27
codegen/ui_tests/export_mod_bad_attr.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(unknown = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_bad_attr.stderr
Normal file
11
codegen/ui_tests/export_mod_bad_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: unknown attribute 'unknown'
|
||||||
|
--> $DIR/export_mod_bad_attr.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(unknown = "thing")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_bad_attr.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_bad_value.rs
Normal file
27
codegen/ui_tests/export_mod_bad_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(name = true)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_bad_value.stderr
Normal file
11
codegen/ui_tests/export_mod_bad_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting string literal
|
||||||
|
--> $DIR/export_mod_bad_value.rs:11:18
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(name = true)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_bad_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
28
codegen/ui_tests/export_mod_cfg.rs
Normal file
28
codegen/ui_tests/export_mod_cfg.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[cfg(not(feature = "foo"))]
|
||||||
|
#[rhai_fn]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_cfg.stderr
Normal file
11
codegen/ui_tests/export_mod_cfg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cfg attributes not allowed on this item
|
||||||
|
--> $DIR/export_mod_cfg.rs:11:1
|
||||||
|
|
|
||||||
|
11 | #[cfg(not(feature = "foo"))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_cfg.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_extra_value.rs
Normal file
27
codegen/ui_tests/export_mod_extra_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(return_raw = "yes")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_extra_value.stderr
Normal file
11
codegen/ui_tests/export_mod_extra_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: extraneous value
|
||||||
|
--> $DIR/export_mod_extra_value.rs:11:24
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(return_raw = "yes")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_extra_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_junk_arg.rs
Normal file
27
codegen/ui_tests/export_mod_junk_arg.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn("wheeeee")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_junk_arg.stderr
Normal file
11
codegen/ui_tests/export_mod_junk_arg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting identifier
|
||||||
|
--> $DIR/export_mod_junk_arg.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn("wheeeee")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_junk_arg.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_missing_value.rs
Normal file
27
codegen/ui_tests/export_mod_missing_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(name)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_missing_value.stderr
Normal file
11
codegen/ui_tests/export_mod_missing_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: requires value
|
||||||
|
--> $DIR/export_mod_missing_value.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(name)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_missing_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_path_attr.rs
Normal file
27
codegen/ui_tests/export_mod_path_attr.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(rhai::name = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_path_attr.stderr
Normal file
11
codegen/ui_tests/export_mod_path_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting attribute name
|
||||||
|
--> $DIR/export_mod_path_attr.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(rhai::name = "thing")]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_path_attr.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
28
codegen/ui_tests/export_mod_raw_noreturn.rs
Normal file
28
codegen/ui_tests/export_mod_raw_noreturn.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(return_raw)]
|
||||||
|
pub fn test_fn(input: &mut Point) {
|
||||||
|
input.x += 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
test_mod::test_fn(&mut n);
|
||||||
|
if n.x >= 10.0 {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_raw_noreturn.stderr
Normal file
11
codegen/ui_tests/export_mod_raw_noreturn.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: return_raw functions must return Result<T>
|
||||||
|
--> $DIR/export_mod_raw_noreturn.rs:12:5
|
||||||
|
|
|
||||||
|
12 | pub fn test_fn(input: &mut Point) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_mod`
|
||||||
|
--> $DIR/export_mod_raw_noreturn.rs:22:5
|
||||||
|
|
|
||||||
|
22 | test_mod::test_fn(&mut n);
|
||||||
|
| ^^^^^^^^ use of undeclared type or module `test_mod`
|
27
codegen/ui_tests/export_mod_raw_return.rs
Normal file
27
codegen/ui_tests/export_mod_raw_return.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_mod {
|
||||||
|
#[rhai_fn(return_raw)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/export_mod_raw_return.stderr
Normal file
11
codegen/ui_tests/export_mod_raw_return.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/export_mod_raw_return.rs:12:8
|
||||||
|
|
|
||||||
|
9 | #[export_module]
|
||||||
|
| ---------------- expected `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>` because of return type
|
||||||
|
...
|
||||||
|
12 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found `bool`
|
||||||
|
|
|
||||||
|
= note: expected enum `std::result::Result<rhai::Dynamic, std::boxed::Box<rhai::EvalAltResult>>`
|
||||||
|
found type `bool`
|
27
codegen/ui_tests/first_shared_ref.rs
Normal file
27
codegen/ui_tests/first_shared_ref.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
struct NonClonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: &NonClonable) -> bool {
|
||||||
|
input.d
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = NonClonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/first_shared_ref.stderr
Normal file
11
codegen/ui_tests/first_shared_ref.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: references from Rhai in this position must be mutable
|
||||||
|
--> $DIR/first_shared_ref.rs:11:23
|
||||||
|
|
|
||||||
|
11 | pub fn test_fn(input: &NonClonable) -> bool {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/first_shared_ref.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
31
codegen/ui_tests/module_cfg_const.rs
Normal file
31
codegen/ui_tests/module_cfg_const.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
use rhai::FLOAT;
|
||||||
|
|
||||||
|
#[cfg(feature = "foo")]
|
||||||
|
pub const MAGIC: FLOAT = 42.0 as FLOAT;
|
||||||
|
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/module_cfg_const.stderr
Normal file
11
codegen/ui_tests/module_cfg_const.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cfg attributes not allowed on this item
|
||||||
|
--> $DIR/module_cfg_const.rs:13:5
|
||||||
|
|
|
||||||
|
13 | #[cfg(feature = "foo")]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/module_cfg_const.rs:26:8
|
||||||
|
|
|
||||||
|
26 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/module_cfg_fn.rs
Normal file
27
codegen/ui_tests/module_cfg_fn.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[cfg(not(feature = "foo"))]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/module_cfg_fn.stderr
Normal file
11
codegen/ui_tests/module_cfg_fn.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cfg attributes not allowed on this item
|
||||||
|
--> $DIR/module_cfg_fn.rs:11:5
|
||||||
|
|
|
||||||
|
11 | #[cfg(not(feature = "foo"))]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/module_cfg_fn.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/non_clonable.rs
Normal file
27
codegen/ui_tests/non_clonable.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
struct NonClonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: NonClonable) -> bool {
|
||||||
|
input.d
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = NonClonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
5
codegen/ui_tests/non_clonable.stderr
Normal file
5
codegen/ui_tests/non_clonable.stderr
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/non_clonable.rs:11:23
|
||||||
|
|
|
||||||
|
11 | pub fn test_fn(input: NonClonable) -> bool {
|
||||||
|
| ^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable`
|
27
codegen/ui_tests/non_clonable_second.rs
Normal file
27
codegen/ui_tests/non_clonable_second.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
struct NonClonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(a: u32, b: NonClonable) -> bool {
|
||||||
|
a == 0 && b.d
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = NonClonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
if test_fn(10, n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
5
codegen/ui_tests/non_clonable_second.stderr
Normal file
5
codegen/ui_tests/non_clonable_second.stderr
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
error[E0277]: the trait bound `NonClonable: std::clone::Clone` is not satisfied
|
||||||
|
--> $DIR/non_clonable_second.rs:11:27
|
||||||
|
|
|
||||||
|
11 | pub fn test_fn(a: u32, b: NonClonable) -> bool {
|
||||||
|
| ^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `NonClonable`
|
28
codegen/ui_tests/return_mut_ref.rs
Normal file
28
codegen/ui_tests/return_mut_ref.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Clonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: &mut Clonable) -> &mut bool {
|
||||||
|
&mut input.d
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Clonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
if test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/return_mut_ref.stderr
Normal file
11
codegen/ui_tests/return_mut_ref.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cannot return a reference to Rhai
|
||||||
|
--> $DIR/return_mut_ref.rs:12:38
|
||||||
|
|
|
||||||
|
12 | pub fn test_fn(input: &mut Clonable) -> &mut bool {
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/return_mut_ref.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_fn(n) {
|
||||||
|
| ^^^^^^^ not found in this scope
|
27
codegen/ui_tests/return_pointer.rs
Normal file
27
codegen/ui_tests/return_pointer.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Clonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: Clonable) -> *const str {
|
||||||
|
"yes"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Clonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
println!("{}", unsafe {
|
||||||
|
let ptr = test_fn(n);
|
||||||
|
*ptr
|
||||||
|
});
|
||||||
|
}
|
11
codegen/ui_tests/return_pointer.stderr
Normal file
11
codegen/ui_tests/return_pointer.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cannot return a pointer to Rhai
|
||||||
|
--> $DIR/return_pointer.rs:12:33
|
||||||
|
|
|
||||||
|
12 | pub fn test_fn(input: Clonable) -> *const str {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/return_pointer.rs:24:19
|
||||||
|
|
|
||||||
|
24 | let ptr = test_fn(n);
|
||||||
|
| ^^^^^^^ not found in this scope
|
24
codegen/ui_tests/return_shared_ref.rs
Normal file
24
codegen/ui_tests/return_shared_ref.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Clonable {
|
||||||
|
a: f32,
|
||||||
|
b: u32,
|
||||||
|
c: char,
|
||||||
|
d: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_fn]
|
||||||
|
pub fn test_fn(input: Clonable) -> &'static str {
|
||||||
|
"yes"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Clonable {
|
||||||
|
a: 0.0,
|
||||||
|
b: 10,
|
||||||
|
c: 'a',
|
||||||
|
d: true,
|
||||||
|
};
|
||||||
|
println!("{}", test_fn(n));
|
||||||
|
}
|
11
codegen/ui_tests/return_shared_ref.stderr
Normal file
11
codegen/ui_tests/return_shared_ref.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: cannot return a reference to Rhai
|
||||||
|
--> $DIR/return_shared_ref.rs:12:33
|
||||||
|
|
|
||||||
|
12 | pub fn test_fn(input: Clonable) -> &'static str {
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0425]: cannot find function `test_fn` in this scope
|
||||||
|
--> $DIR/return_shared_ref.rs:23:20
|
||||||
|
|
|
||||||
|
23 | println!("{}", test_fn(n));
|
||||||
|
| ^^^^^^^ not found in this scope
|
27
codegen/ui_tests/rhai_fn_bad_attr.rs
Normal file
27
codegen/ui_tests/rhai_fn_bad_attr.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(unknown = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_bad_attr.stderr
Normal file
11
codegen/ui_tests/rhai_fn_bad_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: unknown attribute 'unknown'
|
||||||
|
--> $DIR/rhai_fn_bad_attr.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(unknown = "thing")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_bad_attr.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/rhai_fn_bad_value.rs
Normal file
27
codegen/ui_tests/rhai_fn_bad_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(name = true)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_bad_value.stderr
Normal file
11
codegen/ui_tests/rhai_fn_bad_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting string literal
|
||||||
|
--> $DIR/rhai_fn_bad_value.rs:11:18
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(name = true)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_bad_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/rhai_fn_extra_value.rs
Normal file
27
codegen/ui_tests/rhai_fn_extra_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(return_raw = "yes")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_extra_value.stderr
Normal file
11
codegen/ui_tests/rhai_fn_extra_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: extraneous value
|
||||||
|
--> $DIR/rhai_fn_extra_value.rs:11:24
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(return_raw = "yes")]
|
||||||
|
| ^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_extra_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/rhai_fn_junk_arg.rs
Normal file
27
codegen/ui_tests/rhai_fn_junk_arg.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn("wheeeee")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_junk_arg.stderr
Normal file
11
codegen/ui_tests/rhai_fn_junk_arg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting identifier
|
||||||
|
--> $DIR/rhai_fn_junk_arg.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn("wheeeee")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_junk_arg.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/rhai_fn_missing_value.rs
Normal file
27
codegen/ui_tests/rhai_fn_missing_value.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(name)]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_missing_value.stderr
Normal file
11
codegen/ui_tests/rhai_fn_missing_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: requires value
|
||||||
|
--> $DIR/rhai_fn_missing_value.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(name)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_missing_value.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
27
codegen/ui_tests/rhai_fn_path_attr.rs
Normal file
27
codegen/ui_tests/rhai_fn_path_attr.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_fn(rhai::name = "thing")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_path_attr.stderr
Normal file
11
codegen/ui_tests/rhai_fn_path_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting attribute name
|
||||||
|
--> $DIR/rhai_fn_path_attr.rs:11:11
|
||||||
|
|
|
||||||
|
11 | #[rhai_fn(rhai::name = "thing")]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_path_attr.rs:22:8
|
||||||
|
|
|
||||||
|
22 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
33
codegen/ui_tests/rhai_fn_rename_collision.rs
Normal file
33
codegen/ui_tests/rhai_fn_rename_collision.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rhai_fn(name = "foo")]
|
||||||
|
pub fn test_fn_2(input: Point) -> bool {
|
||||||
|
input.x < input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
17
codegen/ui_tests/rhai_fn_rename_collision.stderr
Normal file
17
codegen/ui_tests/rhai_fn_rename_collision.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error: duplicate Rhai signature for 'foo'
|
||||||
|
--> $DIR/rhai_fn_rename_collision.rs:17:15
|
||||||
|
|
|
||||||
|
17 | #[rhai_fn(name = "foo")]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: duplicated function renamed 'foo'
|
||||||
|
--> $DIR/rhai_fn_rename_collision.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo")]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_collision.rs:28:8
|
||||||
|
|
|
||||||
|
28 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
32
codegen/ui_tests/rhai_fn_rename_collision_oneattr.rs
Normal file
32
codegen/ui_tests/rhai_fn_rename_collision_oneattr.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn foo(input: Point) -> bool {
|
||||||
|
input.x < input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
17
codegen/ui_tests/rhai_fn_rename_collision_oneattr.stderr
Normal file
17
codegen/ui_tests/rhai_fn_rename_collision_oneattr.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error: duplicate Rhai signature for 'foo'
|
||||||
|
--> $DIR/rhai_fn_rename_collision_oneattr.rs:12:15
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo")]
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: duplicated function 'foo'
|
||||||
|
--> $DIR/rhai_fn_rename_collision_oneattr.rs:17:12
|
||||||
|
|
|
||||||
|
17 | pub fn foo(input: Point) -> bool {
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_collision_oneattr.rs:27:8
|
||||||
|
|
|
||||||
|
27 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
28
codegen/ui_tests/rhai_fn_rename_dot.rs
Normal file
28
codegen/ui_tests/rhai_fn_rename_dot.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
#[rhai_fn(name = "foo.bar")]
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_fn_rename_dot.stderr
Normal file
11
codegen/ui_tests/rhai_fn_rename_dot.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: Rhai function names may not contain dot
|
||||||
|
--> $DIR/rhai_fn_rename_dot.rs:12:22
|
||||||
|
|
|
||||||
|
12 | #[rhai_fn(name = "foo.bar")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_fn_rename_dot.rs:23:8
|
||||||
|
|
|
||||||
|
23 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_bad_attr.rs
Normal file
29
codegen/ui_tests/rhai_mod_bad_attr.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod(unknown = "thing")]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_mod_bad_attr.stderr
Normal file
11
codegen/ui_tests/rhai_mod_bad_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: unknown attribute 'unknown'
|
||||||
|
--> $DIR/rhai_mod_bad_attr.rs:11:12
|
||||||
|
|
|
||||||
|
11 | #[rhai_mod(unknown = "thing")]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_bad_attr.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_bad_value.rs
Normal file
29
codegen/ui_tests/rhai_mod_bad_value.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod(name = true)]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_mod_bad_value.stderr
Normal file
11
codegen/ui_tests/rhai_mod_bad_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting string literal
|
||||||
|
--> $DIR/rhai_mod_bad_value.rs:11:19
|
||||||
|
|
|
||||||
|
11 | #[rhai_mod(name = true)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_bad_value.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_inner_cfg_false.rs
Normal file
29
codegen/ui_tests/rhai_mod_inner_cfg_false.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[cfg(feature = "unset_feature")]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_mod::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
5
codegen/ui_tests/rhai_mod_inner_cfg_false.stderr
Normal file
5
codegen/ui_tests/rhai_mod_inner_cfg_false.stderr
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
error[E0433]: failed to resolve: could not find `test_mod` in `test_module`
|
||||||
|
--> $DIR/rhai_mod_inner_cfg_false.rs:24:21
|
||||||
|
|
|
||||||
|
24 | if test_module::test_mod::test_fn(n) {
|
||||||
|
| ^^^^^^^^ could not find `test_mod` in `test_module`
|
29
codegen/ui_tests/rhai_mod_junk_arg.rs
Normal file
29
codegen/ui_tests/rhai_mod_junk_arg.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod("wheeeee")]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_mod_junk_arg.stderr
Normal file
11
codegen/ui_tests/rhai_mod_junk_arg.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting identifier
|
||||||
|
--> $DIR/rhai_mod_junk_arg.rs:11:12
|
||||||
|
|
|
||||||
|
11 | #[rhai_mod("wheeeee")]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_junk_arg.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_missing_value.rs
Normal file
29
codegen/ui_tests/rhai_mod_missing_value.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod(name)]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_mod_missing_value.stderr
Normal file
11
codegen/ui_tests/rhai_mod_missing_value.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: requires value
|
||||||
|
--> $DIR/rhai_mod_missing_value.rs:11:12
|
||||||
|
|
|
||||||
|
11 | #[rhai_mod(name)]
|
||||||
|
| ^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_missing_value.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
31
codegen/ui_tests/rhai_mod_name_collisions.rs
Normal file
31
codegen/ui_tests/rhai_mod_name_collisions.rs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
pub use super::Point;
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x < input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
17
codegen/ui_tests/rhai_mod_name_collisions.stderr
Normal file
17
codegen/ui_tests/rhai_mod_name_collisions.stderr
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
error: duplicate function 'test_fn'
|
||||||
|
--> $DIR/rhai_mod_name_collisions.rs:16:12
|
||||||
|
|
|
||||||
|
16 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: duplicated function 'test_fn'
|
||||||
|
--> $DIR/rhai_mod_name_collisions.rs:12:12
|
||||||
|
|
|
||||||
|
12 | pub fn test_fn(input: Point) -> bool {
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_name_collisions.rs:26:8
|
||||||
|
|
|
||||||
|
26 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_path_attr.rs
Normal file
29
codegen/ui_tests/rhai_mod_path_attr.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod(rhai::name = "thing")]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
11
codegen/ui_tests/rhai_mod_path_attr.stderr
Normal file
11
codegen/ui_tests/rhai_mod_path_attr.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error: expecting attribute name
|
||||||
|
--> $DIR/rhai_mod_path_attr.rs:11:12
|
||||||
|
|
|
||||||
|
11 | #[rhai_mod(rhai::name = "thing")]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0433]: failed to resolve: use of undeclared type or module `test_module`
|
||||||
|
--> $DIR/rhai_mod_path_attr.rs:24:8
|
||||||
|
|
|
||||||
|
24 | if test_module::test_fn(n) {
|
||||||
|
| ^^^^^^^^^^^ use of undeclared type or module `test_module`
|
29
codegen/ui_tests/rhai_mod_return_raw.rs
Normal file
29
codegen/ui_tests/rhai_mod_return_raw.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use rhai::plugin::*;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct Point {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
pub mod test_module {
|
||||||
|
#[rhai_mod(return_raw = "yes")]
|
||||||
|
pub mod test_mod {
|
||||||
|
pub fn test_fn(input: Point) -> bool {
|
||||||
|
input.x > input.y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let n = Point {
|
||||||
|
x: 0.0,
|
||||||
|
y: 10.0,
|
||||||
|
};
|
||||||
|
if test_module::test_fn(n) {
|
||||||
|
println!("yes");
|
||||||
|
} else {
|
||||||
|
println!("no");
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user