Fix scoping rules for object definitions.

Refs #5846
This commit is contained in:
Gunnar Beutner 2014-03-24 11:23:47 +01:00
parent 8bfb60b7fa
commit 8e699ac0fa
13 changed files with 57 additions and 16 deletions

View File

@ -445,7 +445,7 @@ Value AExpression::OpSetDivide(const AExpression *expr, const Dictionary::Ptr& l
Value AExpression::OpIndexer(const AExpression *expr, const Dictionary::Ptr& locals) Value AExpression::OpIndexer(const AExpression *expr, const Dictionary::Ptr& locals)
{ {
Dictionary::Ptr dict = locals->Get(expr->m_Operand1); Dictionary::Ptr dict = OpVariable(expr, locals);
if (!dict) if (!dict)
BOOST_THROW_EXCEPTION(ConfigError("Script variable '" + expr->m_Operand1 + "' not set in this scope.")); BOOST_THROW_EXCEPTION(ConfigError("Script variable '" + expr->m_Operand1 + "' not set in this scope."));

View File

@ -24,8 +24,8 @@ using namespace icinga;
ApplyRule::RuleMap ApplyRule::m_Rules; ApplyRule::RuleMap ApplyRule::m_Rules;
ApplyRule::CallbackMap ApplyRule::m_Callbacks; ApplyRule::CallbackMap ApplyRule::m_Callbacks;
ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di) ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope)
: m_Template(tmpl), m_Expression(expression), m_DebugInfo(di) : m_Template(tmpl), m_Expression(expression), m_DebugInfo(di), m_Scope(scope)
{ } { }
String ApplyRule::GetTemplate(void) const String ApplyRule::GetTemplate(void) const
@ -43,9 +43,14 @@ DebugInfo ApplyRule::GetDebugInfo(void) const
return m_DebugInfo; return m_DebugInfo;
} }
void ApplyRule::AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di) Dictionary::Ptr ApplyRule::GetScope(void) const
{ {
m_Rules[std::make_pair(sourceType, targetType)].push_back(ApplyRule(tmpl, expression, di)); return m_Scope;
}
void ApplyRule::AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope)
{
m_Rules[std::make_pair(sourceType, targetType)].push_back(ApplyRule(tmpl, expression, di, scope));
} }
void ApplyRule::EvaluateRules(void) void ApplyRule::EvaluateRules(void)

View File

@ -42,8 +42,9 @@ public:
String GetTemplate(void) const; String GetTemplate(void) const;
AExpression::Ptr GetExpression(void) const; AExpression::Ptr GetExpression(void) const;
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
Dictionary::Ptr GetScope(void) const;
static void AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di); static void AddRule(const String& sourceType, const String& tmpl, const String& targetType, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope);
static void EvaluateRules(void); static void EvaluateRules(void);
static void RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback); static void RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback);
@ -53,11 +54,12 @@ private:
String m_Template; String m_Template;
AExpression::Ptr m_Expression; AExpression::Ptr m_Expression;
DebugInfo m_DebugInfo; DebugInfo m_DebugInfo;
Dictionary::Ptr m_Scope;
static CallbackMap m_Callbacks; static CallbackMap m_Callbacks;
static RuleMap m_Rules; static RuleMap m_Rules;
ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di); ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di, const Dictionary::Ptr& scope);
}; };
} }

View File

@ -460,6 +460,8 @@ object:
item->SetAbstract(m_Abstract); item->SetAbstract(m_Abstract);
item->SetScope(m_ModuleScope);
item->Compile()->Register(); item->Compile()->Register();
item.reset(); item.reset();
} }
@ -713,6 +715,6 @@ apply: T_APPLY optional_template identifier identifier T_TO identifier T_WHERE r
AExpression::Ptr aexpr = make_shared<AExpression>(&AExpression::OpFunctionCall, "bool", make_shared<AExpression>(&AExpression::OpLiteral, arguments, @8), @8); AExpression::Ptr aexpr = make_shared<AExpression>(&AExpression::OpFunctionCall, "bool", make_shared<AExpression>(&AExpression::OpLiteral, arguments, @8), @8);
ApplyRule::AddRule($3, $4, $6, aexpr, DebugInfoRange(@1, @8)); ApplyRule::AddRule($3, $4, $6, aexpr, DebugInfoRange(@1, @8), m_ModuleScope);
} }
%% %%

View File

@ -49,9 +49,11 @@ ConfigItem::ItemMap ConfigItem::m_Items;
*/ */
ConfigItem::ConfigItem(const String& type, const String& name, ConfigItem::ConfigItem(const String& type, const String& name,
bool abstract, const AExpression::Ptr& exprl, bool abstract, const AExpression::Ptr& exprl,
const std::vector<String>& parents, const DebugInfo& debuginfo) const std::vector<String>& parents, const DebugInfo& debuginfo,
const Dictionary::Ptr& scope)
: m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false), : m_Type(type), m_Name(name), m_Abstract(abstract), m_Validated(false),
m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo) m_ExpressionList(exprl), m_ParentNames(parents), m_DebugInfo(debuginfo),
m_Scope(scope)
{ {
} }
@ -95,6 +97,11 @@ DebugInfo ConfigItem::GetDebugInfo(void) const
return m_DebugInfo; return m_DebugInfo;
} }
Dictionary::Ptr ConfigItem::GetScope(void) const
{
return m_Scope;
}
/** /**
* Retrieves the expression list for the configuration item. * Retrieves the expression list for the configuration item.
* *
@ -145,9 +152,14 @@ Dictionary::Ptr ConfigItem::GetProperties(void)
{ {
ASSERT(OwnsLock()); ASSERT(OwnsLock());
Dictionary::Ptr properties = make_shared<Dictionary>(); if (!m_Properties) {
GetLinkedExpressionList()->Evaluate(properties); m_Properties = make_shared<Dictionary>();
return properties; m_Properties->Set("__parent", m_Scope);
GetLinkedExpressionList()->Evaluate(m_Properties);
m_Properties->Remove("__parent");
}
return m_Properties;
} }
/** /**

View File

@ -46,7 +46,7 @@ public:
ConfigItem(const String& type, const String& name, bool abstract, ConfigItem(const String& type, const String& name, bool abstract,
const AExpression::Ptr& exprl, const std::vector<String>& parents, const AExpression::Ptr& exprl, const std::vector<String>& parents,
const DebugInfo& debuginfo); const DebugInfo& debuginfo, const Dictionary::Ptr& scope);
String GetType(void) const; String GetType(void) const;
String GetName(void) const; String GetName(void) const;
@ -62,6 +62,8 @@ public:
DebugInfo GetDebugInfo(void) const; DebugInfo GetDebugInfo(void) const;
Dictionary::Ptr GetScope(void) const;
static ConfigItem::Ptr GetObject(const String& type, static ConfigItem::Ptr GetObject(const String& type,
const String& name); const String& name);
static bool HasObject(const String& type, const String& name); static bool HasObject(const String& type, const String& name);
@ -80,9 +82,11 @@ private:
bool m_Validated; /** Whether this object has been validated. */ bool m_Validated; /** Whether this object has been validated. */
AExpression::Ptr m_ExpressionList; AExpression::Ptr m_ExpressionList;
Dictionary::Ptr m_Properties;
std::vector<String> m_ParentNames; /**< The names of parent configuration std::vector<String> m_ParentNames; /**< The names of parent configuration
items. */ items. */
DebugInfo m_DebugInfo; /**< Debug information. */ DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
AExpression::Ptr m_LinkedExpressionList; AExpression::Ptr m_LinkedExpressionList;

View File

@ -55,6 +55,11 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
m_Abstract = abstract; m_Abstract = abstract;
} }
void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
{
m_Scope = scope;
}
void ConfigItemBuilder::AddParent(const String& parent) void ConfigItemBuilder::AddParent(const String& parent)
{ {
m_Parents.push_back(parent); m_Parents.push_back(parent);
@ -91,12 +96,12 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
} }
Array::Ptr exprs = make_shared<Array>(); Array::Ptr exprs = make_shared<Array>();
exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__type", make_shared<AExpression>(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo)); exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__type", make_shared<AExpression>(&AExpression::OpLiteral, m_Type, m_DebugInfo), m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo)); exprs->Add(make_shared<AExpression>(&AExpression::OpSet, "__name", make_shared<AExpression>(&AExpression::OpLiteral, m_Name, m_DebugInfo), m_DebugInfo));
exprs->Add(make_shared<AExpression>(&AExpression::OpDict, m_Expressions, true, m_DebugInfo));
AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo); AExpression::Ptr exprl = make_shared<AExpression>(&AExpression::OpDict, exprs, true, m_DebugInfo);
return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl, return make_shared<ConfigItem>(m_Type, m_Name, m_Abstract, exprl,
m_Parents, m_DebugInfo); m_Parents, m_DebugInfo, m_Scope);
} }

View File

@ -45,6 +45,7 @@ public:
void SetType(const String& type); void SetType(const String& type);
void SetName(const String& name); void SetName(const String& name);
void SetAbstract(bool abstract); void SetAbstract(bool abstract);
void SetScope(const Dictionary::Ptr& scope);
void AddParent(const String& parent); void AddParent(const String& parent);
@ -60,6 +61,7 @@ private:
items. */ items. */
Array::Ptr m_Expressions; /**< Expressions for this item. */ Array::Ptr m_Expressions; /**< Expressions for this item. */
DebugInfo m_DebugInfo; /**< Debug information. */ DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
}; };
} }

View File

@ -77,6 +77,7 @@ void Host::EvaluateApplyRules(const std::vector<ApplyRule>& rules)
ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo()); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(rule.GetDebugInfo());
builder->SetType("Service"); builder->SetType("Service");
builder->SetName(name); builder->SetName(name);
builder->SetScope(rule.GetScope());
builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo())); builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, "host", make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), rule.GetDebugInfo()), rule.GetDebugInfo()));
builder->AddParent(rule.GetTemplate()); builder->AddParent(rule.GetTemplate());

View File

@ -155,6 +155,8 @@ void Host::UpdateSlaveServices(void)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, svc_exprl, true, di)); builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, svc_exprl, true, di));
builder->SetScope(item->GetScope());
ConfigItem::Ptr serviceItem = builder->Compile(); ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register(); serviceItem->Register();
DynamicObject::Ptr dobj = serviceItem->Commit(); DynamicObject::Ptr dobj = serviceItem->Commit();

View File

@ -231,6 +231,8 @@ void Service::UpdateSlaveDependencies(void)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di)); builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
builder->SetScope(item->GetScope());
ConfigItem::Ptr dependencyItem = builder->Compile(); ConfigItem::Ptr dependencyItem = builder->Compile();
dependencyItem->Register(); dependencyItem->Register();
DynamicObject::Ptr dobj = dependencyItem->Commit(); DynamicObject::Ptr dobj = dependencyItem->Commit();

View File

@ -380,6 +380,8 @@ void Service::UpdateSlaveScheduledDowntimes(void)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di)); builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, sd_exprl, true, di));
builder->SetScope(item->GetScope());
ConfigItem::Ptr scheduledDowntimeItem = builder->Compile(); ConfigItem::Ptr scheduledDowntimeItem = builder->Compile();
scheduledDowntimeItem->Register(); scheduledDowntimeItem->Register();
DynamicObject::Ptr dobj = scheduledDowntimeItem->Commit(); DynamicObject::Ptr dobj = scheduledDowntimeItem->Commit();

View File

@ -159,6 +159,8 @@ void Service::UpdateSlaveNotifications(void)
builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, nfc_exprl, true, di)); builder->AddExpression(make_shared<AExpression>(&AExpression::OpDict, nfc_exprl, true, di));
builder->SetScope(item->GetScope());
ConfigItem::Ptr notificationItem = builder->Compile(); ConfigItem::Ptr notificationItem = builder->Compile();
notificationItem->Register(); notificationItem->Register();
DynamicObject::Ptr dobj = notificationItem->Commit(); DynamicObject::Ptr dobj = notificationItem->Commit();