From 30676c1a17a6036d71ff821e4ae9efc6d5e82ca8 Mon Sep 17 00:00:00 2001 From: Shane Bradley Date: Wed, 27 Jul 2011 18:10:00 +1000 Subject: [PATCH] Add mimetype support for system testcases to qml editor System test-cases are (assumed to be) written in javascript when using an .qtt filename extension. These modificatons ensure that a js editor is used whenever an attempt is made to open a file that ends with .qtt. Also add support for recognising testcases to QmlOutlineModel. Change-Id: Ibcb68126e5123e8069344cf0c05aa2396b967a12 Reviewed-on: http://codereview.qt.nokia.com/2259 Reviewed-by: Qt Sanity Bot Reviewed-by: Leandro T. C. Melo Reviewed-by: Bill King --- .../qmljseditor/QmlJSEditor.mimetypes.xml | 1 + src/plugins/qmljseditor/qmloutlinemodel.cpp | 85 +++++++++++++++++++ src/plugins/qmljseditor/qmloutlinemodel.h | 7 ++ 3 files changed, 93 insertions(+) diff --git a/src/plugins/qmljseditor/QmlJSEditor.mimetypes.xml b/src/plugins/qmljseditor/QmlJSEditor.mimetypes.xml index 044d71fbf64..f5ddfda7de0 100644 --- a/src/plugins/qmljseditor/QmlJSEditor.mimetypes.xml +++ b/src/plugins/qmljseditor/QmlJSEditor.mimetypes.xml @@ -14,5 +14,6 @@ Qt Script file + diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp index 862852db1f3..c3107322322 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.cpp +++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp @@ -266,6 +266,38 @@ private: m_model->leaveFunctionDeclaration(); } + bool visit(AST::BinaryExpression *binExp) + { + AST::IdentifierExpression *lhsIdent = AST::cast(binExp->left); + AST::ObjectLiteral *rhsObjLit = AST::cast(binExp->right); + + if (lhsIdent && rhsObjLit && (lhsIdent->name->asString() == "testcase") + && (binExp->op == QSOperator::Assign)) { + QModelIndex index = m_model->enterTestCase(rhsObjLit); + m_nodeToIndex.insert(rhsObjLit, index); + + if (AST::PropertyNameAndValueList *properties = rhsObjLit->properties) + visitProperties(properties); + + m_model->leaveTestCase(); + } + return true; + } + + void visitProperties(AST::PropertyNameAndValueList *properties) + { + while (properties) { + QModelIndex index = m_model->enterTestCaseProperties(properties); + m_nodeToIndex.insert(properties, index); + + if (AST::ObjectLiteral *objLiteral = AST::cast(properties->value)) + visitProperties(objLiteral->properties); + + m_model->leaveTestCaseProperties(); + properties = properties->next; + } + } + QmlOutlineModel *m_model; QHash m_nodeToIndex; @@ -553,6 +585,49 @@ void QmlOutlineModel::leaveFunctionDeclaration() leaveNode(); } +QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectLiteral *objectLiteral) +{ + QMap objectData; + + objectData.insert(Qt::DisplayRole, "testcase"); + objectData.insert(ItemTypeRole, ElementBindingType); + + QmlOutlineItem *item = enterNode(objectData, objectLiteral, 0, m_icons->objectDefinitionIcon()); + + return item->index(); +} + +void QmlOutlineModel::leaveTestCase() +{ + leaveNode(); +} + +QModelIndex QmlOutlineModel::enterTestCaseProperties(AST::PropertyNameAndValueList *propertyNameAndValueList) +{ + QMap objectData; + if (AST::IdentifierPropertyName *propertyName = AST::cast(propertyNameAndValueList->name)) { + objectData.insert(Qt::DisplayRole, propertyName->id->asString()); + objectData.insert(ItemTypeRole, ElementBindingType); + QmlOutlineItem *item; + if (propertyNameAndValueList->value->kind == AST::Node::Kind_FunctionExpression) { + item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->functionDeclarationIcon()); + } else if (propertyNameAndValueList->value->kind == AST::Node::Kind_ObjectLiteral) { + item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->objectDefinitionIcon()); + } else { + item = enterNode(objectData, propertyNameAndValueList, 0, m_icons->scriptBindingIcon()); + } + + return item->index(); + } else { + return QModelIndex(); + } +} + +void QmlOutlineModel::leaveTestCaseProperties() +{ + leaveNode(); +} + AST::Node *QmlOutlineModel::nodeForIndex(const QModelIndex &index) const { QTC_ASSERT(index.isValid() && (index.model() == this), return 0); @@ -575,6 +650,8 @@ AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) co location = getLocation(member); } else if (AST::ExpressionNode *expression = node->expressionCast()) { location = getLocation(expression); + } else if (AST::PropertyNameAndValueList *propertyNameAndValueList = AST::cast(node)) { + location = getLocation(propertyNameAndValueList); } } return location; @@ -847,6 +924,14 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode) return location; } +AST::SourceLocation QmlOutlineModel::getLocation(AST::PropertyNameAndValueList *propertyNode) { + AST::SourceLocation location; + location.offset = propertyNode->name->propertyNameToken.offset; + location.length = propertyNode->value->lastSourceLocation().end() - location.offset; + + return location; +} + QIcon QmlOutlineModel::getIcon(AST::UiQualifiedId *qualifiedId) { QIcon icon; if (qualifiedId) { diff --git a/src/plugins/qmljseditor/qmloutlinemodel.h b/src/plugins/qmljseditor/qmloutlinemodel.h index 914a75a47f0..fea526125d1 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.h +++ b/src/plugins/qmljseditor/qmloutlinemodel.h @@ -125,6 +125,12 @@ private: QModelIndex enterFunctionDeclaration(QmlJS::AST::FunctionDeclaration *functionDeclaration); void leaveFunctionDeclaration(); + QModelIndex enterTestCase(QmlJS::AST::ObjectLiteral *objectLiteral); + void leaveTestCase(); + + QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyNameAndValueList *propertyNameAndValueList); + void leaveTestCaseProperties(); + private: QmlOutlineItem *enterNode(QMap data, QmlJS::AST::Node *node, QmlJS::AST::UiQualifiedId *idNode, const QIcon &icon); void leaveNode(); @@ -139,6 +145,7 @@ private: static QString asString(QmlJS::AST::UiQualifiedId *id); static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember); static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::ExpressionNode *exprNode); + static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValueList *propertyNode); QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef); QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);