1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//! 方法调用 —— 对应 Java `freemarker.core.MethodCall`
//! (`_eval` :51-71:宏 → invokeFunction;方法模型 → TemplateMethodModelEx.exec)
use crate::core::eval::eval;
use crate::core::Expr;
use crate::error::{Result, TemplateError};
use crate::template::TModel;
/// 方法调用表达式(对应 MethodCall.java;解析器经 `ExprKind::Call` 承载)
pub struct MethodCall {
pub callee: Expr,
pub args: Vec<Expr>,
}
impl MethodCall {
/// 构造(Java 构造器;Rust 侧由解析器产生)
pub fn new(callee: Expr, args: Vec<Expr>) -> Self {
MethodCall { callee, args }
}
/// 求值(Java `_eval` :51-71)
pub(crate) fn eval(&self, env: &mut crate::core::Environment) -> Result<TModel> {
let c = eval(env, &self.callee)?;
if let Some(mv) = env.as_macro(&c) {
// Java MethodCall :68-71:instanceof Macro → invokeFunction
if !mv.def.is_function {
return Err(TemplateError::misc(
"A macro cannot be called in an expression. (Functions can be.)",
));
}
let args: Vec<(String, Expr)> = self
.args
.iter()
.map(|e| (String::new(), e.clone()))
.collect();
return env.invoke_function(&mv, &args);
}
if let Some(m) = &c.method {
let mut vals = Vec::with_capacity(self.args.len());
for a in &self.args {
// Java:标识符求值不抛错(Environment.getVariable 返回 null),缺失
// 参数以 null 传入方法(`m.bar(null, 11)` 的 null 即缺失变量——
// jar 实测合法);本引擎解析层抛 Err → 此处按 Java 语义转为 nothing
match eval(env, a) {
Ok(v) => vals.push(v),
Err(TemplateError::InvalidReference { .. }) => vals.push(TModel::nothing()),
Err(e) => return Err(e),
}
}
// Java :60-66:TemplateMethodModelEx.exec(arguments.getModelList(env));
// Java 经线程局部 Environment 访问上下文,Rust 显式传 env
return m.exec(env, vals);
}
Err(TemplateError::misc(format!(
"The value of {} is not a method or function (it's a {})",
crate::core::environment::expr_desc(&self.callee),
c.type_name
)))
}
}