Catch Fn and eval in method call at parse time.

This commit is contained in:
Stephen Chung 2020-10-17 18:18:29 +08:00
parent 7a4905209c
commit f903eda8ab
3 changed files with 28 additions and 22 deletions

View File

@ -11,6 +11,10 @@ Breaking changes
* `EvalAltResult::ErrorReadingScriptFile` is removed in favor of the new `EvalAltResult::ErrorSystem`. * `EvalAltResult::ErrorReadingScriptFile` is removed in favor of the new `EvalAltResult::ErrorSystem`.
* `EvalAltResult::ErrorLoopBreak` is renamed to `EvalAltResult::LoopBreak`. * `EvalAltResult::ErrorLoopBreak` is renamed to `EvalAltResult::LoopBreak`.
Enhancements
* Calling `eval` or `Fn` in method-call style, which is an error, is now caught during parsing.
Version 0.19.2 Version 0.19.2
============== ==============

View File

@ -524,27 +524,16 @@ impl Engine {
)) ))
} }
// Fn // Fn/eval - reaching this point it must be a method-style call, mostly like redirected
KEYWORD_FN_PTR // by a function pointer so it isn't caught at parse time.
if args.len() == 1 && !self.has_override(lib, hash_fn, hash_script, pub_only) => KEYWORD_FN_PTR | KEYWORD_EVAL if args.len() == 1 => EvalAltResult::ErrorRuntime(
{ format!(
EvalAltResult::ErrorRuntime( "'{}' should not be called in method style. Try {}(...);",
"'Fn' should not be called in method style. Try Fn(...);".into(), fn_name, fn_name
Position::none(), ),
) Position::none(),
.into() )
} .into(),
// eval - reaching this point it must be a method-style call
KEYWORD_EVAL
if args.len() == 1 && !self.has_override(lib, hash_fn, hash_script, pub_only) =>
{
EvalAltResult::ErrorRuntime(
"'eval' should not be called in method style. Try eval(...);".into(),
Position::none(),
)
.into()
}
// Script-like function found // Script-like function found
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]

View File

@ -1,7 +1,9 @@
//! Main module defining the lexer and parser. //! Main module defining the lexer and parser.
use crate::any::{Dynamic, Union}; use crate::any::{Dynamic, Union};
use crate::engine::{Engine, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT}; use crate::engine::{
Engine, KEYWORD_EVAL, KEYWORD_FN_PTR, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT,
};
use crate::error::{LexError, ParseError, ParseErrorType}; use crate::error::{LexError, ParseError, ParseErrorType};
use crate::fn_native::{FnPtr, Shared}; use crate::fn_native::{FnPtr, Shared};
use crate::module::{Module, ModuleRef}; use crate::module::{Module, ModuleRef};
@ -2318,6 +2320,17 @@ fn make_dot_expr(lhs: Expr, rhs: Expr, op_pos: Position) -> Result<Expr, ParseEr
op_pos, op_pos,
))) )))
} }
// lhs.Fn() or lhs.eval()
(_, Expr::FnCall(x))
if x.3.len() == 0 && [KEYWORD_FN_PTR, KEYWORD_EVAL].contains(&(x.0).0.as_ref()) =>
{
return Err(PERR::BadInput(format!(
"'{}' should not be called in method style. Try {}(...);",
(x.0).0,
(x.0).0
))
.into_err((x.0).3));
}
// lhs.func!(...) // lhs.func!(...)
(_, Expr::FnCall(x)) if (x.0).2 => { (_, Expr::FnCall(x)) if (x.0).2 => {
return Err(PERR::MalformedCapture( return Err(PERR::MalformedCapture(