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)
{
Dictionary::Ptr dict = locals->Get(expr->m_Operand1);
Dictionary::Ptr dict = OpVariable(expr, locals);
if (!dict)
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::CallbackMap ApplyRule::m_Callbacks;
ApplyRule::ApplyRule(const String& tmpl, const AExpression::Ptr& expression, const DebugInfo& di)
: m_Template(tmpl), m_Expression(expression), m_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_Scope(scope)
{ }
String ApplyRule::GetTemplate(void) const
@ -43,9 +43,14 @@ DebugInfo ApplyRule::GetDebugInfo(void) const
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)

View File

@ -42,8 +42,9 @@ public:
String GetTemplate(void) const;
AExpression::Ptr GetExpression(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 RegisterCombination(const String& sourceType, const String& targetType, const ApplyRule::Callback& callback);
@ -53,11 +54,12 @@ private:
String m_Template;
AExpression::Ptr m_Expression;
DebugInfo m_DebugInfo;
Dictionary::Ptr m_Scope;
static CallbackMap m_Callbacks;
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->SetScope(m_ModuleScope);
item->Compile()->Register();
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);
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,
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_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;
}
Dictionary::Ptr ConfigItem::GetScope(void) const
{
return m_Scope;
}
/**
* Retrieves the expression list for the configuration item.
*
@ -145,9 +152,14 @@ Dictionary::Ptr ConfigItem::GetProperties(void)
{
ASSERT(OwnsLock());
Dictionary::Ptr properties = make_shared<Dictionary>();
GetLinkedExpressionList()->Evaluate(properties);
return properties;
if (!m_Properties) {
m_Properties = make_shared<Dictionary>();
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,
const AExpression::Ptr& exprl, const std::vector<String>& parents,
const DebugInfo& debuginfo);
const DebugInfo& debuginfo, const Dictionary::Ptr& scope);
String GetType(void) const;
String GetName(void) const;
@ -62,6 +62,8 @@ public:
DebugInfo GetDebugInfo(void) const;
Dictionary::Ptr GetScope(void) const;
static ConfigItem::Ptr GetObject(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. */
AExpression::Ptr m_ExpressionList;
Dictionary::Ptr m_Properties;
std::vector<String> m_ParentNames; /**< The names of parent configuration
items. */
DebugInfo m_DebugInfo; /**< Debug information. */
Dictionary::Ptr m_Scope; /**< variable scope. */
AExpression::Ptr m_LinkedExpressionList;

View File

@ -55,6 +55,11 @@ void ConfigItemBuilder::SetAbstract(bool abstract)
m_Abstract = abstract;
}
void ConfigItemBuilder::SetScope(const Dictionary::Ptr& scope)
{
m_Scope = scope;
}
void ConfigItemBuilder::AddParent(const String& parent)
{
m_Parents.push_back(parent);
@ -91,12 +96,12 @@ ConfigItem::Ptr ConfigItemBuilder::Compile(void)
}
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, "__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);
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 SetName(const String& name);
void SetAbstract(bool abstract);
void SetScope(const Dictionary::Ptr& scope);
void AddParent(const String& parent);
@ -60,6 +61,7 @@ private:
items. */
Array::Ptr m_Expressions; /**< Expressions for this item. */
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());
builder->SetType("Service");
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->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->SetScope(item->GetScope());
ConfigItem::Ptr serviceItem = builder->Compile();
serviceItem->Register();
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->SetScope(item->GetScope());
ConfigItem::Ptr dependencyItem = builder->Compile();
dependencyItem->Register();
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->SetScope(item->GetScope());
ConfigItem::Ptr scheduledDowntimeItem = builder->Compile();
scheduledDowntimeItem->Register();
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->SetScope(item->GetScope());
ConfigItem::Ptr notificationItem = builder->Compile();
notificationItem->Register();
DynamicObject::Ptr dobj = notificationItem->Commit();