LibJS: Improve CallExpression::execute()'s error messages

This commit is contained in:
Linus Groh 2020-04-19 01:12:51 +01:00 committed by Andreas Kling
parent 4e9643981f
commit 03f2024b6e
Notes: sideshowbarker 2024-07-19 07:29:08 +09:00
2 changed files with 29 additions and 9 deletions

View file

@ -92,17 +92,24 @@ Value CallExpression::execute(Interpreter& interpreter) const
ASSERT(!callee.is_empty());
if (is_new_expression()) {
if (!callee.is_object()
|| !callee.as_object().is_function()
|| (callee.as_object().is_native_function()
&& !static_cast<NativeFunction&>(callee.as_object()).has_constructor()))
return interpreter.throw_exception<TypeError>(String::format("%s is not a constructor", callee.to_string().characters()));
if (!callee.is_object()
|| !callee.as_object().is_function()
|| (callee.as_object().is_native_function() && !static_cast<NativeFunction&>(callee.as_object()).has_constructor())) {
String error_message;
auto call_type = is_new_expression() ? "constructor" : "function";
if (m_callee->is_identifier() || m_callee->is_member_expression()) {
String expression_string;
if (m_callee->is_identifier())
expression_string = static_cast<const Identifier&>(*m_callee).string();
else
expression_string = static_cast<const MemberExpression&>(*m_callee).to_string_approximation();
error_message = String::format("%s is not a %s (evaluated from '%s')", callee.to_string().characters(), call_type, expression_string.characters());
} else {
error_message = String::format("%s is not a %s", callee.to_string().characters(), call_type);
}
return interpreter.throw_exception<TypeError>(error_message);
}
if (!callee.is_object() || !callee.as_object().is_function())
return interpreter.throw_exception<TypeError>(String::format("%s is not a function", callee.to_string().characters()));
auto& function = static_cast<Function&>(callee.as_object());
Vector<Value> arguments;
@ -943,6 +950,17 @@ PropertyName MemberExpression::computed_property_name(Interpreter& interpreter)
return PropertyName(index.to_string());
}
String MemberExpression::to_string_approximation() const
{
String object_string = "<object>";
if (m_object->is_identifier())
object_string = static_cast<const Identifier&>(*m_object).string();
if (is_computed())
return String::format("%s[<computed>]", object_string.characters());
ASSERT(m_property->is_identifier());
return String::format("%s.%s", object_string.characters(), static_cast<const Identifier&>(*m_property).string().characters());
}
Value MemberExpression::execute(Interpreter& interpreter) const
{
auto object_value = m_object->execute(interpreter);

View file

@ -716,6 +716,8 @@ public:
PropertyName computed_property_name(Interpreter&) const;
String to_string_approximation() const;
private:
virtual bool is_member_expression() const override { return true; }
virtual const char* class_name() const override { return "MemberExpression"; }