From f717a7df300e374d456813342255cc1f4ef9f417 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Tue, 23 Feb 2010 12:36:12 +0100 Subject: [PATCH] Add Qml type checks for assigning literals to properties. Done-with: Erik Verbruggen --- src/libs/qmljs/qmljscheck.cpp | 42 ++++++++++++++++++++++++++++++----- src/libs/qmljs/qmljscheck.h | 1 + 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index c8dcc6db638..34bf7eacee9 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -33,8 +33,9 @@ #include "qmljsevaluate.h" #include "parser/qmljsast_p.h" -#include <QtGui/QApplication> #include <QtCore/QDebug> +#include <QtCore/QCoreApplication> +#include <QtGui/QApplication> namespace QmlJS { namespace Messages { @@ -125,17 +126,48 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId, _scopeBuilder.pop(); } +void Check::errorOnWrongRhs(const SourceLocation &loc, const Value *lhsValue) +{ + if (lhsValue->asBooleanValue()) { + error(loc, QCoreApplication::translate("QmlJS::Check", "boolean value expected")); + } else if (lhsValue->asNumberValue()) { + error(loc, QCoreApplication::translate("QmlJS::Check", "numerical value expected")); + } else if (lhsValue->asStringValue()) { + error(loc, QCoreApplication::translate("QmlJS::Check", "string value expected")); + } +} + bool Check::visit(UiScriptBinding *ast) { const Value *lhsValue = checkScopeObjectMember(ast->qualifiedId); if (lhsValue) { // ### Fix the evaluator to accept statements! if (ExpressionStatement *expStmt = cast<ExpressionStatement *>(ast->statement)) { - Evaluate evaluator(&_context); - const Value *rhsValue = evaluator(expStmt->expression); - + ExpressionNode *expr = expStmt->expression; const SourceLocation loc = locationFromRange(expStmt->firstSourceLocation(), expStmt->lastSourceLocation()); - checkPropertyAssignment(loc, lhsValue, rhsValue, expStmt->expression); + + // Qml is particularly strict with literals + if (cast<StringLiteral *>(expr) + && ! lhsValue->asStringValue()) { + errorOnWrongRhs(loc, lhsValue); + } else if ((expr->kind == Node::Kind_TrueLiteral + || expr->kind == Node::Kind_FalseLiteral) + && ! lhsValue->asBooleanValue()) { + errorOnWrongRhs(loc, lhsValue); + } else if (cast<NumericLiteral *>(expr) + && ! lhsValue->asNumberValue()) { + errorOnWrongRhs(loc, lhsValue); + } else if (UnaryMinusExpression *unaryMinus = cast<UnaryMinusExpression *>(expr)) { + if (cast<NumericLiteral *>(unaryMinus->expression) + && ! lhsValue->asNumberValue()) { + errorOnWrongRhs(loc, lhsValue); + } + } else { + Evaluate evaluator(&_context); + const Value *rhsValue = evaluator(expr); + + checkPropertyAssignment(loc, lhsValue, rhsValue, expr); + } } } diff --git a/src/libs/qmljs/qmljscheck.h b/src/libs/qmljs/qmljscheck.h index 778952bf939..a50953e15fa 100644 --- a/src/libs/qmljs/qmljscheck.h +++ b/src/libs/qmljs/qmljscheck.h @@ -61,6 +61,7 @@ private: const Interpreter::Value *lhsValue, const Interpreter::Value *rhsValue, QmlJS::AST::ExpressionNode *ast); + void errorOnWrongRhs(const AST::SourceLocation &loc, const Interpreter::Value *lhsValue); void warning(const AST::SourceLocation &loc, const QString &message); void error(const AST::SourceLocation &loc, const QString &message); -- GitLab