From 54bbaf9f7d6469043be40dfa74036c21da547daf Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Wed, 10 Aug 2016 15:40:02 +0200 Subject: [PATCH] Implement support for marking functions as deprecated fixes #12393 --- lib/base/CMakeLists.txt | 3 ++- lib/base/array-script.cpp | 32 ++++++++++++------------ lib/base/boolean-script.cpp | 2 +- lib/base/configobject-script.cpp | 4 +-- lib/base/datetime-script.cpp | 2 +- lib/base/dictionary-script.cpp | 14 +++++------ lib/base/function-script.cpp | 4 +-- lib/base/function.cpp | 20 +++++++-------- lib/base/function.hpp | 29 ++++++++++++++++------ lib/base/function.ti | 34 ++++++++++++++++++++++++++ lib/base/json-script.cpp | 4 +-- lib/base/math-script.cpp | 42 ++++++++++++++++---------------- lib/base/number-script.cpp | 2 +- lib/base/object-script.cpp | 6 ++--- lib/base/string-script.cpp | 22 ++++++++--------- lib/base/typetype-script.cpp | 2 +- lib/config/config_parser.yy | 14 +++++------ lib/config/expression.cpp | 2 +- lib/config/expression.hpp | 3 ++- lib/config/vmops.hpp | 4 +-- lib/icinga/checkable-script.cpp | 2 +- lib/icinga/macroprocessor.cpp | 4 +-- tools/mkclass/classcompiler.cpp | 9 +++++++ 23 files changed, 158 insertions(+), 102 deletions(-) create mode 100644 lib/base/function.ti diff --git a/lib/base/CMakeLists.txt b/lib/base/CMakeLists.txt index a040371d4..ea0bb807f 100644 --- a/lib/base/CMakeLists.txt +++ b/lib/base/CMakeLists.txt @@ -19,6 +19,7 @@ mkclass_target(application.ti application.tcpp application.thpp) mkclass_target(configobject.ti configobject.tcpp configobject.thpp) mkclass_target(datetime.ti datetime.tcpp datetime.thpp) mkclass_target(filelogger.ti filelogger.tcpp filelogger.thpp) +mkclass_target(function.ti function.tcpp function.thpp) mkclass_target(logger.ti logger.tcpp logger.thpp) mkclass_target(streamlogger.ti streamlogger.tcpp streamlogger.thpp) mkclass_target(sysloglogger.ti sysloglogger.tcpp sysloglogger.thpp) @@ -32,7 +33,7 @@ set(base_SOURCES json-script.cpp loader.cpp logger.cpp logger.thpp math-script.cpp netstring.cpp networkstream.cpp number.cpp number-script.cpp object.cpp object-script.cpp objecttype.cpp primitivetype.cpp process.cpp ringbuffer.cpp scriptframe.cpp - function.cpp function-script.cpp functionwrapper.cpp scriptglobal.cpp + function.cpp function.thpp function-script.cpp functionwrapper.cpp scriptglobal.cpp scriptutils.cpp serializer.cpp socket.cpp socketevents.cpp socketevents-epoll.cpp socketevents-poll.cpp stacktrace.cpp statsfunction.cpp stdiostream.cpp stream.cpp streamlogger.cpp streamlogger.thpp string.cpp string-script.cpp sysloglogger.cpp sysloglogger.thpp tcpsocket.cpp threadpool.cpp timer.cpp diff --git a/lib/base/array-script.cpp b/lib/base/array-script.cpp index a56cb4567..e7f57a349 100644 --- a/lib/base/array-script.cpp +++ b/lib/base/array-script.cpp @@ -229,22 +229,22 @@ Object::Ptr Array::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("len", new Function(WrapFunction(ArrayLen), true)); - prototype->Set("set", new Function(WrapFunction(ArraySet))); - prototype->Set("get", new Function(WrapFunction(ArrayGet))); - prototype->Set("add", new Function(WrapFunction(ArrayAdd))); - prototype->Set("remove", new Function(WrapFunction(ArrayRemove))); - prototype->Set("contains", new Function(WrapFunction(ArrayContains), true)); - prototype->Set("clear", new Function(WrapFunction(ArrayClear))); - prototype->Set("sort", new Function(WrapFunction(ArraySort), true)); - prototype->Set("shallow_clone", new Function(WrapFunction(ArrayShallowClone), true)); - prototype->Set("join", new Function(WrapFunction(ArrayJoin), true)); - prototype->Set("reverse", new Function(WrapFunction(ArrayReverse), true)); - prototype->Set("map", new Function(WrapFunction(ArrayMap), true)); - prototype->Set("reduce", new Function(WrapFunction(ArrayReduce), true)); - prototype->Set("filter", new Function(WrapFunction(ArrayFilter), true)); - prototype->Set("unique", new Function(WrapFunction(ArrayUnique), true)); + prototype->Set("len", new Function("Array#len", WrapFunction(ArrayLen), true)); + prototype->Set("set", new Function("Array#set", WrapFunction(ArraySet))); + prototype->Set("get", new Function("Array#get", WrapFunction(ArrayGet))); + prototype->Set("add", new Function("Array#add", WrapFunction(ArrayAdd))); + prototype->Set("remove", new Function("Array#remove", WrapFunction(ArrayRemove))); + prototype->Set("contains", new Function("Array#contains", WrapFunction(ArrayContains), true)); + prototype->Set("clear", new Function("Array#clear", WrapFunction(ArrayClear))); + prototype->Set("sort", new Function("Array#sort", WrapFunction(ArraySort), true)); + prototype->Set("shallow_clone", new Function("Array#shallow_clone", WrapFunction(ArrayShallowClone), true)); + prototype->Set("join", new Function("Array#join", WrapFunction(ArrayJoin), true)); + prototype->Set("reverse", new Function("Array#reverse", WrapFunction(ArrayReverse), true)); + prototype->Set("map", new Function("Array#map", WrapFunction(ArrayMap), true)); + prototype->Set("reduce", new Function("Array#reduce", WrapFunction(ArrayReduce), true)); + prototype->Set("filter", new Function("Array#filter", WrapFunction(ArrayFilter), true)); + prototype->Set("unique", new Function("Array#unique", WrapFunction(ArrayUnique), true)); } return prototype; -} \ No newline at end of file +} diff --git a/lib/base/boolean-script.cpp b/lib/base/boolean-script.cpp index d262ed5c6..c454864b9 100644 --- a/lib/base/boolean-script.cpp +++ b/lib/base/boolean-script.cpp @@ -38,7 +38,7 @@ Object::Ptr Boolean::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("to_string", new Function(WrapFunction(BooleanToString), true)); + prototype->Set("to_string", new Function("Boolean#to_string", WrapFunction(BooleanToString), true)); } return prototype; diff --git a/lib/base/configobject-script.cpp b/lib/base/configobject-script.cpp index 34d234325..23d968295 100644 --- a/lib/base/configobject-script.cpp +++ b/lib/base/configobject-script.cpp @@ -45,8 +45,8 @@ Object::Ptr ConfigObject::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("modify_attribute", new Function(WrapFunction(ConfigObjectModifyAttribute), false)); - prototype->Set("restore_attribute", new Function(WrapFunction(ConfigObjectRestoreAttribute), false)); + prototype->Set("modify_attribute", new Function("ConfigObject#modify_attribute", WrapFunction(ConfigObjectModifyAttribute), false)); + prototype->Set("restore_attribute", new Function("ConfigObject#restore_attribute", WrapFunction(ConfigObjectRestoreAttribute), false)); } return prototype; diff --git a/lib/base/datetime-script.cpp b/lib/base/datetime-script.cpp index e0210a9b6..dda68b88c 100644 --- a/lib/base/datetime-script.cpp +++ b/lib/base/datetime-script.cpp @@ -39,7 +39,7 @@ Object::Ptr DateTime::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("format", new Function(WrapFunction(DateTimeFormat))); + prototype->Set("format", new Function("DateTime#format", WrapFunction(DateTimeFormat))); } return prototype; diff --git a/lib/base/dictionary-script.cpp b/lib/base/dictionary-script.cpp index 9128eb936..01196d52c 100644 --- a/lib/base/dictionary-script.cpp +++ b/lib/base/dictionary-script.cpp @@ -86,13 +86,13 @@ Object::Ptr Dictionary::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("len", new Function(WrapFunction(DictionaryLen), true)); - prototype->Set("set", new Function(WrapFunction(DictionarySet))); - prototype->Set("get", new Function(WrapFunction(DictionaryGet))); - prototype->Set("remove", new Function(WrapFunction(DictionaryRemove))); - prototype->Set("contains", new Function(WrapFunction(DictionaryContains), true)); - prototype->Set("shallow_clone", new Function(WrapFunction(DictionaryShallowClone), true)); - prototype->Set("keys", new Function(WrapFunction(DictionaryKeys), true)); + prototype->Set("len", new Function("Dictionary#len", WrapFunction(DictionaryLen), true)); + prototype->Set("set", new Function("Dictionary#set", WrapFunction(DictionarySet))); + prototype->Set("get", new Function("Dictionary#get", WrapFunction(DictionaryGet))); + prototype->Set("remove", new Function("Dictionary#remove", WrapFunction(DictionaryRemove))); + prototype->Set("contains", new Function("Dictionary#contains", WrapFunction(DictionaryContains), true)); + prototype->Set("shallow_clone", new Function("Dictionary#shallow_clone", WrapFunction(DictionaryShallowClone), true)); + prototype->Set("keys", new Function("Dictionary#keys", WrapFunction(DictionaryKeys), true)); } return prototype; diff --git a/lib/base/function-script.cpp b/lib/base/function-script.cpp index f0bd61118..54b82cb2f 100644 --- a/lib/base/function-script.cpp +++ b/lib/base/function-script.cpp @@ -59,8 +59,8 @@ Object::Ptr Function::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("call", new Function(WrapFunction(FunctionCall))); - prototype->Set("callv", new Function(WrapFunction(FunctionCallV))); + prototype->Set("call", new Function("Function#call", WrapFunction(FunctionCall))); + prototype->Set("callv", new Function("Function#callv", WrapFunction(FunctionCallV))); } return prototype; diff --git a/lib/base/function.cpp b/lib/base/function.cpp index d7ef94270..529e95dcc 100644 --- a/lib/base/function.cpp +++ b/lib/base/function.cpp @@ -18,17 +18,20 @@ ******************************************************************************/ #include "base/function.hpp" -#include "base/primitivetype.hpp" -#include "base/dictionary.hpp" +#include "base/function.tcpp" #include "base/scriptframe.hpp" using namespace icinga; -REGISTER_PRIMITIVE_TYPE_NOINST(Function, Object, Function::GetPrototype()); +REGISTER_TYPE_WITH_PROTOTYPE(Function, Function::GetPrototype()); -Function::Function(const Callback& function, bool side_effect_free) - : m_Callback(function), m_SideEffectFree(side_effect_free) -{ } +Function::Function(const String& name, const Callback& function, bool side_effect_free, bool deprecated) + : m_Callback(function) +{ + SetName(name, true); + SetSideEffectFree(side_effect_free, true); + SetDeprecated(deprecated, true); +} Value Function::Invoke(const std::vector& arguments) { @@ -43,11 +46,6 @@ Value Function::Invoke(const Value& otherThis, const std::vector& argumen return m_Callback(arguments); } -bool Function::IsSideEffectFree(void) const -{ - return m_SideEffectFree; -} - Object::Ptr Function::Clone(void) const { return const_cast(this); diff --git a/lib/base/function.hpp b/lib/base/function.hpp index 6dba72582..223a94d2e 100644 --- a/lib/base/function.hpp +++ b/lib/base/function.hpp @@ -21,6 +21,7 @@ #define SCRIPTFUNCTION_H #include "base/i2-base.hpp" +#include "base/function.thpp" #include "base/value.hpp" #include "base/functionwrapper.hpp" #include "base/scriptglobal.hpp" @@ -35,18 +36,27 @@ namespace icinga * * @ingroup base */ -class I2_BASE_API Function : public Object +class I2_BASE_API Function : public ObjectImpl { public: DECLARE_OBJECT(Function); typedef boost::function& arguments)> Callback; - Function(const Callback& function, bool side_effect_free = false); + Function(const String& name, const Callback& function, bool side_effect_free = false, bool deprecated = false); Value Invoke(const std::vector& arguments = std::vector()); Value Invoke(const Value& otherThis, const std::vector& arguments = std::vector()); - bool IsSideEffectFree(void) const; + + inline bool IsSideEffectFree(void) const + { + return GetSideEffectFree(); + } + + inline bool IsDeprecated(void) const + { + return GetDeprecated(); + } static Object::Ptr GetPrototype(void); @@ -54,13 +64,12 @@ public: private: Callback m_Callback; - bool m_SideEffectFree; }; #define REGISTER_SCRIPTFUNCTION(name, callback) \ namespace { namespace UNIQUE_NAME(sf) { namespace sf ## name { \ void RegisterFunction(void) { \ - Function::Ptr sf = new icinga::Function(WrapFunction(callback)); \ + Function::Ptr sf = new icinga::Function(#name, WrapFunction(callback)); \ ScriptGlobal::Set(#name, sf); \ } \ INITIALIZE_ONCE_WITH_PRIORITY(RegisterFunction, 10); \ @@ -69,8 +78,10 @@ private: #define REGISTER_SCRIPTFUNCTION_NS(ns, name, callback) \ namespace { namespace UNIQUE_NAME(sf) { namespace sf ## ns ## name { \ void RegisterFunction(void) { \ - Function::Ptr sf = new icinga::Function(WrapFunction(callback)); \ + Function::Ptr sf = new icinga::Function(#ns "#" #name, WrapFunction(callback), false); \ ScriptGlobal::Set(#ns "." #name, sf); \ + Function::Ptr dsf = new icinga::Function(#name " (deprecated)", WrapFunction(callback), false, true); \ + ScriptGlobal::Set(#name, dsf); \ } \ INITIALIZE_ONCE_WITH_PRIORITY(RegisterFunction, 10); \ } } } @@ -78,7 +89,7 @@ private: #define REGISTER_SAFE_SCRIPTFUNCTION(name, callback) \ namespace { namespace UNIQUE_NAME(sf) { namespace sf ## name { \ void RegisterFunction(void) { \ - Function::Ptr sf = new icinga::Function(WrapFunction(callback), true); \ + Function::Ptr sf = new icinga::Function(#name, WrapFunction(callback), true); \ ScriptGlobal::Set(#name, sf); \ } \ INITIALIZE_ONCE_WITH_PRIORITY(RegisterFunction, 10); \ @@ -87,8 +98,10 @@ private: #define REGISTER_SAFE_SCRIPTFUNCTION_NS(ns, name, callback) \ namespace { namespace UNIQUE_NAME(sf) { namespace sf ## ns ## name { \ void RegisterFunction(void) { \ - Function::Ptr sf = new icinga::Function(WrapFunction(callback), true); \ + Function::Ptr sf = new icinga::Function(#ns "#" #name, WrapFunction(callback), true); \ ScriptGlobal::Set(#ns "." #name, sf); \ + Function::Ptr dsf = new icinga::Function(#name " (deprecated)", WrapFunction(callback), true, true); \ + ScriptGlobal::Set(#name, dsf); \ } \ INITIALIZE_ONCE_WITH_PRIORITY(RegisterFunction, 10); \ } } } diff --git a/lib/base/function.ti b/lib/base/function.ti new file mode 100644 index 000000000..b9b9f9cef --- /dev/null +++ b/lib/base/function.ti @@ -0,0 +1,34 @@ +/****************************************************************************** + * Icinga 2 * + * Copyright (C) 2012-2016 Icinga Development Team (https://www.icinga.org/) * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software Foundation * + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * + ******************************************************************************/ + +#include "base/configobject.hpp" + +library base; + +namespace icinga +{ + +abstract class Function +{ + String "name"; + bool side_effect_free; + bool deprecated; +}; + +} diff --git a/lib/base/json-script.cpp b/lib/base/json-script.cpp index 5e754ec84..9cf68b35b 100644 --- a/lib/base/json-script.cpp +++ b/lib/base/json-script.cpp @@ -36,8 +36,8 @@ static void InitializeJsonObj(void) Dictionary::Ptr jsonObj = new Dictionary(); /* Methods */ - jsonObj->Set("encode", new Function(WrapFunction(JsonEncodeShim), true)); - jsonObj->Set("decode", new Function(WrapFunction(JsonDecode), true)); + jsonObj->Set("encode", new Function("Json#encode", WrapFunction(JsonEncodeShim), true)); + jsonObj->Set("decode", new Function("Json#decode", WrapFunction(JsonDecode), true)); ScriptGlobal::Set("Json", jsonObj); } diff --git a/lib/base/math-script.cpp b/lib/base/math-script.cpp index 9b2322409..ff24d8bc6 100644 --- a/lib/base/math-script.cpp +++ b/lib/base/math-script.cpp @@ -174,27 +174,27 @@ static void InitializeMathObj(void) mathObj->Set("SQRT2", 1.41421356237309504880); /* Methods */ - mathObj->Set("abs", new Function(WrapFunction(MathAbs), true)); - mathObj->Set("acos", new Function(WrapFunction(MathAcos), true)); - mathObj->Set("asin", new Function(WrapFunction(MathAsin), true)); - mathObj->Set("atan", new Function(WrapFunction(MathAtan), true)); - mathObj->Set("atan2", new Function(WrapFunction(MathAtan2), true)); - mathObj->Set("ceil", new Function(WrapFunction(MathCeil), true)); - mathObj->Set("cos", new Function(WrapFunction(MathCos), true)); - mathObj->Set("exp", new Function(WrapFunction(MathExp), true)); - mathObj->Set("floor", new Function(WrapFunction(MathFloor), true)); - mathObj->Set("log", new Function(WrapFunction(MathLog), true)); - mathObj->Set("max", new Function(WrapFunction(MathMax), true)); - mathObj->Set("min", new Function(WrapFunction(MathMin), true)); - mathObj->Set("pow", new Function(WrapFunction(MathPow), true)); - mathObj->Set("random", new Function(WrapFunction(MathRandom), true)); - mathObj->Set("round", new Function(WrapFunction(MathRound), true)); - mathObj->Set("sin", new Function(WrapFunction(MathSin), true)); - mathObj->Set("sqrt", new Function(WrapFunction(MathSqrt), true)); - mathObj->Set("tan", new Function(WrapFunction(MathTan), true)); - mathObj->Set("isnan", new Function(WrapFunction(MathIsnan), true)); - mathObj->Set("isinf", new Function(WrapFunction(MathIsinf), true)); - mathObj->Set("sign", new Function(WrapFunction(MathSign), true)); + mathObj->Set("abs", new Function("Math#abs", WrapFunction(MathAbs), true)); + mathObj->Set("acos", new Function("Math#acos", WrapFunction(MathAcos), true)); + mathObj->Set("asin", new Function("Math#asin", WrapFunction(MathAsin), true)); + mathObj->Set("atan", new Function("Math#atan", WrapFunction(MathAtan), true)); + mathObj->Set("atan2", new Function("Math#atan2", WrapFunction(MathAtan2), true)); + mathObj->Set("ceil", new Function("Math#ceil", WrapFunction(MathCeil), true)); + mathObj->Set("cos", new Function("Math#cos", WrapFunction(MathCos), true)); + mathObj->Set("exp", new Function("Math#exp", WrapFunction(MathExp), true)); + mathObj->Set("floor", new Function("Math#floor", WrapFunction(MathFloor), true)); + mathObj->Set("log", new Function("Math#log", WrapFunction(MathLog), true)); + mathObj->Set("max", new Function("Math#max", WrapFunction(MathMax), true)); + mathObj->Set("min", new Function("Math#min", WrapFunction(MathMin), true)); + mathObj->Set("pow", new Function("Math#pow", WrapFunction(MathPow), true)); + mathObj->Set("random", new Function("Math#random", WrapFunction(MathRandom), true)); + mathObj->Set("round", new Function("Math#round", WrapFunction(MathRound), true)); + mathObj->Set("sin", new Function("Math#sin", WrapFunction(MathSin), true)); + mathObj->Set("sqrt", new Function("Math#sqrt", WrapFunction(MathSqrt), true)); + mathObj->Set("tan", new Function("Math#tan", WrapFunction(MathTan), true)); + mathObj->Set("isnan", new Function("Math#isnan", WrapFunction(MathIsnan), true)); + mathObj->Set("isinf", new Function("Math#isinf", WrapFunction(MathIsinf), true)); + mathObj->Set("sign", new Function("Math#sign", WrapFunction(MathSign), true)); ScriptGlobal::Set("Math", mathObj); } diff --git a/lib/base/number-script.cpp b/lib/base/number-script.cpp index 30d2e43b7..b6ccf0c37 100644 --- a/lib/base/number-script.cpp +++ b/lib/base/number-script.cpp @@ -37,7 +37,7 @@ Object::Ptr Number::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("to_string", new Function(WrapFunction(NumberToString), true)); + prototype->Set("to_string", new Function("Number#to_string", WrapFunction(NumberToString), true)); } return prototype; diff --git a/lib/base/object-script.cpp b/lib/base/object-script.cpp index edef30077..903c93987 100644 --- a/lib/base/object-script.cpp +++ b/lib/base/object-script.cpp @@ -52,9 +52,9 @@ Object::Ptr Object::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("to_string", new Function(WrapFunction(ObjectToString), true)); - prototype->Set("notify_attribute", new Function(WrapFunction(ObjectNotifyAttribute), false)); - prototype->Set("clone", new Function(WrapFunction(ObjectClone), true)); + prototype->Set("to_string", new Function("Object#to_string", WrapFunction(ObjectToString), true)); + prototype->Set("notify_attribute", new Function("Object#notify_attribute", WrapFunction(ObjectNotifyAttribute), false)); + prototype->Set("clone", new Function("Object#clone", WrapFunction(ObjectClone), true)); } return prototype; diff --git a/lib/base/string-script.cpp b/lib/base/string-script.cpp index 7ea1c91ab..531918e8e 100644 --- a/lib/base/string-script.cpp +++ b/lib/base/string-script.cpp @@ -146,17 +146,17 @@ Object::Ptr String::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("len", new Function(WrapFunction(StringLen), true)); - prototype->Set("to_string", new Function(WrapFunction(StringToString), true)); - prototype->Set("substr", new Function(WrapFunction(StringSubstr), true)); - prototype->Set("upper", new Function(WrapFunction(StringUpper), true)); - prototype->Set("lower", new Function(WrapFunction(StringLower), true)); - prototype->Set("split", new Function(WrapFunction(StringSplit), true)); - prototype->Set("find", new Function(WrapFunction(StringFind), true)); - prototype->Set("contains", new Function(WrapFunction(StringContains), true)); - prototype->Set("replace", new Function(WrapFunction(StringReplace), true)); - prototype->Set("reverse", new Function(WrapFunction(StringReverse), true)); - prototype->Set("trim", new Function(WrapFunction(StringTrim), true)); + prototype->Set("len", new Function("String#len", WrapFunction(StringLen), true)); + prototype->Set("to_string", new Function("String#to_string", WrapFunction(StringToString), true)); + prototype->Set("substr", new Function("String#substr", WrapFunction(StringSubstr), true)); + prototype->Set("upper", new Function("String#upper", WrapFunction(StringUpper), true)); + prototype->Set("lower", new Function("String#lower", WrapFunction(StringLower), true)); + prototype->Set("split", new Function("String#split", WrapFunction(StringSplit), true)); + prototype->Set("find", new Function("String#find", WrapFunction(StringFind), true)); + prototype->Set("contains", new Function("String#contains", WrapFunction(StringContains), true)); + prototype->Set("replace", new Function("String#replace", WrapFunction(StringReplace), true)); + prototype->Set("reverse", new Function("String#reverse", WrapFunction(StringReverse), true)); + prototype->Set("trim", new Function("String#trim", WrapFunction(StringTrim), true)); } return prototype; diff --git a/lib/base/typetype-script.cpp b/lib/base/typetype-script.cpp index 01a9950cf..54b3ccf2b 100644 --- a/lib/base/typetype-script.cpp +++ b/lib/base/typetype-script.cpp @@ -48,7 +48,7 @@ Object::Ptr TypeType::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("register_attribute_handler", new Function(WrapFunction(TypeRegisterAttributeHandler), false)); + prototype->Set("register_attribute_handler", new Function("Type#register_attribute_handler", WrapFunction(TypeRegisterAttributeHandler), false)); } return prototype; diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 6a0e4df69..baf9b241f 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -629,7 +629,7 @@ lterm: T_LIBRARY rterm { EndFlowControlBlock(context); - FunctionExpression *fexpr = new FunctionExpression(*$4, $6, $8, @$); + FunctionExpression *fexpr = new FunctionExpression(*$2, *$4, $6, $8, @$); delete $4; $$ = new SetExpression(MakeIndexer(ScopeThis, *$2), OpSetLiteral, fexpr, @$); @@ -920,7 +920,7 @@ rterm_no_side_effect_no_dict: T_STRING args.push_back(*$1); delete $1; - $$ = new FunctionExpression(args, new std::map(), $4, @$); + $$ = new FunctionExpression("", args, new std::map(), $4, @$); } | identifier T_FOLLOWS rterm %dprec 1 { @@ -930,7 +930,7 @@ rterm_no_side_effect_no_dict: T_STRING args.push_back(*$1); delete $1; - $$ = new FunctionExpression(args, new std::map(), $3, @$); + $$ = new FunctionExpression("", args, new std::map(), $3, @$); } | '(' identifier_items ')' T_FOLLOWS { @@ -940,14 +940,14 @@ rterm_no_side_effect_no_dict: T_STRING { EndFlowControlBlock(context); - $$ = new FunctionExpression(*$2, new std::map(), $6, @$); + $$ = new FunctionExpression("", *$2, new std::map(), $6, @$); delete $2; } | '(' identifier_items ')' T_FOLLOWS rterm %dprec 1 { ASSERT(!dynamic_cast($5)); - $$ = new FunctionExpression(*$2, new std::map(), $5, @$); + $$ = new FunctionExpression("", *$2, new std::map(), $5, @$); delete $2; } | rterm_array @@ -988,7 +988,7 @@ rterm_no_side_effect_no_dict: T_STRING { EndFlowControlBlock(context); - $$ = new FunctionExpression(*$3, $5, $7, @$); + $$ = new FunctionExpression("", *$3, $5, $7, @$); delete $3; } | T_NULLARY_LAMBDA_BEGIN @@ -1012,7 +1012,7 @@ rterm_no_side_effect_no_dict: T_STRING DictExpression *aexpr = new DictExpression(dlist, @$); aexpr->MakeInline(); - $$ = new FunctionExpression(std::vector(), NULL, aexpr, @$); + $$ = new FunctionExpression("", std::vector(), NULL, aexpr, @$); } ; diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index bd87767e3..2e52425fd 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -755,7 +755,7 @@ ExpressionResult ImportExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhi ExpressionResult FunctionExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { - return VMOps::NewFunction(frame, m_Args, m_ClosedVars, m_Expression); + return VMOps::NewFunction(frame, m_Name, m_Args, m_ClosedVars, m_Expression); } ExpressionResult ApplyExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const diff --git a/lib/config/expression.hpp b/lib/config/expression.hpp index 8e0e9cdad..7db4b11a2 100644 --- a/lib/config/expression.hpp +++ b/lib/config/expression.hpp @@ -790,7 +790,7 @@ private: class I2_CONFIG_API FunctionExpression : public DebuggableExpression { public: - FunctionExpression(const std::vector& args, + FunctionExpression(const String& name, const std::vector& args, std::map *closedVars, Expression *expression, const DebugInfo& debugInfo = DebugInfo()) : DebuggableExpression(debugInfo), m_Args(args), m_ClosedVars(closedVars), m_Expression(expression) { } @@ -799,6 +799,7 @@ protected: virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override; private: + String m_Name; std::vector m_Args; std::map *m_ClosedVars; boost::shared_ptr m_Expression; diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp index 1dc5b2b94..a23687217 100644 --- a/lib/config/vmops.hpp +++ b/lib/config/vmops.hpp @@ -95,10 +95,10 @@ public: } - static inline Value NewFunction(ScriptFrame& frame, const std::vector& args, + static inline Value NewFunction(ScriptFrame& frame, const String& name, const std::vector& args, std::map *closedVars, const boost::shared_ptr& expression) { - return new Function(boost::bind(&FunctionWrapper, _1, args, + return new Function(name, boost::bind(&FunctionWrapper, _1, args, EvaluateClosedVars(frame, closedVars), expression)); } diff --git a/lib/icinga/checkable-script.cpp b/lib/icinga/checkable-script.cpp index ce02e6605..1e301ff7b 100644 --- a/lib/icinga/checkable-script.cpp +++ b/lib/icinga/checkable-script.cpp @@ -39,7 +39,7 @@ Object::Ptr Checkable::GetPrototype(void) if (!prototype) { prototype = new Dictionary(); - prototype->Set("process_check_result", new Function(WrapFunction(CheckableProcessCheckResult), false)); + prototype->Set("process_check_result", new Function("Checkable#process_check_result", WrapFunction(CheckableProcessCheckResult), false)); } return prototype; diff --git a/lib/icinga/macroprocessor.cpp b/lib/icinga/macroprocessor.cpp index a985fa933..de90b055d 100644 --- a/lib/icinga/macroprocessor.cpp +++ b/lib/icinga/macroprocessor.cpp @@ -216,10 +216,10 @@ Value MacroProcessor::EvaluateFunction(const Function::Ptr& func, const Resolver resolvers_this->Set(resolver.first, resolver.second); } - resolvers_this->Set("macro", new Function(boost::bind(&MacroProcessor::InternalResolveMacrosShim, + resolvers_this->Set("macro", new Function("macro (temporary)", boost::bind(&MacroProcessor::InternalResolveMacrosShim, _1, boost::cref(resolvers), cr, MacroProcessor::EscapeCallback(), resolvedMacros, useResolvedMacros, recursionLevel + 1))); - resolvers_this->Set("resolve_arguments", new Function(boost::bind(&MacroProcessor::InternalResolveArgumentsShim, + resolvers_this->Set("resolve_arguments", new Function("resolve_arguments (temporary)", boost::bind(&MacroProcessor::InternalResolveArgumentsShim, _1, boost::cref(resolvers), cr, resolvedMacros, useResolvedMacros, recursionLevel + 1))); diff --git a/tools/mkclass/classcompiler.cpp b/tools/mkclass/classcompiler.cpp index 80c0b107d..8277826be 100644 --- a/tools/mkclass/classcompiler.cpp +++ b/tools/mkclass/classcompiler.cpp @@ -522,6 +522,12 @@ void ClassCompiler::HandleClass(const Klass& klass, const ClassDebugInfo&) } else m_Impl << "\t" << "Value avalue = value;" << std::endl; + m_Impl << "\t" << "if (avalue.IsObjectType()) {" << std::endl + << "\t\t" << "Function::Ptr func = avalue;" << std::endl + << "\t\t" << "if (func->IsDeprecated())" << std::endl + << "\t\t\t" << "Log(LogWarning, \"" << klass.Name << "\") << \"Field '" << field.Name << "' for object '\" << dynamic_cast(this)->GetName() << \"' of type '\" << dynamic_cast(this)->GetType()->GetName() << \"' is set to a deprecated function: \" << func->GetName();" << std::endl + << "\t" << "}" << std::endl << std::endl; + std::string ftype = FieldTypeToIcingaName(field, true); if (field.Type.IsName) { @@ -1379,6 +1385,9 @@ void ClassCompiler::CompileStream(const std::string& path, std::istream& input, << "#include \"base/utility.hpp\"" << std::endl << "#include \"base/convert.hpp\"" << std::endl << "#include \"base/dependencygraph.hpp\"" << std::endl + << "#include \"base/logger.hpp\"" << std::endl + << "#include \"base/function.hpp\"" << std::endl + << "#include \"base/configtype.hpp\"" << std::endl << "#include " << std::endl << "#include " << std::endl << "#ifdef _MSC_VER" << std::endl -- 2.40.0