Commit 0e268533 authored by Christian Kamm's avatar Christian Kamm
Browse files

Add check for correct color string in Qml.

parent f6cd2493
......@@ -35,8 +35,13 @@
#include <QtCore/QDebug>
#include <QtCore/QCoreApplication>
#include <QtGui/QColor>
#include <QtGui/QApplication>
#ifndef NO_DECLARATIVE_BACKEND
# include <QtDeclarative/private/qmlstringconverters_p.h> // ### remove me
#endif
namespace QmlJS {
namespace Messages {
static const char *invalid_property_name = QT_TRANSLATE_NOOP("QmlJS::Check", "'%1' is not a valid property name");
......@@ -144,30 +149,13 @@ bool Check::visit(UiScriptBinding *ast)
// ### Fix the evaluator to accept statements!
if (ExpressionStatement *expStmt = cast<ExpressionStatement *>(ast->statement)) {
ExpressionNode *expr = expStmt->expression;
const SourceLocation loc = locationFromRange(expStmt->firstSourceLocation(), expStmt->lastSourceLocation());
// 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);
}
Evaluate evaluator(&_context);
const Value *rhsValue = evaluator(expr);
const SourceLocation loc = locationFromRange(expStmt->firstSourceLocation(),
expStmt->lastSourceLocation());
checkPropertyAssignment(loc, lhsValue, rhsValue, expr);
}
}
......@@ -180,25 +168,53 @@ void Check::checkPropertyAssignment(const SourceLocation &location,
const Interpreter::Value *rhsValue,
ExpressionNode *ast)
{
if (lhsValue->asEasingCurveNameValue()) {
const StringValue *rhsStringValue = rhsValue->asStringValue();
if (!rhsStringValue) {
if (rhsValue->asUndefinedValue())
warning(location, tr(Messages::value_might_be_undefined));
else
error(location, tr(Messages::easing_curve_not_a_string));
return;
}
if (StringLiteral *string = cast<StringLiteral *>(ast)) {
const QString value = string->value->asString();
UnaryMinusExpression *unaryMinus = cast<UnaryMinusExpression *>(ast);
// Qml is particularly strict with literals
if (StringLiteral *stringLiteral = cast<StringLiteral *>(ast)) {
const QString string = stringLiteral->value->asString();
if (lhsValue->asStringValue()) {
// okay
} else if (lhsValue->asColorValue()) {
#ifndef NO_DECLARATIVE_BACKEND
bool ok = false;
QmlStringConverters::colorFromString(string, &ok);
if (!ok)
error(location, QCoreApplication::translate("QmlJS::Check", "not a valid color"));
#endif
} else if (lhsValue->asEasingCurveNameValue()) {
// ### do something with easing-curve attributes.
// ### Incomplete documentation at: http://qt.nokia.com/doc/4.7-snapshot/qml-propertyanimation.html#easing-prop
// ### The implementation is at: src/declarative/util/qmlanimation.cpp
const QString curveName = value.left(value.indexOf(QLatin1Char('(')));
const QString curveName = string.left(string.indexOf(QLatin1Char('(')));
if (!EasingCurveNameValue::curveNames().contains(curveName)) {
error(location, tr(Messages::unknown_easing_curve_name));
}
} else {
errorOnWrongRhs(location, lhsValue);
}
} else if ((ast->kind == Node::Kind_TrueLiteral
|| ast->kind == Node::Kind_FalseLiteral)
&& ! lhsValue->asBooleanValue()) {
errorOnWrongRhs(location, lhsValue);
} else if (cast<NumericLiteral *>(ast)
&& ! lhsValue->asNumberValue()) {
errorOnWrongRhs(location, lhsValue);
} else if (unaryMinus && cast<NumericLiteral *>(unaryMinus->expression)
&& ! lhsValue->asNumberValue()) {
errorOnWrongRhs(location, lhsValue);
} else {
// rhs is not a literal
if (lhsValue->asEasingCurveNameValue()) {
const StringValue *rhsStringValue = rhsValue->asStringValue();
if (!rhsStringValue) {
if (rhsValue->asUndefinedValue())
warning(location, tr(Messages::value_might_be_undefined));
else
error(location, tr(Messages::easing_curve_not_a_string));
return;
}
}
}
}
......
......@@ -326,6 +326,10 @@ const Value *QmlObjectValue::propertyValue(const QMetaProperty &prop) const
value = object;
} break;
case QMetaType::QColor: {
value = engine()->colorValue();
} break;
default:
break;
} // end of switch
......@@ -610,6 +614,10 @@ void ValueVisitor::visit(const EasingCurveNameValue *)
{
}
void ValueVisitor::visit(const ColorValue *)
{
}
////////////////////////////////////////////////////////////////////////////////
// Value
////////////////////////////////////////////////////////////////////////////////
......@@ -671,6 +679,11 @@ const EasingCurveNameValue *Value::asEasingCurveNameValue() const
return 0;
}
const ColorValue *Value::asColorValue() const
{
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Values
////////////////////////////////////////////////////////////////////////////////
......@@ -977,6 +990,16 @@ const EasingCurveNameValue *EasingCurveNameValue::asEasingCurveNameValue() const
return this;
}
void ColorValue::accept(ValueVisitor *visitor) const
{
visitor->visit(this);
}
const ColorValue *ColorValue::asColorValue() const
{
return this;
}
MemberProcessor::MemberProcessor()
{
}
......@@ -1621,6 +1644,11 @@ const EasingCurveNameValue *Engine::easingCurveNameValue() const
return &_easingCurveNameValue;
}
const ColorValue *Engine::colorValue() const
{
return &_colorValue;
}
const Value *Engine::newArray()
{
return arrayCtor()->construct();
......
......@@ -61,6 +61,7 @@ class ObjectValue;
class FunctionValue;
class Reference;
class EasingCurveNameValue;
class ColorValue;
typedef QList<const Value *> ValueList;
......@@ -82,6 +83,7 @@ public:
virtual void visit(const FunctionValue *);
virtual void visit(const Reference *);
virtual void visit(const EasingCurveNameValue *);
virtual void visit(const ColorValue *);
};
////////////////////////////////////////////////////////////////////////////////
......@@ -105,6 +107,7 @@ public:
virtual const FunctionValue *asFunctionValue() const;
virtual const Reference *asReference() const;
virtual const EasingCurveNameValue *asEasingCurveNameValue() const;
virtual const ColorValue *asColorValue() const;
virtual void accept(ValueVisitor *) const = 0;
......@@ -167,6 +170,12 @@ template <> Q_INLINE_TEMPLATE const EasingCurveNameValue *value_cast(const Value
else return 0;
}
template <> Q_INLINE_TEMPLATE const ColorValue *value_cast(const Value *v)
{
if (v) return v->asColorValue();
else return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Value nodes
////////////////////////////////////////////////////////////////////////////////
......@@ -326,6 +335,14 @@ public:
virtual void accept(ValueVisitor *) const;
};
class QMLJS_EXPORT ColorValue: public Value
{
public:
// Value interface
virtual const ColorValue *asColorValue() const;
virtual void accept(ValueVisitor *) const;
};
class QMLJS_EXPORT ObjectValue: public Value
{
public:
......@@ -585,6 +602,7 @@ public:
const BooleanValue *booleanValue() const;
const StringValue *stringValue() const;
const EasingCurveNameValue *easingCurveNameValue() const;
const ColorValue *colorValue() const;
ObjectValue *newObject(const ObjectValue *prototype);
ObjectValue *newObject();
......@@ -674,6 +692,7 @@ private:
BooleanValue _booleanValue;
StringValue _stringValue;
EasingCurveNameValue _easingCurveNameValue;
ColorValue _colorValue;
QList<Value *> _registeredValues;
ConvertToNumber _convertToNumber;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment