mirror of
https://github.com/Icinga/icinga2.git
synced 2025-09-21 16:57:58 +02:00
DSL: allow function()use(this){} and function()use(this=x){}
This commit is contained in:
parent
a65f2d6b41
commit
5683a03f55
@ -1049,6 +1049,14 @@ function MakeHelloFunction(name) {
|
||||
}
|
||||
```
|
||||
|
||||
The `use` keyword also supports `this`, i.e.:
|
||||
|
||||
```
|
||||
(function() use (this = [ "foo", "bar" ]) {
|
||||
log(this)
|
||||
})()
|
||||
```
|
||||
|
||||
## Conditional Statements <a id="conditional-statements"></a>
|
||||
|
||||
### Conditional Statements: if/else <a id="conditional-statements-if-else"></a>
|
||||
|
@ -10,8 +10,9 @@ using namespace icinga;
|
||||
REGISTER_TYPE_WITH_PROTOTYPE(Function, Function::GetPrototype());
|
||||
|
||||
Function::Function(const String& name, Callback function, const std::vector<String>& args,
|
||||
bool hasClosedThis, Value closedThis,
|
||||
bool side_effect_free, bool deprecated)
|
||||
: m_Callback(std::move(function))
|
||||
: m_Callback(std::move(function)), m_HasClosedThis(hasClosedThis), m_ClosedThis(std::move(closedThis))
|
||||
{
|
||||
SetName(name, true);
|
||||
SetSideEffectFree(side_effect_free, true);
|
||||
@ -21,6 +22,10 @@ Function::Function(const String& name, Callback function, const std::vector<Stri
|
||||
|
||||
Value Function::Invoke(const std::vector<Value>& arguments)
|
||||
{
|
||||
if (m_HasClosedThis) {
|
||||
return InvokeThis(m_ClosedThis, arguments);
|
||||
}
|
||||
|
||||
ScriptFrame frame(false);
|
||||
return m_Callback(arguments);
|
||||
}
|
||||
|
@ -27,8 +27,9 @@ public:
|
||||
|
||||
template<typename F>
|
||||
Function(const String& name, F function, const std::vector<String>& args = std::vector<String>(),
|
||||
bool hasClosedThis = false, Value closedThis = Value(),
|
||||
bool side_effect_free = false, bool deprecated = false)
|
||||
: Function(name, WrapFunction(function), args, side_effect_free, deprecated)
|
||||
: Function(name, WrapFunction(function), args, hasClosedThis, std::move(closedThis), side_effect_free, deprecated)
|
||||
{ }
|
||||
|
||||
Value Invoke(const std::vector<Value>& arguments = std::vector<Value>());
|
||||
@ -50,8 +51,11 @@ public:
|
||||
|
||||
private:
|
||||
Callback m_Callback;
|
||||
bool m_HasClosedThis;
|
||||
Value m_ClosedThis;
|
||||
|
||||
Function(const String& name, Callback function, const std::vector<String>& args,
|
||||
bool hasClosedThis, Value closedThis,
|
||||
bool side_effect_free, bool deprecated);
|
||||
};
|
||||
|
||||
|
@ -1103,6 +1103,14 @@ use_specifier_item: identifier
|
||||
$$ = new std::pair<String, std::unique_ptr<Expression> >(std::move(*$1), std::unique_ptr<Expression>($3));
|
||||
delete $1;
|
||||
}
|
||||
| T_THIS
|
||||
{
|
||||
$$ = new std::pair<String, std::unique_ptr<Expression> >("this", std::unique_ptr<Expression>(new GetScopeExpression(ScopeThis)));
|
||||
}
|
||||
| T_THIS T_SET rterm
|
||||
{
|
||||
$$ = new std::pair<String, std::unique_ptr<Expression> >("this", std::unique_ptr<Expression>($3));
|
||||
}
|
||||
;
|
||||
|
||||
apply_for_specifier: /* empty */
|
||||
|
@ -904,7 +904,7 @@ ExpressionResult ImportDefaultTemplatesExpression::DoEvaluate(ScriptFrame& frame
|
||||
|
||||
ExpressionResult FunctionExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
return VMOps::NewFunction(frame, m_Name, m_Args, m_ClosedVars, m_Expression);
|
||||
return VMOps::NewFunction(frame, m_Name, m_Args, m_ClosedVars, m_ClosedThis, m_Expression);
|
||||
}
|
||||
|
||||
ExpressionResult ApplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
|
@ -814,7 +814,14 @@ public:
|
||||
FunctionExpression(String name, std::vector<String> args,
|
||||
std::map<String, std::unique_ptr<Expression> >&& closedVars, std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
|
||||
: DebuggableExpression(debugInfo), m_Name(std::move(name)), m_Args(std::move(args)), m_ClosedVars(std::move(closedVars)), m_Expression(expression.release())
|
||||
{ }
|
||||
{
|
||||
auto closedThis (m_ClosedVars.find("this"));
|
||||
|
||||
if (closedThis != m_ClosedVars.end()) {
|
||||
m_ClosedThis = std::move(closedThis->second);
|
||||
m_ClosedVars.erase(closedThis);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
@ -823,6 +830,7 @@ private:
|
||||
String m_Name;
|
||||
std::vector<String> m_Args;
|
||||
std::map<String, std::unique_ptr<Expression> > m_ClosedVars;
|
||||
std::unique_ptr<Expression> m_ClosedThis;
|
||||
Expression::Ptr m_Expression;
|
||||
};
|
||||
|
||||
|
@ -91,9 +91,15 @@ public:
|
||||
}
|
||||
|
||||
static inline Value NewFunction(ScriptFrame& frame, const String& name, const std::vector<String>& argNames,
|
||||
const std::map<String, std::unique_ptr<Expression> >& closedVars, const Expression::Ptr& expression)
|
||||
const std::map<String, std::unique_ptr<Expression> >& closedVars,
|
||||
const std::unique_ptr<Expression>& closedThis, const Expression::Ptr& expression)
|
||||
{
|
||||
auto evaluatedClosedVars = EvaluateClosedVars(frame, closedVars);
|
||||
Value evaluatedClosedThis;
|
||||
|
||||
if (closedThis) {
|
||||
evaluatedClosedThis = closedThis->Evaluate(frame);
|
||||
}
|
||||
|
||||
auto wrapper = [argNames, evaluatedClosedVars, expression](const std::vector<Value>& arguments) -> Value {
|
||||
if (arguments.size() < argNames.size())
|
||||
@ -112,7 +118,7 @@ public:
|
||||
return expression->Evaluate(*frame);
|
||||
};
|
||||
|
||||
return new Function(name, wrapper, argNames);
|
||||
return new Function(name, wrapper, argNames, (bool)closedThis, std::move(evaluatedClosedThis));
|
||||
}
|
||||
|
||||
static inline Value NewApply(ScriptFrame& frame, const String& type, const String& target, const String& name, const Expression::Ptr& filter,
|
||||
|
Loading…
x
Reference in New Issue
Block a user