浏览代码

LibJS: Track source positions all the way down to exceptions

This makes exceptions have a trace of source positions too, which could
probably be helpful in making fancier error tracebacks.
AnotherTest 4 年之前
父节点
当前提交
b34b681811

+ 166 - 13
Libraries/LibJS/AST.cpp

@@ -88,26 +88,41 @@ static String get_function_name(GlobalObject& global_object, Value value)
 
 Value ScopeNode::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return interpreter.execute_statement(global_object, *this);
 }
 
 Value Program::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return interpreter.execute_statement(global_object, *this, ScopeType::Block);
 }
 
-Value FunctionDeclaration::execute(Interpreter&, GlobalObject&) const
+Value FunctionDeclaration::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return js_undefined();
 }
 
 Value FunctionExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return ScriptFunction::create(global_object, name(), body(), parameters(), function_length(), interpreter.current_scope(), is_strict_mode() || interpreter.vm().in_strict_mode(), m_is_arrow_function);
 }
 
 Value ExpressionStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return m_expression->execute(interpreter, global_object);
 }
 
@@ -152,6 +167,9 @@ CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interprete
 
 Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto& vm = interpreter.vm();
     auto [this_value, callee] = compute_this_and_callee(interpreter, global_object);
     if (vm.exception())
@@ -235,6 +253,9 @@ Value CallExpression::execute(Interpreter& interpreter, GlobalObject& global_obj
 
 Value ReturnStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto value = argument() ? argument()->execute(interpreter, global_object) : js_undefined();
     if (interpreter.exception())
         return {};
@@ -244,6 +265,9 @@ Value ReturnStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
 
 Value IfStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto predicate_result = m_predicate->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -259,6 +283,9 @@ Value IfStatement::execute(Interpreter& interpreter, GlobalObject& global_object
 
 Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto object_value = m_object->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -277,6 +304,9 @@ Value WithStatement::execute(Interpreter& interpreter, GlobalObject& global_obje
 
 Value WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     Value last_value = js_undefined();
     for (;;) {
         auto test_result = m_test->execute(interpreter, global_object);
@@ -304,6 +334,9 @@ Value WhileStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
 
 Value DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     Value last_value = js_undefined();
     for (;;) {
         if (interpreter.exception())
@@ -333,10 +366,13 @@ Value DoWhileStatement::execute(Interpreter& interpreter, GlobalObject& global_o
 
 Value ForStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     RefPtr<BlockStatement> wrapper;
 
     if (m_init && m_init->is_variable_declaration() && static_cast<const VariableDeclaration*>(m_init.ptr())->declaration_kind() != DeclarationKind::Var) {
-        wrapper = create_ast_node<BlockStatement>();
+        wrapper = create_ast_node<BlockStatement>(source_range());
         NonnullRefPtrVector<VariableDeclaration> decls;
         decls.append(*static_cast<const VariableDeclaration*>(m_init.ptr()));
         wrapper->add_variables(decls);
@@ -415,7 +451,7 @@ static FlyString variable_from_for_declaration(Interpreter& interpreter, GlobalO
         auto* variable_declaration = static_cast<const VariableDeclaration*>(node.ptr());
         ASSERT(!variable_declaration->declarations().is_empty());
         if (variable_declaration->declaration_kind() != DeclarationKind::Var) {
-            wrapper = create_ast_node<BlockStatement>();
+            wrapper = create_ast_node<BlockStatement>(node->source_range());
             interpreter.enter_scope(*wrapper, ScopeType::Block, global_object);
         }
         variable_declaration->execute(interpreter, global_object);
@@ -430,6 +466,9 @@ static FlyString variable_from_for_declaration(Interpreter& interpreter, GlobalO
 
 Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     if (!m_lhs->is_variable_declaration() && !m_lhs->is_identifier()) {
         // FIXME: Implement "for (foo.bar in baz)", "for (foo[0] in bar)"
         ASSERT_NOT_REACHED();
@@ -474,6 +513,9 @@ Value ForInStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
 
 Value ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     if (!m_lhs->is_variable_declaration() && !m_lhs->is_identifier()) {
         // FIXME: Implement "for (foo.bar of baz)", "for (foo[0] of bar)"
         ASSERT_NOT_REACHED();
@@ -515,6 +557,9 @@ Value ForOfStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
 
 Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto lhs_result = m_lhs->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -574,6 +619,9 @@ Value BinaryExpression::execute(Interpreter& interpreter, GlobalObject& global_o
 
 Value LogicalExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto lhs_result = m_lhs->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -631,6 +679,9 @@ Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject&
 
 Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto& vm = interpreter.vm();
     if (m_op == UnaryOp::Delete) {
         auto reference = m_lhs->to_reference(interpreter, global_object);
@@ -713,19 +764,28 @@ Value UnaryExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
     ASSERT_NOT_REACHED();
 }
 
-Value SuperExpression::execute(Interpreter&, GlobalObject&) const
+Value SuperExpression::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // The semantics for SuperExpressions are handled in CallExpression::compute_this_and_callee()
     ASSERT_NOT_REACHED();
 }
 
 Value ClassMethod::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return m_function->execute(interpreter, global_object);
 }
 
 Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto& vm = interpreter.vm();
     Value class_constructor_value = m_constructor->execute(interpreter, global_object);
     if (interpreter.exception())
@@ -812,6 +872,9 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
 
 Value ClassDeclaration::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     Value class_constructor = m_class_expression->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -1224,6 +1287,9 @@ void ForOfStatement::dump(int indent) const
 
 Value Identifier::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto value = interpreter.vm().get_variable(string(), global_object);
     if (value.is_empty()) {
         interpreter.vm().throw_exception<ReferenceError>(global_object, ErrorType::UnknownIdentifier, string());
@@ -1246,11 +1312,17 @@ void SpreadExpression::dump(int indent) const
 
 Value SpreadExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return m_target->execute(interpreter, global_object);
 }
 
 Value ThisExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return interpreter.vm().resolve_this_binding(global_object);
 }
 
@@ -1261,6 +1333,9 @@ void ThisExpression::dump(int indent) const
 
 Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
 #define EXECUTE_LHS_AND_RHS()                                    \
     do {                                                         \
         lhs_result = m_lhs->execute(interpreter, global_object); \
@@ -1376,6 +1451,9 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob
 
 Value UpdateExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto reference = m_argument->to_reference(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -1497,6 +1575,9 @@ void UpdateExpression::dump(int indent) const
 
 Value VariableDeclaration::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     for (auto& declarator : m_declarations) {
         if (auto* init = declarator.init()) {
             auto initalizer_result = init->execute(interpreter, global_object);
@@ -1510,8 +1591,11 @@ Value VariableDeclaration::execute(Interpreter& interpreter, GlobalObject& globa
     return js_undefined();
 }
 
-Value VariableDeclarator::execute(Interpreter&, GlobalObject&) const
+Value VariableDeclarator::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // NOTE: VariableDeclarator execution is handled by VariableDeclaration.
     ASSERT_NOT_REACHED();
 }
@@ -1568,14 +1652,20 @@ void ExpressionStatement::dump(int indent) const
     m_expression->dump(indent + 1);
 }
 
-Value ObjectProperty::execute(Interpreter&, GlobalObject&) const
+Value ObjectProperty::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // NOTE: ObjectProperty execution is handled by ObjectExpression.
     ASSERT_NOT_REACHED();
 }
 
 Value ObjectExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto* object = Object::create_empty(global_object);
     for (auto& property : m_properties) {
         auto key = property.key().execute(interpreter, global_object);
@@ -1677,6 +1767,9 @@ String MemberExpression::to_string_approximation() const
 
 Value MemberExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto object_value = m_object->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -1704,6 +1797,9 @@ void MetaProperty::dump(int indent) const
 
 Value MetaProperty::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     if (m_type == MetaProperty::Type::NewTarget)
         return interpreter.vm().get_new_target().value_or(js_undefined());
     if (m_type == MetaProperty::Type::ImportMeta)
@@ -1713,26 +1809,41 @@ Value MetaProperty::execute(Interpreter& interpreter, GlobalObject&) const
 
 Value StringLiteral::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return js_string(interpreter.heap(), m_value);
 }
 
-Value NumericLiteral::execute(Interpreter&, GlobalObject&) const
+Value NumericLiteral::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return Value(m_value);
 }
 
 Value BigIntLiteral::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1)));
 }
 
-Value BooleanLiteral::execute(Interpreter&, GlobalObject&) const
+Value BooleanLiteral::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return Value(m_value);
 }
 
-Value NullLiteral::execute(Interpreter&, GlobalObject&) const
+Value NullLiteral::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return js_null();
 }
 
@@ -1742,8 +1853,11 @@ void RegExpLiteral::dump(int indent) const
     outln("{} (/{}/{})", class_name(), content(), flags());
 }
 
-Value RegExpLiteral::execute(Interpreter&, GlobalObject& global_object) const
+Value RegExpLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     return RegExpObject::create(global_object, content(), flags());
 }
 
@@ -1762,6 +1876,9 @@ void ArrayExpression::dump(int indent) const
 
 Value ArrayExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto* array = Array::create(global_object);
     for (auto& element : m_elements) {
         auto value = Value();
@@ -1794,6 +1911,9 @@ void TemplateLiteral::dump(int indent) const
 
 Value TemplateLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     StringBuilder string_builder;
 
     for (auto& expression : m_expressions) {
@@ -1822,6 +1942,9 @@ void TaggedTemplateLiteral::dump(int indent) const
 
 Value TaggedTemplateLiteral::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto& vm = interpreter.vm();
     auto tag = m_tag->execute(interpreter, global_object);
     if (vm.exception())
@@ -1897,6 +2020,9 @@ void ThrowStatement::dump(int indent) const
 
 Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     interpreter.execute_statement(global_object, m_block, ScopeType::Try);
     if (auto* exception = interpreter.exception()) {
         if (m_handler) {
@@ -1928,8 +2054,11 @@ Value TryStatement::execute(Interpreter& interpreter, GlobalObject& global_objec
     return js_undefined();
 }
 
-Value CatchClause::execute(Interpreter&, GlobalObject&) const
+Value CatchClause::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // NOTE: CatchClause execution is handled by TryStatement.
     ASSERT_NOT_REACHED();
     return {};
@@ -1937,6 +2066,9 @@ Value CatchClause::execute(Interpreter&, GlobalObject&) const
 
 Value ThrowStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto value = m_argument->execute(interpreter, global_object);
     if (interpreter.vm().exception())
         return {};
@@ -1946,6 +2078,9 @@ Value ThrowStatement::execute(Interpreter& interpreter, GlobalObject& global_obj
 
 Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto discriminant_result = m_discriminant->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -1983,8 +2118,11 @@ Value SwitchStatement::execute(Interpreter& interpreter, GlobalObject& global_ob
     return js_undefined();
 }
 
-Value SwitchCase::execute(Interpreter&, GlobalObject&) const
+Value SwitchCase::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // NOTE: SwitchCase execution is handled by SwitchStatement.
     ASSERT_NOT_REACHED();
     return {};
@@ -1992,12 +2130,18 @@ Value SwitchCase::execute(Interpreter&, GlobalObject&) const
 
 Value BreakStatement::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     interpreter.vm().unwind(ScopeType::Breakable, m_target_label);
     return js_undefined();
 }
 
 Value ContinueStatement::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     interpreter.vm().unwind(ScopeType::Continuable, m_target_label);
     return js_undefined();
 }
@@ -2029,6 +2173,9 @@ void SwitchCase::dump(int indent) const
 
 Value ConditionalExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     auto test_result = m_test->execute(interpreter, global_object);
     if (interpreter.exception())
         return {};
@@ -2066,6 +2213,9 @@ void SequenceExpression::dump(int indent) const
 
 Value SequenceExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     Value last_value;
     for (auto& expression : m_expressions) {
         last_value = expression.execute(interpreter, global_object);
@@ -2075,8 +2225,11 @@ Value SequenceExpression::execute(Interpreter& interpreter, GlobalObject& global
     return last_value;
 }
 
-Value DebuggerStatement::execute(Interpreter&, GlobalObject&) const
+Value DebuggerStatement::execute(Interpreter& interpreter, GlobalObject&) const
 {
+    interpreter.enter_node(*this);
+    ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } };
+
     // Sorry, no JavaScript debugger available (yet)!
     return js_undefined();
 }

+ 220 - 107
Libraries/LibJS/AST.h

@@ -36,6 +36,7 @@
 #include <LibJS/Forward.h>
 #include <LibJS/Runtime/PropertyName.h>
 #include <LibJS/Runtime/Value.h>
+#include <LibJS/SourceRange.h>
 
 namespace JS {
 
@@ -44,9 +45,9 @@ class FunctionDeclaration;
 
 template<class T, class... Args>
 static inline NonnullRefPtr<T>
-create_ast_node(Args&&... args)
+create_ast_node(SourceRange range, Args&&... args)
 {
-    return adopt(*new T(forward<Args>(args)...));
+    return adopt(*new T(range, forward<Args>(args)...));
 }
 
 class ASTNode : public RefCounted<ASTNode> {
@@ -67,14 +68,26 @@ public:
     virtual bool is_expression_statement() const { return false; };
     virtual bool is_string_literal() const { return false; };
 
+    const SourceRange& source_range() const { return m_source_range; }
+    SourceRange& source_range() { return m_source_range; }
+
 protected:
-    ASTNode() { }
+    ASTNode(SourceRange source_range)
+        : m_source_range(move(source_range))
+    {
+    }
 
 private:
+    SourceRange m_source_range;
 };
 
 class Statement : public ASTNode {
 public:
+    Statement(SourceRange source_range)
+        : ASTNode(move(source_range))
+    {
+    }
+
     const FlyString& label() const { return m_label; }
     void set_label(FlyString string) { m_label = string; }
 
@@ -84,20 +97,29 @@ protected:
 
 class EmptyStatement final : public Statement {
 public:
+    EmptyStatement(SourceRange source_range)
+        : Statement(move(source_range))
+    {
+    }
     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
     const char* class_name() const override { return "EmptyStatement"; }
 };
 
 class ErrorStatement final : public Statement {
 public:
+    ErrorStatement(SourceRange source_range)
+        : Statement(move(source_range))
+    {
+    }
     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
     const char* class_name() const override { return "ErrorStatement"; }
 };
 
 class ExpressionStatement final : public Statement {
 public:
-    ExpressionStatement(NonnullRefPtr<Expression> expression)
-        : m_expression(move(expression))
+    ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression> expression)
+        : Statement(move(source_range))
+        , m_expression(move(expression))
     {
     }
 
@@ -116,9 +138,9 @@ private:
 class ScopeNode : public Statement {
 public:
     template<typename T, typename... Args>
-    T& append(Args&&... args)
+    T& append(SourceRange range, Args&&... args)
     {
-        auto child = create_ast_node<T>(forward<Args>(args)...);
+        auto child = create_ast_node<T>(range, forward<Args>(args)...);
         m_children.append(move(child));
         return static_cast<T&>(m_children.last());
     }
@@ -137,7 +159,10 @@ public:
     const NonnullRefPtrVector<FunctionDeclaration>& functions() const { return m_functions; }
 
 protected:
-    ScopeNode() { }
+    ScopeNode(SourceRange source_range)
+        : Statement(move(source_range))
+    {
+    }
 
 private:
     virtual bool is_scope_node() const final { return true; }
@@ -148,7 +173,10 @@ private:
 
 class Program final : public ScopeNode {
 public:
-    Program() { }
+    Program(SourceRange source_range)
+        : ScopeNode(move(source_range))
+    {
+    }
 
     virtual Value execute(Interpreter&, GlobalObject&) const override;
 
@@ -164,7 +192,10 @@ private:
 
 class BlockStatement final : public ScopeNode {
 public:
-    BlockStatement() { }
+    BlockStatement(SourceRange source_range)
+        : ScopeNode(move(source_range))
+    {
+    }
 
 private:
     virtual const char* class_name() const override { return "BlockStatement"; }
@@ -172,14 +203,27 @@ private:
 
 class Expression : public ASTNode {
 public:
+    Expression(SourceRange source_range)
+        : ASTNode(move(source_range))
+    {
+    }
     virtual Reference to_reference(Interpreter&, GlobalObject&) const;
 };
 
 class Declaration : public Statement {
+public:
+    Declaration(SourceRange source_range)
+        : Statement(move(source_range))
+    {
+    }
 };
 
 class ErrorDeclaration final : public Declaration {
 public:
+    ErrorDeclaration(SourceRange source_range)
+        : Declaration(move(source_range))
+    {
+    }
     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
     const char* class_name() const override { return "ErrorDeclaration"; }
 };
@@ -228,8 +272,9 @@ class FunctionDeclaration final
 public:
     static bool must_have_name() { return true; }
 
-    FunctionDeclaration(const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode = false)
-        : FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
+    FunctionDeclaration(SourceRange source_range, const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode = false)
+        : Declaration(move(source_range))
+        , FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
     {
     }
 
@@ -246,8 +291,9 @@ class FunctionExpression final
 public:
     static bool must_have_name() { return false; }
 
-    FunctionExpression(const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode, bool is_arrow_function = false)
-        : FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
+    FunctionExpression(SourceRange source_range, const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode, bool is_arrow_function = false)
+        : Expression(move(source_range))
+        , FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
         , m_is_arrow_function(is_arrow_function)
     {
     }
@@ -263,14 +309,20 @@ private:
 
 class ErrorExpression final : public Expression {
 public:
+    explicit ErrorExpression(SourceRange source_range)
+        : Expression(move(source_range))
+    {
+    }
+
     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
     const char* class_name() const override { return "ErrorExpression"; }
 };
 
 class ReturnStatement final : public Statement {
 public:
-    explicit ReturnStatement(RefPtr<Expression> argument)
-        : m_argument(move(argument))
+    explicit ReturnStatement(SourceRange source_range, RefPtr<Expression> argument)
+        : Statement(move(source_range))
+        , m_argument(move(argument))
     {
     }
 
@@ -287,8 +339,9 @@ private:
 
 class IfStatement final : public Statement {
 public:
-    IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate)
-        : m_predicate(move(predicate))
+    IfStatement(SourceRange source_range, NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate)
+        : Statement(move(source_range))
+        , m_predicate(move(predicate))
         , m_consequent(move(consequent))
         , m_alternate(move(alternate))
     {
@@ -311,8 +364,9 @@ private:
 
 class WhileStatement final : public Statement {
 public:
-    WhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
-        : m_test(move(test))
+    WhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_test(move(test))
         , m_body(move(body))
     {
     }
@@ -332,8 +386,9 @@ private:
 
 class DoWhileStatement final : public Statement {
 public:
-    DoWhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
-        : m_test(move(test))
+    DoWhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_test(move(test))
         , m_body(move(body))
     {
     }
@@ -353,8 +408,9 @@ private:
 
 class WithStatement final : public Statement {
 public:
-    WithStatement(NonnullRefPtr<Expression> object, NonnullRefPtr<Statement> body)
-        : m_object(move(object))
+    WithStatement(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_object(move(object))
         , m_body(move(body))
     {
     }
@@ -374,8 +430,9 @@ private:
 
 class ForStatement final : public Statement {
 public:
-    ForStatement(RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body)
-        : m_init(move(init))
+    ForStatement(SourceRange source_range, RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_init(move(init))
         , m_test(move(test))
         , m_update(move(update))
         , m_body(move(body))
@@ -401,8 +458,9 @@ private:
 
 class ForInStatement final : public Statement {
 public:
-    ForInStatement(NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
-        : m_lhs(move(lhs))
+    ForInStatement(SourceRange source_range, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_lhs(move(lhs))
         , m_rhs(move(rhs))
         , m_body(move(body))
     {
@@ -425,8 +483,9 @@ private:
 
 class ForOfStatement final : public Statement {
 public:
-    ForOfStatement(NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
-        : m_lhs(move(lhs))
+    ForOfStatement(SourceRange source_range, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
+        : Statement(move(source_range))
+        , m_lhs(move(lhs))
         , m_rhs(move(rhs))
         , m_body(move(body))
     {
@@ -474,8 +533,9 @@ enum class BinaryOp {
 
 class BinaryExpression final : public Expression {
 public:
-    BinaryExpression(BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
-        : m_op(op)
+    BinaryExpression(SourceRange source_range, BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
+        : Expression(move(source_range))
+        , m_op(op)
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
     {
@@ -500,8 +560,9 @@ enum class LogicalOp {
 
 class LogicalExpression final : public Expression {
 public:
-    LogicalExpression(LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
-        : m_op(op)
+    LogicalExpression(SourceRange source_range, LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
+        : Expression(move(source_range))
+        , m_op(op)
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
     {
@@ -530,8 +591,9 @@ enum class UnaryOp {
 
 class UnaryExpression final : public Expression {
 public:
-    UnaryExpression(UnaryOp op, NonnullRefPtr<Expression> lhs)
-        : m_op(op)
+    UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression> lhs)
+        : Expression(move(source_range))
+        , m_op(op)
         , m_lhs(move(lhs))
     {
     }
@@ -548,8 +610,9 @@ private:
 
 class SequenceExpression final : public Expression {
 public:
-    SequenceExpression(NonnullRefPtrVector<Expression> expressions)
-        : m_expressions(move(expressions))
+    SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
+        : Expression(move(source_range))
+        , m_expressions(move(expressions))
     {
     }
 
@@ -564,13 +627,17 @@ private:
 
 class Literal : public Expression {
 protected:
-    explicit Literal() { }
+    explicit Literal(SourceRange source_range)
+        : Expression(move(source_range))
+    {
+    }
 };
 
 class BooleanLiteral final : public Literal {
 public:
-    explicit BooleanLiteral(bool value)
-        : m_value(value)
+    explicit BooleanLiteral(SourceRange source_range, bool value)
+        : Literal(move(source_range))
+        , m_value(value)
     {
     }
 
@@ -585,8 +652,9 @@ private:
 
 class NumericLiteral final : public Literal {
 public:
-    explicit NumericLiteral(double value)
-        : m_value(value)
+    explicit NumericLiteral(SourceRange source_range, double value)
+        : Literal(move(source_range))
+        , m_value(value)
     {
     }
 
@@ -601,8 +669,9 @@ private:
 
 class BigIntLiteral final : public Literal {
 public:
-    explicit BigIntLiteral(String value)
-        : m_value(move(value))
+    explicit BigIntLiteral(SourceRange source_range, String value)
+        : Literal(move(source_range))
+        , m_value(move(value))
     {
     }
 
@@ -617,8 +686,9 @@ private:
 
 class StringLiteral final : public Literal {
 public:
-    explicit StringLiteral(String value, bool is_use_strict_directive = false)
-        : m_value(move(value))
+    explicit StringLiteral(SourceRange source_range, String value, bool is_use_strict_directive = false)
+        : Literal(move(source_range))
+        , m_value(move(value))
         , m_is_use_strict_directive(is_use_strict_directive)
     {
     }
@@ -639,7 +709,10 @@ private:
 
 class NullLiteral final : public Literal {
 public:
-    explicit NullLiteral() { }
+    explicit NullLiteral(SourceRange source_range)
+        : Literal(move(source_range))
+    {
+    }
 
     virtual Value execute(Interpreter&, GlobalObject&) const override;
     virtual void dump(int indent) const override;
@@ -650,8 +723,9 @@ private:
 
 class RegExpLiteral final : public Literal {
 public:
-    explicit RegExpLiteral(String content, String flags)
-        : m_content(content)
+    explicit RegExpLiteral(SourceRange source_range, String content, String flags)
+        : Literal(move(source_range))
+        , m_content(content)
         , m_flags(flags)
     {
     }
@@ -671,8 +745,9 @@ private:
 
 class Identifier final : public Expression {
 public:
-    explicit Identifier(const FlyString& string)
-        : m_string(string)
+    explicit Identifier(SourceRange source_range, const FlyString& string)
+        : Expression(move(source_range))
+        , m_string(string)
     {
     }
 
@@ -697,8 +772,9 @@ public:
         Setter,
     };
 
-    ClassMethod(NonnullRefPtr<Expression> key, NonnullRefPtr<FunctionExpression> function, Kind kind, bool is_static)
-        : m_key(move(key))
+    ClassMethod(SourceRange source_range, NonnullRefPtr<Expression> key, NonnullRefPtr<FunctionExpression> function, Kind kind, bool is_static)
+        : ASTNode(move(source_range))
+        , m_key(move(key))
         , m_function(move(function))
         , m_kind(kind)
         , m_is_static(is_static)
@@ -723,6 +799,11 @@ private:
 
 class SuperExpression final : public Expression {
 public:
+    SuperExpression(SourceRange source_range)
+        : Expression(move(source_range))
+    {
+    }
+
     virtual Value execute(Interpreter&, GlobalObject&) const override;
     virtual void dump(int indent) const override;
 
@@ -733,8 +814,9 @@ private:
 
 class ClassExpression final : public Expression {
 public:
-    ClassExpression(String name, RefPtr<FunctionExpression> constructor, RefPtr<Expression> super_class, NonnullRefPtrVector<ClassMethod> methods)
-        : m_name(move(name))
+    ClassExpression(SourceRange source_range, String name, RefPtr<FunctionExpression> constructor, RefPtr<Expression> super_class, NonnullRefPtrVector<ClassMethod> methods)
+        : Expression(move(source_range))
+        , m_name(move(name))
         , m_constructor(move(constructor))
         , m_super_class(move(super_class))
         , m_methods(move(methods))
@@ -757,8 +839,9 @@ private:
 
 class ClassDeclaration final : public Declaration {
 public:
-    ClassDeclaration(NonnullRefPtr<ClassExpression> class_expression)
-        : m_class_expression(move(class_expression))
+    ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression> class_expression)
+        : Declaration(move(source_range))
+        , m_class_expression(move(class_expression))
     {
     }
 
@@ -772,8 +855,9 @@ private:
 
 class SpreadExpression final : public Expression {
 public:
-    explicit SpreadExpression(NonnullRefPtr<Expression> target)
-        : m_target(target)
+    explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression> target)
+        : Expression(move(source_range))
+        , m_target(target)
     {
     }
 
@@ -789,6 +873,10 @@ private:
 
 class ThisExpression final : public Expression {
 public:
+    ThisExpression(SourceRange source_range)
+        : Expression(move(source_range))
+    {
+    }
     virtual Value execute(Interpreter&, GlobalObject&) const override;
     virtual void dump(int indent) const override;
 
@@ -803,8 +891,9 @@ public:
         bool is_spread;
     };
 
-    CallExpression(NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
-        : m_callee(move(callee))
+    CallExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
+        : Expression(move(source_range))
+        , m_callee(move(callee))
         , m_arguments(move(arguments))
     {
     }
@@ -828,8 +917,8 @@ private:
 
 class NewExpression final : public CallExpression {
 public:
-    NewExpression(NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
-        : CallExpression(move(callee), move(arguments))
+    NewExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
+        : CallExpression(move(source_range), move(callee), move(arguments))
     {
     }
 
@@ -860,8 +949,9 @@ enum class AssignmentOp {
 
 class AssignmentExpression final : public Expression {
 public:
-    AssignmentExpression(AssignmentOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
-        : m_op(op)
+    AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
+        : Expression(move(source_range))
+        , m_op(op)
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
     {
@@ -885,8 +975,9 @@ enum class UpdateOp {
 
 class UpdateExpression final : public Expression {
 public:
-    UpdateExpression(UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false)
-        : m_op(op)
+    UpdateExpression(SourceRange source_range, UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false)
+        : Expression(move(source_range))
+        , m_op(op)
         , m_argument(move(argument))
         , m_prefixed(prefixed)
     {
@@ -911,13 +1002,15 @@ enum class DeclarationKind {
 
 class VariableDeclarator final : public ASTNode {
 public:
-    VariableDeclarator(NonnullRefPtr<Identifier> id)
-        : m_id(move(id))
+    VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id)
+        : ASTNode(move(source_range))
+        , m_id(move(id))
     {
     }
 
-    VariableDeclarator(NonnullRefPtr<Identifier> id, RefPtr<Expression> init)
-        : m_id(move(id))
+    VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id, RefPtr<Expression> init)
+        : ASTNode(move(source_range))
+        , m_id(move(id))
         , m_init(move(init))
     {
     }
@@ -937,8 +1030,9 @@ private:
 
 class VariableDeclaration final : public Declaration {
 public:
-    VariableDeclaration(DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations)
-        : m_declaration_kind(declaration_kind)
+    VariableDeclaration(SourceRange source_range, DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations)
+        : Declaration(move(source_range))
+        , m_declaration_kind(declaration_kind)
         , m_declarations(move(declarations))
     {
     }
@@ -967,8 +1061,9 @@ public:
         Spread,
     };
 
-    ObjectProperty(NonnullRefPtr<Expression> key, RefPtr<Expression> value, Type property_type, bool is_method)
-        : m_key(move(key))
+    ObjectProperty(SourceRange source_range, NonnullRefPtr<Expression> key, RefPtr<Expression> value, Type property_type, bool is_method)
+        : ASTNode(move(source_range))
+        , m_key(move(key))
         , m_value(move(value))
         , m_property_type(property_type)
         , m_is_method(is_method)
@@ -999,8 +1094,9 @@ private:
 
 class ObjectExpression final : public Expression {
 public:
-    ObjectExpression(NonnullRefPtrVector<ObjectProperty> properties = {})
-        : m_properties(move(properties))
+    ObjectExpression(SourceRange source_range, NonnullRefPtrVector<ObjectProperty> properties = {})
+        : Expression(move(source_range))
+        , m_properties(move(properties))
     {
     }
 
@@ -1015,8 +1111,9 @@ private:
 
 class ArrayExpression final : public Expression {
 public:
-    ArrayExpression(Vector<RefPtr<Expression>> elements)
-        : m_elements(move(elements))
+    ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression>> elements)
+        : Expression(move(source_range))
+        , m_elements(move(elements))
     {
     }
 
@@ -1033,13 +1130,15 @@ private:
 
 class TemplateLiteral final : public Expression {
 public:
-    TemplateLiteral(NonnullRefPtrVector<Expression> expressions)
-        : m_expressions(move(expressions))
+    TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
+        : Expression(move(source_range))
+        , m_expressions(move(expressions))
     {
     }
 
-    TemplateLiteral(NonnullRefPtrVector<Expression> expressions, NonnullRefPtrVector<Expression> raw_strings)
-        : m_expressions(move(expressions))
+    TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions, NonnullRefPtrVector<Expression> raw_strings)
+        : Expression(move(source_range))
+        , m_expressions(move(expressions))
         , m_raw_strings(move(raw_strings))
     {
     }
@@ -1059,8 +1158,9 @@ private:
 
 class TaggedTemplateLiteral final : public Expression {
 public:
-    TaggedTemplateLiteral(NonnullRefPtr<Expression> tag, NonnullRefPtr<TemplateLiteral> template_literal)
-        : m_tag(move(tag))
+    TaggedTemplateLiteral(SourceRange source_range, NonnullRefPtr<Expression> tag, NonnullRefPtr<TemplateLiteral> template_literal)
+        : Expression(move(source_range))
+        , m_tag(move(tag))
         , m_template_literal(move(template_literal))
     {
     }
@@ -1077,8 +1177,9 @@ private:
 
 class MemberExpression final : public Expression {
 public:
-    MemberExpression(NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false)
-        : m_object(move(object))
+    MemberExpression(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false)
+        : Expression(move(source_range))
+        , m_object(move(object))
         , m_property(move(property))
         , m_computed(computed)
     {
@@ -1112,8 +1213,9 @@ public:
         ImportMeta,
     };
 
-    MetaProperty(Type type)
-        : m_type(type)
+    MetaProperty(SourceRange source_range, Type type)
+        : Expression(move(source_range))
+        , m_type(type)
     {
     }
 
@@ -1128,8 +1230,9 @@ private:
 
 class ConditionalExpression final : public Expression {
 public:
-    ConditionalExpression(NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate)
-        : m_test(move(test))
+    ConditionalExpression(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate)
+        : Expression(move(source_range))
+        , m_test(move(test))
         , m_consequent(move(consequent))
         , m_alternate(move(alternate))
     {
@@ -1148,8 +1251,9 @@ private:
 
 class CatchClause final : public ASTNode {
 public:
-    CatchClause(const FlyString& parameter, NonnullRefPtr<BlockStatement> body)
-        : m_parameter(parameter)
+    CatchClause(SourceRange source_range, const FlyString& parameter, NonnullRefPtr<BlockStatement> body)
+        : ASTNode(move(source_range))
+        , m_parameter(parameter)
         , m_body(move(body))
     {
     }
@@ -1169,8 +1273,9 @@ private:
 
 class TryStatement final : public Statement {
 public:
-    TryStatement(NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer)
-        : m_block(move(block))
+    TryStatement(SourceRange source_range, NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer)
+        : Statement(move(source_range))
+        , m_block(move(block))
         , m_handler(move(handler))
         , m_finalizer(move(finalizer))
     {
@@ -1193,8 +1298,9 @@ private:
 
 class ThrowStatement final : public Statement {
 public:
-    explicit ThrowStatement(NonnullRefPtr<Expression> argument)
-        : m_argument(move(argument))
+    explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression> argument)
+        : Statement(move(source_range))
+        , m_argument(move(argument))
     {
     }
 
@@ -1211,8 +1317,9 @@ private:
 
 class SwitchCase final : public ASTNode {
 public:
-    SwitchCase(RefPtr<Expression> test, NonnullRefPtrVector<Statement> consequent)
-        : m_test(move(test))
+    SwitchCase(SourceRange source_range, RefPtr<Expression> test, NonnullRefPtrVector<Statement> consequent)
+        : ASTNode(move(source_range))
+        , m_test(move(test))
         , m_consequent(move(consequent))
     {
     }
@@ -1232,8 +1339,9 @@ private:
 
 class SwitchStatement final : public Statement {
 public:
-    SwitchStatement(NonnullRefPtr<Expression> discriminant, NonnullRefPtrVector<SwitchCase> cases)
-        : m_discriminant(move(discriminant))
+    SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression> discriminant, NonnullRefPtrVector<SwitchCase> cases)
+        : Statement(move(source_range))
+        , m_discriminant(move(discriminant))
         , m_cases(move(cases))
     {
     }
@@ -1250,8 +1358,9 @@ private:
 
 class BreakStatement final : public Statement {
 public:
-    BreakStatement(FlyString target_label)
-        : m_target_label(target_label)
+    BreakStatement(SourceRange source_range, FlyString target_label)
+        : Statement(move(source_range))
+        , m_target_label(target_label)
     {
     }
 
@@ -1267,8 +1376,9 @@ private:
 
 class ContinueStatement final : public Statement {
 public:
-    ContinueStatement(FlyString target_label)
-        : m_target_label(target_label)
+    ContinueStatement(SourceRange source_range, FlyString target_label)
+        : Statement(move(source_range))
+        , m_target_label(target_label)
     {
     }
 
@@ -1284,7 +1394,10 @@ private:
 
 class DebuggerStatement final : public Statement {
 public:
-    DebuggerStatement() { }
+    DebuggerStatement(SourceRange source_range)
+        : Statement(move(source_range))
+    {
+    }
 
     virtual Value execute(Interpreter&, GlobalObject&) const override;
 

+ 10 - 0
Libraries/LibJS/Interpreter.cpp

@@ -143,6 +143,16 @@ void Interpreter::exit_scope(const ScopeNode& scope_node)
         vm().unwind(ScopeType::None);
 }
 
+void Interpreter::enter_node(const ASTNode& node)
+{
+    vm().push_ast_node(node);
+}
+
+void Interpreter::exit_node(const ASTNode&)
+{
+    vm().pop_ast_node();
+}
+
 void Interpreter::push_scope(ScopeFrame frame)
 {
     m_scope_stack.append(move(frame));

+ 3 - 0
Libraries/LibJS/Interpreter.h

@@ -77,6 +77,9 @@ public:
     void enter_scope(const ScopeNode&, ScopeType, GlobalObject&);
     void exit_scope(const ScopeNode&);
 
+    void enter_node(const ASTNode&);
+    void exit_node(const ASTNode&);
+
     Value execute_statement(GlobalObject&, const Statement&, ScopeType = ScopeType::Block);
 
 private:

文件差异内容过多而无法显示
+ 162 - 119
Libraries/LibJS/Parser.cpp


+ 26 - 5
Libraries/LibJS/Parser.h

@@ -31,6 +31,7 @@
 #include <AK/StringBuilder.h>
 #include <LibJS/AST.h>
 #include <LibJS/Lexer.h>
+#include <LibJS/SourceRange.h>
 #include <stdio.h>
 
 namespace JS {
@@ -102,11 +103,6 @@ public:
     RefPtr<Statement> try_parse_labelled_statement();
     RefPtr<MetaProperty> try_parse_new_target_expression();
 
-    struct Position {
-        size_t line;
-        size_t column;
-    };
-
     struct Error {
         String message;
         Optional<Position> position;
@@ -175,6 +171,30 @@ private:
     void load_state();
     Position position() const;
 
+    struct RulePosition {
+        RulePosition(Parser& parser, Position position)
+            : m_parser(parser)
+            , m_position(position)
+        {
+            m_parser.m_parser_state.m_rule_starts.append(position);
+        }
+
+        ~RulePosition()
+        {
+            auto last = m_parser.m_parser_state.m_rule_starts.take_last();
+            ASSERT(last.line == m_position.line);
+            ASSERT(last.column == m_position.column);
+        }
+
+        const Position& position() const { return m_position; }
+
+    private:
+        Parser& m_parser;
+        Position m_position;
+    };
+
+    [[nodiscard]] RulePosition push_start() { return { *this, position() }; }
+
     struct ParserState {
         Lexer m_lexer;
         Token m_current_token;
@@ -182,6 +202,7 @@ private:
         Vector<NonnullRefPtrVector<VariableDeclaration>> m_var_scopes;
         Vector<NonnullRefPtrVector<VariableDeclaration>> m_let_scopes;
         Vector<NonnullRefPtrVector<FunctionDeclaration>> m_function_scopes;
+        Vector<Position> m_rule_starts;
         HashTable<StringView> m_labels_in_scope;
         bool m_strict_mode { false };
         bool m_allow_super_property_lookup { false };

+ 8 - 0
Libraries/LibJS/Runtime/Exception.cpp

@@ -25,6 +25,7 @@
  */
 
 #include <AK/String.h>
+#include <LibJS/AST.h>
 #include <LibJS/Runtime/Exception.h>
 #include <LibJS/Runtime/VM.h>
 
@@ -40,6 +41,13 @@ Exception::Exception(Value value)
             function_name = "<anonymous>";
         m_trace.append(function_name);
     }
+
+    auto& node_stack = vm().node_stack();
+    for (ssize_t i = node_stack.size() - 1; i >= 0; --i) {
+        auto* node = node_stack[i];
+        ASSERT(node);
+        m_source_ranges.append(node->source_range());
+    }
 }
 
 Exception::~Exception()

+ 3 - 0
Libraries/LibJS/Runtime/Exception.h

@@ -29,6 +29,7 @@
 #include <AK/Vector.h>
 #include <LibJS/Runtime/Cell.h>
 #include <LibJS/Runtime/Value.h>
+#include <LibJS/SourceRange.h>
 
 namespace JS {
 
@@ -39,6 +40,7 @@ public:
 
     Value value() const { return m_value; }
     const Vector<String>& trace() const { return m_trace; }
+    const Vector<SourceRange>& source_ranges() const { return m_source_ranges; }
 
 private:
     virtual const char* class_name() const override { return "Exception"; }
@@ -46,6 +48,7 @@ private:
 
     Value m_value;
     Vector<String> m_trace;
+    Vector<SourceRange> m_source_ranges;
 };
 
 }

+ 5 - 0
Libraries/LibJS/Runtime/VM.h

@@ -126,10 +126,14 @@ public:
 
     void pop_call_frame() { m_call_stack.take_last(); }
 
+    void push_ast_node(const ASTNode& node) { m_ast_nodes.append(&node); }
+    void pop_ast_node() { m_ast_nodes.take_last(); }
+
     CallFrame& call_frame() { return *m_call_stack.last(); }
     const CallFrame& call_frame() const { return *m_call_stack.last(); }
     const Vector<CallFrame*>& call_stack() const { return m_call_stack; }
     Vector<CallFrame*>& call_stack() { return m_call_stack; }
+    const Vector<const ASTNode*>& node_stack() const { return m_ast_nodes; }
 
     const ScopeObject* current_scope() const { return call_frame().scope; }
     ScopeObject* current_scope() { return call_frame().scope; }
@@ -249,6 +253,7 @@ private:
     Vector<Interpreter*> m_interpreters;
 
     Vector<CallFrame*> m_call_stack;
+    Vector<const ASTNode*> m_ast_nodes;
 
     Value m_last_value;
     ScopeType m_unwind_until { ScopeType::None };

+ 43 - 0
Libraries/LibJS/SourceRange.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2020, the SerenityOS developers.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Types.h>
+
+namespace JS {
+
+struct Position {
+    size_t line { 0 };
+    size_t column { 0 };
+};
+
+struct SourceRange {
+    Position start;
+    Position end;
+};
+
+}

部分文件因为文件数量过多而无法显示