[icinga-checkins] icinga.org: icinga2/master: Change scoping mechanism for the __using keyword

git at icinga.org git at icinga.org
Fri Aug 12 13:13:35 CEST 2016


Module: icinga2
Branch: master
Commit: 00af6b2db2d84223209fafb727b55eb0037ecd22
URL:    https://git.icinga.org/?p=icinga2.git;a=commit;h=00af6b2db2d84223209fafb727b55eb0037ecd22

Author: Gunnar Beutner <gunnar.beutner at netways.de>
Date:   Fri Aug 12 13:13:01 2016 +0200

Change scoping mechanism for the __using keyword

refs #12408

---

 lib/base/scriptframe.cpp      |   25 +++++++++++++++++++------
 lib/base/scriptframe.hpp      |    5 ++++-
 lib/config/expression.cpp     |   11 +++--------
 lib/config/vmops.hpp          |    7 +++----
 lib/methods/methods-itl.conf  |    2 ++
 lib/remote/consolehandler.cpp |   33 ++++++++++++++++++---------------
 6 files changed, 49 insertions(+), 34 deletions(-)

diff --git a/lib/base/scriptframe.cpp b/lib/base/scriptframe.cpp
index 6ea697c..cd2ec8e 100644
--- a/lib/base/scriptframe.cpp
+++ b/lib/base/scriptframe.cpp
@@ -24,6 +24,7 @@
 using namespace icinga;
 
 boost::thread_specific_ptr<std::stack<ScriptFrame *> > ScriptFrame::m_ScriptFrames;
+Array::Ptr ScriptFrame::m_Imports;
 
 ScriptFrame::ScriptFrame(void)
 	: Locals(new Dictionary()), Self(ScriptGlobal::GetGlobals()), Sandboxed(false), Depth(0)
@@ -45,12 +46,6 @@ void ScriptFrame::InitializeFrame(void)
 		ScriptFrame *frame = frames->top();
 
 		Sandboxed = frame->Sandboxed;
-		Imports = frame->Imports;
-	}
-
-	if (!Imports) {
-		Imports = new Array();
-		Imports->Add(ScriptGlobal::Get("System"));
 	}
 
 	PushFrame(this);
@@ -111,3 +106,21 @@ void ScriptFrame::PushFrame(ScriptFrame *frame)
 
 	frames->push(frame);
 }
+
+Array::Ptr ScriptFrame::GetImports(void)
+{
+	if (!m_Imports) {
+		m_Imports = new Array();
+		m_Imports->Add(ScriptGlobal::Get("System"));
+	}
+
+	return m_Imports;
+}
+
+void ScriptFrame::AddImport(const Object::Ptr& import)
+{
+	Array::Ptr imports = m_Imports->ShallowClone();
+	imports->Add(import);
+	m_Imports = imports;
+}
+
diff --git a/lib/base/scriptframe.hpp b/lib/base/scriptframe.hpp
index 9827011..e60b400 100644
--- a/lib/base/scriptframe.hpp
+++ b/lib/base/scriptframe.hpp
@@ -32,7 +32,6 @@ namespace icinga
 struct I2_BASE_API ScriptFrame
 {
 	Dictionary::Ptr Locals;
-	Array::Ptr Imports;
 	Value Self;
 	bool Sandboxed;
 	int Depth;
@@ -46,8 +45,12 @@ struct I2_BASE_API ScriptFrame
 
 	static ScriptFrame *GetCurrentFrame(void);
 
+	static Array::Ptr GetImports(void);
+	static void AddImport(const Object::Ptr& import);
+
 private:
 	static boost::thread_specific_ptr<std::stack<ScriptFrame *> > m_ScriptFrames;
+	static Array::Ptr m_Imports;
 
 	inline static void PushFrame(ScriptFrame *frame);
 	inline static ScriptFrame *PopFrame(void);
diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp
index bd24225..7c18071 100644
--- a/lib/config/expression.cpp
+++ b/lib/config/expression.cpp
@@ -904,15 +904,10 @@ ExpressionResult UsingExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhin
 	CHECK_RESULT(importres);
 	Value import = importres.GetValue();
 
-	if (!import.IsObject())
-		BOOST_THROW_EXCEPTION(ScriptError("The parameter does not resolve to an object", m_DebugInfo));
+	if (!import.IsObjectType<Dictionary>())
+		BOOST_THROW_EXCEPTION(ScriptError("The parameter must resolve to an object of type 'Dictionary'", m_DebugInfo));
 
-	if (!frame.Imports)
-		frame.Imports = new Array();
-	else
-		frame.Imports = static_pointer_cast<Array>(frame.Imports->ShallowClone());
-
-	frame.Imports->Add(import);
+	ScriptFrame::AddImport(import);
 
 	return Empty;
 }
diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp
index 40d5617..8a11b52 100644
--- a/lib/config/vmops.hpp
+++ b/lib/config/vmops.hpp
@@ -46,11 +46,10 @@ class VMOps
 public:
 	static inline bool FindVarImportRef(ScriptFrame& frame, const String& name, Value *result, const DebugInfo& debugInfo = DebugInfo())
 	{
-		if (!frame.Imports)
-			return false;
+		Array::Ptr imports = ScriptFrame::GetImports();
 
-		ObjectLock olock(frame.Imports);
-		BOOST_FOREACH(const Value& import, frame.Imports) {
+		ObjectLock olock(imports);
+		BOOST_FOREACH(const Value& import, imports) {
 			Object::Ptr obj = import;
 			if (obj->HasOwnField(name)) {
 				*result = import;
diff --git a/lib/methods/methods-itl.conf b/lib/methods/methods-itl.conf
index eed5dbb..91b7141 100644
--- a/lib/methods/methods-itl.conf
+++ b/lib/methods/methods-itl.conf
@@ -20,6 +20,8 @@
 assert(Internal.run_with_activation_context(function() {
 	template CheckCommand "icinga-check-command" {
 		execute = Internal.IcingaCheck
+
+		Internal.remove("IcingaCheck")
 	}
 
 	template CheckCommand "cluster-check-command" {
diff --git a/lib/remote/consolehandler.cpp b/lib/remote/consolehandler.cpp
index 3fb41ed..ac99b03 100644
--- a/lib/remote/consolehandler.cpp
+++ b/lib/remote/consolehandler.cpp
@@ -215,7 +215,7 @@ static void AddSuggestion(std::vector<String>& matches, const String& word, cons
 	matches.push_back(suggestion);
 }
 
-static void AddSuggestions(std::vector<String>& matches, const String& word, const String& pword, const Value& value)
+static void AddSuggestions(std::vector<String>& matches, const String& word, const String& pword, bool withPrototype, const Value& value)
 {
 	String prefix;
 
@@ -239,18 +239,20 @@ static void AddSuggestions(std::vector<String>& matches, const String& word, con
 		AddSuggestion(matches, word, prefix + field.Name);
 	}
 
-	while (type) {
-		Object::Ptr prototype = type->GetPrototype();
-		Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(prototype);
+	if (withPrototype) {
+		while (type) {
+			Object::Ptr prototype = type->GetPrototype();
+			Dictionary::Ptr dict = dynamic_pointer_cast<Dictionary>(prototype);
 
-		if (dict) {
-			ObjectLock olock(dict);
-			BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
-				AddSuggestion(matches, word, prefix + kv.first);
+			if (dict) {
+				ObjectLock olock(dict);
+				BOOST_FOREACH(const Dictionary::Pair& kv, dict) {
+					AddSuggestion(matches, word, prefix + kv.first);
+				}
 			}
-		}
 
-		type = type->GetBaseType();
+			type = type->GetBaseType();
+		}
 	}
 }
 
@@ -276,10 +278,11 @@ std::vector<String> ConsoleHandler::GetAutocompletionSuggestions(const String& w
 		}
 	}
 
-	if (frame.Imports) {
-		ObjectLock olock(frame.Imports);
-		BOOST_FOREACH(const Value& import, frame.Imports) {
-			AddSuggestions(matches, word, "", import);
+	{
+		Array::Ptr imports = ScriptFrame::GetImports();
+		ObjectLock olock(imports);
+		BOOST_FOREACH(const Value& import, imports) {
+			AddSuggestions(matches, word, "", false, import);
 		}
 	}
 
@@ -296,7 +299,7 @@ std::vector<String> ConsoleHandler::GetAutocompletionSuggestions(const String& w
 			if (expr)
 				value = expr->Evaluate(frame);
 
-			AddSuggestions(matches, word, pword, value);
+			AddSuggestions(matches, word, pword, true, value);
 
 		} catch (...) { /* Ignore the exception */ }
 	}



More information about the icinga-checkins mailing list