forked from qt-creator/qt-creator
Add check for correct color string in Qml.
This commit is contained in:
@@ -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);
|
||||
Evaluate evaluator(&_context);
|
||||
const Value *rhsValue = evaluator(expr);
|
||||
|
||||
checkPropertyAssignment(loc, lhsValue, rhsValue, 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;
|
||||
}
|
||||
UnaryMinusExpression *unaryMinus = cast<UnaryMinusExpression *>(ast);
|
||||
|
||||
if (StringLiteral *string = cast<StringLiteral *>(ast)) {
|
||||
const QString value = string->value->asString();
|
||||
// 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;
|
||||
|
||||
Reference in New Issue
Block a user