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 <qt_sanity_bot@ovi.com>
Reviewed-by: Leandro T. C. Melo <leandro.melo@nokia.com>
Reviewed-by: Bill King <bill.king@nokia.com>
This commit is contained in:
Shane Bradley
2011-07-27 18:10:00 +10:00
committed by Bill King
parent 2a2bde0510
commit 30676c1a17
3 changed files with 93 additions and 0 deletions

View File

@@ -14,5 +14,6 @@
<comment>Qt Script file</comment> <comment>Qt Script file</comment>
<glob pattern="*.js"/> <glob pattern="*.js"/>
<glob pattern="*.qs"/> <glob pattern="*.qs"/>
<glob pattern="*.qtt"/>
</mime-type> </mime-type>
</mime-info> </mime-info>

View File

@@ -266,6 +266,38 @@ private:
m_model->leaveFunctionDeclaration(); m_model->leaveFunctionDeclaration();
} }
bool visit(AST::BinaryExpression *binExp)
{
AST::IdentifierExpression *lhsIdent = AST::cast<AST::IdentifierExpression *>(binExp->left);
AST::ObjectLiteral *rhsObjLit = AST::cast<AST::ObjectLiteral *>(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<AST::ObjectLiteral *>(properties->value))
visitProperties(objLiteral->properties);
m_model->leaveTestCaseProperties();
properties = properties->next;
}
}
QmlOutlineModel *m_model; QmlOutlineModel *m_model;
QHash<AST::Node*, QModelIndex> m_nodeToIndex; QHash<AST::Node*, QModelIndex> m_nodeToIndex;
@@ -553,6 +585,49 @@ void QmlOutlineModel::leaveFunctionDeclaration()
leaveNode(); leaveNode();
} }
QModelIndex QmlOutlineModel::enterTestCase(AST::ObjectLiteral *objectLiteral)
{
QMap<int, QVariant> 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<int, QVariant> objectData;
if (AST::IdentifierPropertyName *propertyName = AST::cast<AST::IdentifierPropertyName *>(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 AST::Node *QmlOutlineModel::nodeForIndex(const QModelIndex &index) const
{ {
QTC_ASSERT(index.isValid() && (index.model() == this), return 0); QTC_ASSERT(index.isValid() && (index.model() == this), return 0);
@@ -575,6 +650,8 @@ AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) co
location = getLocation(member); location = getLocation(member);
} else if (AST::ExpressionNode *expression = node->expressionCast()) { } else if (AST::ExpressionNode *expression = node->expressionCast()) {
location = getLocation(expression); location = getLocation(expression);
} else if (AST::PropertyNameAndValueList *propertyNameAndValueList = AST::cast<AST::PropertyNameAndValueList *>(node)) {
location = getLocation(propertyNameAndValueList);
} }
} }
return location; return location;
@@ -847,6 +924,14 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode)
return location; 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 QmlOutlineModel::getIcon(AST::UiQualifiedId *qualifiedId) {
QIcon icon; QIcon icon;
if (qualifiedId) { if (qualifiedId) {

View File

@@ -125,6 +125,12 @@ private:
QModelIndex enterFunctionDeclaration(QmlJS::AST::FunctionDeclaration *functionDeclaration); QModelIndex enterFunctionDeclaration(QmlJS::AST::FunctionDeclaration *functionDeclaration);
void leaveFunctionDeclaration(); void leaveFunctionDeclaration();
QModelIndex enterTestCase(QmlJS::AST::ObjectLiteral *objectLiteral);
void leaveTestCase();
QModelIndex enterTestCaseProperties(QmlJS::AST::PropertyNameAndValueList *propertyNameAndValueList);
void leaveTestCaseProperties();
private: private:
QmlOutlineItem *enterNode(QMap<int, QVariant> data, QmlJS::AST::Node *node, QmlJS::AST::UiQualifiedId *idNode, const QIcon &icon); QmlOutlineItem *enterNode(QMap<int, QVariant> data, QmlJS::AST::Node *node, QmlJS::AST::UiQualifiedId *idNode, const QIcon &icon);
void leaveNode(); void leaveNode();
@@ -139,6 +145,7 @@ private:
static QString asString(QmlJS::AST::UiQualifiedId *id); static QString asString(QmlJS::AST::UiQualifiedId *id);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember); 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::ExpressionNode *exprNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PropertyNameAndValueList *propertyNode);
QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef); QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef);
QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer); QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);