just_engine/runner/plugin/resolver.rs
1//! Plugin resolver trait for lazy, dynamic resolution of super-global objects.
2//!
3//! Plugins implement `PluginResolver` to provide objects (like `Math`, `console`)
4//! that are available in the super-global scope. Objects are resolved lazily —
5//! only when JS code actually references them.
6
7use crate::runner::ds::error::JErrorType;
8use crate::runner::ds::value::JsValue;
9use crate::runner::plugin::types::EvalContext;
10
11/// A plugin resolver that can dynamically provide named objects and their methods.
12///
13/// Resolvers are queried in registration order when a name lookup reaches the
14/// super-global scope. The first resolver that claims a name wins.
15pub trait PluginResolver {
16 /// Does this resolver provide a binding with the given name?
17 ///
18 /// This should be a cheap check (e.g. a `HashSet::contains`).
19 /// It must NOT allocate or materialize the object.
20 fn has_binding(&self, name: &str) -> bool;
21
22 /// Materialize the object for the given name.
23 ///
24 /// Called only after `has_binding` returns `true`.
25 /// The returned `JsValue` is cached in the super-global environment
26 /// so this is called at most once per name per execution.
27 fn resolve(&self, name: &str, ctx: &mut EvalContext) -> Result<JsValue, JErrorType>;
28
29 /// Resolve a method on an object this resolver provides.
30 ///
31 /// For example, if this resolver provides `"Math"`, then
32 /// `resolve_method("Math", "abs", ctx, this, args)` should execute `Math.abs`.
33 ///
34 /// Returns `None` if the method is not found, allowing fallback to
35 /// property lookup on the materialized object.
36 fn call_method(
37 &self,
38 object_name: &str,
39 method_name: &str,
40 ctx: &mut EvalContext,
41 this: JsValue,
42 args: Vec<JsValue>,
43 ) -> Option<Result<JsValue, JErrorType>>;
44
45 /// Get a constructor for the given object name, if available.
46 ///
47 /// Returns `None` if this resolver doesn't provide a constructor for the name.
48 fn call_constructor(
49 &self,
50 _object_name: &str,
51 _ctx: &mut EvalContext,
52 _args: Vec<JsValue>,
53 ) -> Option<Result<JsValue, JErrorType>> {
54 None
55 }
56
57 /// Human-readable name for this resolver (for debugging/logging).
58 fn name(&self) -> &str;
59}