diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index c8dcc6db638cf6cff1fef1d262fb0b7efd6bfaef..34bf7eacee961afb04c2ef5eda14060e7f8013f1 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 778952bf939a3308d028ad78c978aed362f8ba81..a50953e15fabdb1c374b0f8bfa0c0e781b2881e0 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);