From d72bd4fec2a814a9c54ad500c9463c895beede73 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Mon, 15 Dec 2014 17:23:18 +0100 Subject: [PATCH] Add another unit test for expressions refs #8074 --- lib/config/expression.cpp | 8 ++++---- lib/config/vmops.hpp | 20 +++++++++++++------- test/config-ops.cpp | 4 ++++ 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/lib/config/expression.cpp b/lib/config/expression.cpp index a2cc2b09f..e6bdcf4d1 100644 --- a/lib/config/expression.cpp +++ b/lib/config/expression.cpp @@ -263,7 +263,7 @@ Value FunctionCallExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) c String index; if (m_FName->GetReference(frame, false, &self, &index)) - vfunc = VMOps::GetField(self, index); + vfunc = VMOps::GetField(self, index, m_DebugInfo); else vfunc = m_FName->Evaluate(frame); @@ -343,7 +343,7 @@ Value SetExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const Value right = m_Operand2->Evaluate(frame, dhint); if (m_Op != OpSetLiteral) { - Value object = VMOps::GetField(parent, index); + Value object = VMOps::GetField(parent, index, m_DebugInfo); Expression *lhs = MakeLiteral(object); Expression *rhs = MakeLiteral(right); @@ -409,7 +409,7 @@ Value IndexerExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const { Value object = m_Operand1->Evaluate(frame, dhint); String index = m_Operand2->Evaluate(frame, dhint); - return VMOps::GetField(object, index); + return VMOps::GetField(object, index, m_DebugInfo); } bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const @@ -421,7 +421,7 @@ bool IndexerExpression::GetReference(ScriptFrame& frame, bool init_dict, Value * if (init_dict && VMOps::GetField(vparent, vindex).IsEmpty()) VMOps::SetField(vparent, vindex, new Dictionary()); - *parent = VMOps::GetField(vparent, vindex); + *parent = VMOps::GetField(vparent, vindex, m_DebugInfo); } else *parent = m_Operand1->Evaluate(frame); diff --git a/lib/config/vmops.hpp b/lib/config/vmops.hpp index be035d649..184da244b 100644 --- a/lib/config/vmops.hpp +++ b/lib/config/vmops.hpp @@ -186,7 +186,7 @@ public: } } - static inline Value GetPrototypeField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo()) + static inline Value GetPrototypeField(const Value& context, const String& field, bool not_found_error = true, const DebugInfo& debugInfo = DebugInfo()) { Type::Ptr type = context.GetReflectionType(); @@ -194,18 +194,24 @@ public: Object::Ptr object = type->GetPrototype(); if (HasField(object, field)) - return GetField(object, field); + return GetField(object, field, debugInfo); type = type->GetBaseType(); } while (type); - return Empty; + if (not_found_error) + BOOST_THROW_EXCEPTION(ScriptError("Invalid field name: '" + field + "'", debugInfo)); + else + return Empty; } static inline Value GetField(const Value& context, const String& field, const DebugInfo& debugInfo = DebugInfo()) { + if (context.IsEmpty()) + return Empty; + if (!context.IsObject()) - return GetPrototypeField(context, field); + return GetPrototypeField(context, field, true, debugInfo); Object::Ptr object = context; @@ -215,7 +221,7 @@ public: if (dict->Contains(field)) return dict->Get(field); else - return GetPrototypeField(context, field); + return GetPrototypeField(context, field, false, debugInfo); } Array::Ptr arr = dynamic_pointer_cast(object); @@ -226,7 +232,7 @@ public: try { index = Convert::ToLong(field); } catch (...) { - return GetPrototypeField(context, field); + return GetPrototypeField(context, field, true, debugInfo); } return arr->Get(index); @@ -240,7 +246,7 @@ public: int fid = type->GetFieldId(field); if (fid == -1) - return GetPrototypeField(context, field); + return GetPrototypeField(context, field, true, debugInfo); return object->GetField(fid); } diff --git a/test/config-ops.cpp b/test/config-ops.cpp index ca74749cf..db16a017e 100644 --- a/test/config-ops.cpp +++ b/test/config-ops.cpp @@ -307,6 +307,10 @@ BOOST_AUTO_TEST_CASE(advanced) expr = ConfigCompiler::CompileText("", "var e = 3; e"); BOOST_CHECK(expr->Evaluate(frame) == 3); delete expr; + + expr = ConfigCompiler::CompileText("", "Array.x"); + BOOST_CHECK_THROW(expr->Evaluate(frame), ScriptError); + delete expr; } BOOST_AUTO_TEST_SUITE_END()