Index: tools/gn/parse_tree.cc |
diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc |
index 4015fd1f353149acfd0d610b5f7eddc3cf52c608..f93b53854d55944507015a037bb6c7e95dcd4074 100644 |
--- a/tools/gn/parse_tree.cc |
+++ b/tools/gn/parse_tree.cc |
@@ -53,10 +53,25 @@ const AccessorNode* AccessorNode::AsAccessor() const { |
} |
Value AccessorNode::Execute(Scope* scope, Err* err) const { |
- if (index_) |
+ if (index_) { |
return ExecuteArrayAccess(scope, err); |
- else if (member_) |
- return ExecuteScopeAccess(scope, err); |
+ } else if (member_) { |
+ const Value* value = scope->GetValue(base_.value(), true); |
+ if (!value) { |
+ *err = MakeErrorDescribing("Undefined identifier."); |
+ return Value(); |
+ } |
+ if (value->type() == Value::SCOPE) { |
+ return ExecuteScopeAccess(scope, err); |
+ } else if (value->type() == Value::DICT) { |
+ return ExecuteDictAccess(value, err); |
+ } else { |
+ *err = MakeErrorDescribing( |
+ std::string("Type \"") + Value::DescribeType(value->type()) + |
+ "\" is not usable with the '.' operator."); |
+ return Value(); |
+ } |
+ } |
NOTREACHED(); |
return Value(); |
} |
@@ -165,6 +180,17 @@ Value AccessorNode::ExecuteScopeAccess(Scope* scope, Err* err) const { |
return *result; |
} |
+Value AccessorNode::ExecuteDictAccess(const Value* dict, Err* err) const { |
+ std::map<std::string, Value>::const_iterator found = |
+ dict->dict_value().find(member_->value().value().as_string()); |
+ if (found == dict->dict_value().end()) { |
+ *err = Err(member_.get(), "No value named \"" + |
+ member_->value().value() + "\" in scope \"" + base_.value() + "\""); |
+ return Value(); |
+ } |
+ return found->second; |
+} |
+ |
// BinaryOpNode --------------------------------------------------------------- |
BinaryOpNode::BinaryOpNode() { |