From 23793482e9b187441203fb629b459245c504dfba Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 30 Sep 2013 09:41:35 +0200 Subject: [PATCH] Fix invalid alias error reporting in new compiler Match exactly the VME code path by reporting the right type of error as well as the right hand side of the alias binding if necessary. Change-Id: I35d192a20641e0acbf25d20f3dc5fb53cc7cbae5 Reviewed-by: Lars Knoll --- src/qml/compiler/qqmlcodegenerator.cpp | 55 ++++++++++++++++++++++++++++++---- src/qml/compiler/qqmlcodegenerator_p.h | 2 ++ src/qml/compiler/qv4compileddata_p.h | 1 + src/qml/qml/qqmlobjectcreator.cpp | 24 ++++++++++----- 4 files changed, 68 insertions(+), 14 deletions(-) diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index b257d2d..2394b07 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -634,15 +634,33 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node) if (!node->statement && !node->binding) COMPILE_EXCEPTION(loc, tr("No property alias location")); + AST::SourceLocation rhsLoc; + if (node->binding) + rhsLoc = node->binding->firstSourceLocation(); + else if (node->statement) + rhsLoc = node->statement->firstSourceLocation(); + else + rhsLoc = node->semicolonToken; + property->aliasLocation.line = rhsLoc.startLine; + property->aliasLocation.column = rhsLoc.startColumn; + QStringList alias; - if (AST::ExpressionStatement *stmt = AST::cast(node->statement)) - alias = astNodeToStringList(stmt->expression); - if (node->binding || alias.isEmpty()) - COMPILE_EXCEPTION(loc, tr("Invalid alias location")); + if (AST::ExpressionStatement *stmt = AST::cast(node->statement)) { + alias = astNodeToStringList(stmt->expression); + if (alias.isEmpty()) { + if (isStatementNodeScript(node->statement)) { + COMPILE_EXCEPTION(rhsLoc, tr("Invalid alias reference. An alias reference must be specified as , . or ..")); + } else { + COMPILE_EXCEPTION(rhsLoc, tr("Invalid alias location")); + } + } + } else { + COMPILE_EXCEPTION(rhsLoc, tr("Invalid alias reference. An alias reference must be specified as , . or ..")); + } - if (alias.count() < 1 || alias.count() > 3) - COMPILE_EXCEPTION(loc, tr("Invalid alias reference. An alias reference must be specified as , . or ..")); + if (alias.count() < 1 || alias.count() > 3) + COMPILE_EXCEPTION(rhsLoc, tr("Invalid alias reference. An alias reference must be specified as , . or ..")); property->aliasIdValueIndex = registerString(alias.first()); @@ -987,6 +1005,31 @@ QQmlScript::LocationSpan QQmlCodeGenerator::location(AST::SourceLocation start, return rv; } +bool QQmlCodeGenerator::isStatementNodeScript(AST::Statement *statement) +{ + if (AST::ExpressionStatement *stmt = AST::cast(statement)) { + AST::ExpressionNode *expr = stmt->expression; + if (AST::StringLiteral *lit = AST::cast(expr)) + return false; + else if (expr->kind == AST::Node::Kind_TrueLiteral) + return false; + else if (expr->kind == AST::Node::Kind_FalseLiteral) + return false; + else if (AST::NumericLiteral *lit = AST::cast(expr)) + return false; + else { + + if (AST::UnaryMinusExpression *unaryMinus = AST::cast(expr)) { + if (AST::NumericLiteral *lit = AST::cast(unaryMinus->expression)) { + return false; + } + } + } + } + + return true; +} + QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output) { jsUnitGenerator = &output.jsGenerator; diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h index 9273892..ec75c38 100644 --- a/src/qml/compiler/qqmlcodegenerator_p.h +++ b/src/qml/compiler/qqmlcodegenerator_p.h @@ -247,6 +247,8 @@ public: QString stringAt(int index) const { return jsGenerator->strings.at(index); } + static bool isStatementNodeScript(AST::Statement *statement); + QList errors; QList _imports; diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 9186086..5159ac5 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -336,6 +336,7 @@ struct Property quint32 aliasPropertyValueIndex; quint32 flags; // readonly Location location; + Location aliasLocation; // If type == Alias }; struct Object diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 1882d35..e41248b 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -1552,8 +1552,10 @@ bool QQmlComponentAndAliasResolver::resolveAliases() const int idIndex = p->aliasIdValueIndex; const int targetObjectIndex = _idToObjectIndex.value(idIndex, -1); - if (targetObjectIndex == -1) - COMPILE_EXCEPTION(p, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex))); + if (targetObjectIndex == -1) { + recordError(p->aliasLocation, tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex))); + return false; + } const int targetId = _objectIndexToIdInScope->value(targetObjectIndex, -1); Q_ASSERT(targetId != -1); @@ -1596,8 +1598,10 @@ bool QQmlComponentAndAliasResolver::resolveAliases() QtQml::PropertyResolver resolver(targetCache); QQmlPropertyData *targetProperty = resolver.property(property.toString()); - if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) - COMPILE_EXCEPTION(p, tr("Invalid alias location")); + if (!targetProperty || targetProperty->coreIndex > 0x0000FFFF) { + recordError(p->aliasLocation, tr("Invalid alias location")); + return false; + } propIdx = targetProperty->coreIndex; type = targetProperty->propType; @@ -1608,15 +1612,19 @@ bool QQmlComponentAndAliasResolver::resolveAliases() if (!subProperty.isEmpty()) { QQmlValueType *valueType = QQmlValueTypeFactory::valueType(type); - if (!valueType) - COMPILE_EXCEPTION(p, tr("Invalid alias location")); + if (!valueType) { + recordError(p->aliasLocation, tr("Invalid alias location")); + return false; + } propType = type; int valueTypeIndex = valueType->metaObject()->indexOfProperty(subProperty.toString().toUtf8().constData()); - if (valueTypeIndex == -1) - COMPILE_EXCEPTION(p, tr("Invalid alias location")); + if (valueTypeIndex == -1) { + recordError(p->aliasLocation, tr("Invalid alias location")); + return false; + } Q_ASSERT(valueTypeIndex <= 0x0000FFFF); propIdx |= (valueTypeIndex << 16); -- 2.7.4