Implement error.fileName and error.lineNumber
authorLars Knoll <lars.knoll@digia.com>
Fri, 14 Jun 2013 11:08:13 +0000 (13:08 +0200)
committerSimon Hausmann <simon.hausmann@digia.com>
Fri, 14 Jun 2013 11:15:05 +0000 (13:15 +0200)
Useful extensions to the error object. This also helped
track down a few places in the parser where we wouldn't give
correct error information.

Change-Id: Id03653e096216e097c13a7a6e698ca142d92da13
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/qml/v4/qv4codegen.cpp
src/qml/qml/v4/qv4context.cpp
src/qml/qml/v4/qv4context_p.h
src/qml/qml/v4/qv4engine.cpp
src/qml/qml/v4/qv4engine_p.h
src/qml/qml/v4/qv4errorobject.cpp
src/qml/qml/v4/qv4errorobject_p.h
tests/auto/qml/qjsengine/tst_qjsengine.cpp

index 77c4610..310272c 100644 (file)
@@ -2616,7 +2616,7 @@ void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail)
 void Codegen::throwReferenceError(const SourceLocation &loc, const QString &detail)
 {
     if (_context)
-        _context->throwReferenceError(QV4::Value::fromString(_context, detail));
+        _context->throwReferenceError(QV4::Value::fromString(_context, detail), _fileName, loc.startLine);
     else if (_errorHandler)
         throwSyntaxError(loc, detail);
     else
index 79553b9..4838a15 100644 (file)
@@ -582,6 +582,13 @@ void ExecutionContext::throwReferenceError(Value value)
     throwError(Value::fromObject(engine->newReferenceErrorObject(msg)));
 }
 
+void ExecutionContext::throwReferenceError(Value value, const QString &fileName, int line)
+{
+    String *s = value.toString(this);
+    QString msg = s->toQString() + QStringLiteral(" is not defined");
+    throwError(Value::fromObject(engine->newReferenceErrorObject(msg, fileName, line)));
+}
+
 void ExecutionContext::throwRangeError(Value value)
 {
     String *s = value.toString(this);
index 1f59d27..4e1aebf 100644 (file)
@@ -133,6 +133,7 @@ struct Q_QML_EXPORT ExecutionContext
     void Q_NORETURN throwTypeError();
     void Q_NORETURN throwTypeError(const QString &message);
     void Q_NORETURN throwReferenceError(Value value);
+    void Q_NORETURN throwReferenceError(Value value, const QString &fileName, int line);
     void Q_NORETURN throwRangeError(Value value);
     void Q_NORETURN throwURIError(Value msg);
     void Q_NORETURN throwUnimplemented(const QString &message);
index f0ceaf7..ad5bcaf 100644 (file)
@@ -532,6 +532,12 @@ Object *ExecutionEngine::newReferenceErrorObject(const QString &message)
     return new (memoryManager) ReferenceErrorObject(this, message);
 }
 
+Object *ExecutionEngine::newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber)
+{
+    return new (memoryManager) ReferenceErrorObject(this, message, fileName, lineNumber);
+}
+
+
 Object *ExecutionEngine::newTypeErrorObject(const QString &message)
 {
     return new (memoryManager) TypeErrorObject(this, message);
index c137534..09f76ec 100644 (file)
@@ -266,6 +266,7 @@ struct Q_QML_EXPORT ExecutionEngine
     Object *newSyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message);
     Object *newSyntaxErrorObject(const QString &message);
     Object *newReferenceErrorObject(const QString &message);
+    Object *newReferenceErrorObject(const QString &message, const QString &fileName, int lineNumber);
     Object *newTypeErrorObject(const QString &message);
     Object *newRangeErrorObject(const QString &message);
     Object *newURIErrorObject(Value message);
index b8939a9..0f77b54 100644 (file)
@@ -85,6 +85,10 @@ ErrorObject::ErrorObject(ExecutionEngine *engine, const Value &message, ErrorTyp
     defineDefaultProperty(engine, QStringLiteral("name"), Value::fromString(engine, className()));
 
     stackTrace = engine->stackTrace();
+    if (!stackTrace.isEmpty()) {
+        defineDefaultProperty(engine, QStringLiteral("fileName"), Value::fromString(engine, stackTrace.at(0).source));
+        defineDefaultProperty(engine, QStringLiteral("lineNumber"), Value::fromInt32(stackTrace.at(0).line));
+    }
 
     stack = Value::emptyValue();
 }
@@ -137,6 +141,10 @@ SyntaxErrorObject::SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *m
 {
     vtbl = &static_vtbl;
     prototype = ctx->engine->syntaxErrorPrototype;
+    if (message) {
+        defineDefaultProperty(ctx->engine, QStringLiteral("fileName"), Value::fromString(ctx, message->fileName));
+        defineDefaultProperty(ctx->engine, QStringLiteral("lineNumber"), Value::fromInt32(message->startLine));
+    }
 }
 
 
@@ -171,6 +179,14 @@ ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QStrin
     prototype = engine->referenceErrorPrototype;
 }
 
+ReferenceErrorObject::ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber)
+    : ErrorObject(engine, Value::fromString(engine, msg), ReferenceError)
+{
+    prototype = engine->referenceErrorPrototype;
+    defineDefaultProperty(engine, QStringLiteral("fileName"), Value::fromString(engine->rootContext, fileName));
+    defineDefaultProperty(engine, QStringLiteral("lineNumber"), Value::fromInt32(lineNumber));
+}
+
 TypeErrorObject::TypeErrorObject(ExecutionEngine *engine, const Value &message)
     : ErrorObject(engine, message, TypeError)
 {
index 41e3aba..7cc8804 100644 (file)
@@ -83,6 +83,7 @@ struct RangeErrorObject: ErrorObject {
 struct ReferenceErrorObject: ErrorObject {
     ReferenceErrorObject(ExecutionEngine *engine, const Value &message);
     ReferenceErrorObject(ExecutionEngine *engine, const QString &msg);
+    ReferenceErrorObject(ExecutionEngine *engine, const QString &msg, const QString &fileName, int lineNumber);
 };
 
 struct SyntaxErrorObject: ErrorObject {
index e0e08d9..9f4756b 100644 (file)
@@ -923,7 +923,6 @@ void tst_QJSEngine::evaluate()
         ret = eng.evaluate(code);
     QCOMPARE(ret.isError(), expectHadError);
     if (ret.isError()) {
-        QEXPECT_FAIL("", "we have no more lineNumber property ", Continue);
         QVERIFY(ret.property("lineNumber").strictlyEquals(eng.toScriptValue(expectErrorLineNumber)));
     }
 }
@@ -1605,8 +1604,6 @@ void tst_QJSEngine::errorConstructors()
             QJSValue ret = eng.evaluate(code);
             QVERIFY(ret.isError());
             QVERIFY(ret.toString().startsWith(name));
-            //QTBUG-6138: JSC doesn't assign lineNumber when errors are not thrown
-            QEXPECT_FAIL("", "we have no more lineNumber property ", Continue);
             QCOMPARE(ret.property("lineNumber").toInt(), i+2);
         }
     }