Throw a SyntaxError instead of printing an error message.
Change-Id: I94ef8a4f2bea80bc3689b104e381a9dc134439fa Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
61460c7859
commit
4bd20c2ac3
28
main.cpp
28
main.cpp
|
@ -108,10 +108,32 @@ struct TestHarnessError: FunctionObject
|
|||
|
||||
static void showException(QQmlJS::VM::ExecutionContext *ctx)
|
||||
{
|
||||
if (QQmlJS::VM::ErrorObject *e = ctx->engine->exception.asErrorObject())
|
||||
std::cerr << "Uncaught exception: " << qPrintable(e->value.toString(ctx)->toQString()) << std::endl;
|
||||
else
|
||||
QQmlJS::VM::ErrorObject *e = ctx->engine->exception.asErrorObject();
|
||||
if (!e) {
|
||||
std::cerr << "Uncaught exception: " << qPrintable(ctx->engine->exception.toString(ctx)->toQString()) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (QQmlJS::VM::SyntaxErrorObject *err = e->asSyntaxError()) {
|
||||
QQmlJS::VM::DiagnosticMessage *msg = err->message();
|
||||
if (!msg) {
|
||||
std::cerr << "Uncaught exception: Syntax error" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (; msg; msg = msg->next) {
|
||||
if (msg->fileName)
|
||||
std::cerr << qPrintable(msg->fileName->toQString());
|
||||
std::cerr << ':' << msg->startLine << ':' << msg->startColumn << ": ";
|
||||
if (msg->type == QQmlJS::VM::DiagnosticMessage::Error)
|
||||
std::cerr << "error";
|
||||
else
|
||||
std::cerr << "warning";
|
||||
std::cerr << ": " << qPrintable(msg->message->toQString()) << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Uncaught exception: " << qPrintable(e->value.toString(ctx)->toQString()) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QMLJS_NO_LLVM
|
||||
|
|
|
@ -316,6 +316,13 @@ Object *ExecutionEngine::newErrorObject(const Value &value)
|
|||
return object;
|
||||
}
|
||||
|
||||
Object *ExecutionEngine::newSyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message)
|
||||
{
|
||||
SyntaxErrorObject *object = new SyntaxErrorObject(ctx, message);
|
||||
object->prototype = syntaxErrorPrototype;
|
||||
return object;
|
||||
}
|
||||
|
||||
Object *ExecutionEngine::newMathObject(ExecutionContext *ctx)
|
||||
{
|
||||
MathObject *object = new MathObject(ctx);
|
||||
|
|
|
@ -175,6 +175,7 @@ struct ExecutionEngine
|
|||
FunctionObject *newRegExpCtor(ExecutionContext *ctx);
|
||||
|
||||
Object *newErrorObject(const Value &value);
|
||||
Object *newSyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message);
|
||||
Object *newMathObject(ExecutionContext *ctx);
|
||||
Object *newActivationObject(DeclarativeEnvironment *ctx);
|
||||
|
||||
|
|
|
@ -45,6 +45,17 @@
|
|||
namespace QQmlJS {
|
||||
namespace VM {
|
||||
|
||||
DiagnosticMessage::DiagnosticMessage()
|
||||
: fileName(0)
|
||||
, offset(0)
|
||||
, length(0)
|
||||
, startLine(0)
|
||||
, startColumn(0)
|
||||
, type(0)
|
||||
, message(0)
|
||||
, next(0)
|
||||
{}
|
||||
|
||||
DeclarativeEnvironment::DeclarativeEnvironment(ExecutionEngine *e)
|
||||
{
|
||||
engine = e;
|
||||
|
@ -255,6 +266,11 @@ void ExecutionContext::throwError(const QString &message)
|
|||
throwError(Value::fromObject(engine->newErrorObject(v)));
|
||||
}
|
||||
|
||||
void ExecutionContext::throwSyntaxError(DiagnosticMessage *message)
|
||||
{
|
||||
throwError(Value::fromObject(engine->newSyntaxErrorObject(this, message)));
|
||||
}
|
||||
|
||||
void ExecutionContext::throwTypeError()
|
||||
{
|
||||
Value v = Value::fromString(this, QStringLiteral("Type error"));
|
||||
|
|
|
@ -52,6 +52,22 @@ struct ExecutionEngine;
|
|||
struct ExecutionContext;
|
||||
struct DeclarativeEnvironment;
|
||||
|
||||
struct DiagnosticMessage
|
||||
{
|
||||
enum { Error, Warning };
|
||||
|
||||
String *fileName;
|
||||
quint32 offset;
|
||||
quint32 length;
|
||||
quint32 startLine;
|
||||
unsigned startColumn: 31;
|
||||
unsigned type: 1;
|
||||
String *message;
|
||||
DiagnosticMessage *next;
|
||||
|
||||
DiagnosticMessage();
|
||||
};
|
||||
|
||||
// This merges LexicalEnvironment and EnvironmentRecord from
|
||||
// Sec. 10.2 into one class
|
||||
struct DeclarativeEnvironment
|
||||
|
@ -109,6 +125,7 @@ struct ExecutionContext
|
|||
|
||||
void throwError(Value value);
|
||||
void throwError(const QString &message);
|
||||
void throwSyntaxError(DiagnosticMessage *message);
|
||||
void throwTypeError();
|
||||
void throwReferenceError(Value value);
|
||||
void throwUnimplemented(const QString &message);
|
||||
|
|
|
@ -525,10 +525,25 @@ QQmlJS::IR::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ct
|
|||
|
||||
const bool parsed = parser.parseProgram();
|
||||
|
||||
foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {
|
||||
std::cerr << qPrintable(fileName) << ':' << m.loc.startLine << ':' << m.loc.startColumn
|
||||
<< ": error: " << qPrintable(m.message) << std::endl;
|
||||
VM::DiagnosticMessage *error = 0, **errIt = &error;
|
||||
foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
|
||||
if (m.isError()) {
|
||||
*errIt = new VM::DiagnosticMessage; // FIXME: should we ask the engine to create this object?
|
||||
(*errIt)->fileName = ctx->engine->newString(fileName);
|
||||
(*errIt)->offset = m.loc.offset;
|
||||
(*errIt)->length = m.loc.length;
|
||||
(*errIt)->startLine = m.loc.startLine;
|
||||
(*errIt)->startColumn = m.loc.startColumn;
|
||||
(*errIt)->type = VM::DiagnosticMessage::Error;
|
||||
(*errIt)->message = ctx->engine->newString(m.message);
|
||||
errIt = &(*errIt)->next;
|
||||
} else {
|
||||
std::cerr << qPrintable(fileName) << ':' << m.loc.startLine << ':' << m.loc.startColumn
|
||||
<< ": warning: " << qPrintable(m.message) << std::endl;
|
||||
}
|
||||
}
|
||||
if (error)
|
||||
ctx->throwSyntaxError(error);
|
||||
|
||||
if (parsed) {
|
||||
using namespace AST;
|
||||
|
@ -612,6 +627,16 @@ void ErrorObject::setNameProperty(ExecutionContext *ctx)
|
|||
__put__(ctx, QLatin1String("name"), Value::fromString(ctx, className()));
|
||||
}
|
||||
|
||||
SyntaxErrorObject::SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *message)
|
||||
: ErrorObject(ctx->argument(0))
|
||||
, msg(message)
|
||||
{
|
||||
if (message)
|
||||
value = Value::fromString(message->message);
|
||||
setNameProperty(ctx);
|
||||
}
|
||||
|
||||
|
||||
Value ScriptFunction::construct(VM::ExecutionContext *ctx)
|
||||
{
|
||||
Object *obj = ctx->engine->newObject();
|
||||
|
|
|
@ -566,6 +566,8 @@ struct ErrorObject: Object {
|
|||
virtual ErrorObject *asErrorObject() { return this; }
|
||||
virtual Value __get__(ExecutionContext *ctx, String *name);
|
||||
|
||||
virtual struct SyntaxErrorObject *asSyntaxError() { return 0; }
|
||||
|
||||
protected:
|
||||
void setNameProperty(ExecutionContext *ctx);
|
||||
};
|
||||
|
@ -589,9 +591,14 @@ struct ReferenceErrorObject: ErrorObject {
|
|||
};
|
||||
|
||||
struct SyntaxErrorObject: ErrorObject {
|
||||
SyntaxErrorObject(ExecutionContext *ctx)
|
||||
: ErrorObject(ctx->argument(0)) { setNameProperty(ctx); }
|
||||
SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *msg);
|
||||
virtual QString className() { return QStringLiteral("SyntaxError"); }
|
||||
|
||||
virtual SyntaxErrorObject *asSyntaxError() { return this; }
|
||||
DiagnosticMessage *message() { return msg; }
|
||||
|
||||
private:
|
||||
DiagnosticMessage *msg;
|
||||
};
|
||||
|
||||
struct TypeErrorObject: ErrorObject {
|
||||
|
|
|
@ -2630,7 +2630,7 @@ Value ReferenceErrorCtor::construct(ExecutionContext *ctx)
|
|||
|
||||
Value SyntaxErrorCtor::construct(ExecutionContext *ctx)
|
||||
{
|
||||
ctx->thisObject = Value::fromObject(new SyntaxErrorObject(ctx));
|
||||
ctx->thisObject = Value::fromObject(new SyntaxErrorObject(ctx, 0));
|
||||
return ctx->thisObject;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ struct ReferenceErrorPrototype: ReferenceErrorObject
|
|||
|
||||
struct SyntaxErrorPrototype: SyntaxErrorObject
|
||||
{
|
||||
SyntaxErrorPrototype(ExecutionContext *ctx): SyntaxErrorObject(ctx) {}
|
||||
SyntaxErrorPrototype(ExecutionContext *ctx): SyntaxErrorObject(ctx, 0) {}
|
||||
void init(ExecutionContext *ctx, const Value &ctor) { ErrorPrototype::init(ctx, ctor, this); }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue