QmlJS::AST::SourceLocation QMLRewriter::calculateLocation(QmlJS::AST::UiQualifiedId *id) { Q_ASSERT(id != 0); const QmlJS::AST::SourceLocation startLocation = id->identifierToken; QmlJS::AST::UiQualifiedId *nextId = id; while (nextId->next) { nextId = nextId->next; } const QmlJS::AST::SourceLocation endLocation = nextId->identifierToken; return QmlJS::AST::SourceLocation(startLocation.offset, endLocation.end() - startLocation.offset); }
// FIXME: duplicate code in the QmlJS::Rewriter class, remove this void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializer) { QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder); QmlJS::AST::SourceLocation endOfPreviousMember; QmlJS::AST::SourceLocation startOfNextMember; unsigned depth; if (insertAfter == 0 || insertAfter->member == 0) { // insert as first member endOfPreviousMember = initializer->lbraceToken; if (initializer->members && initializer->members->member) startOfNextMember = initializer->members->member->firstSourceLocation(); else startOfNextMember = initializer->rbraceToken; depth = calculateIndentDepth(endOfPreviousMember) + indentDepth(); } else { endOfPreviousMember = insertAfter->member->lastSourceLocation(); if (insertAfter->next && insertAfter->next->member) startOfNextMember = insertAfter->next->member->firstSourceLocation(); else startOfNextMember = initializer->rbraceToken; depth = calculateIndentDepth(endOfPreviousMember); } const bool isOneLiner = endOfPreviousMember.startLine == startOfNextMember.startLine; bool needsPreceedingSemicolon = false; bool needsTrailingSemicolon = false; if (isOneLiner) { if (insertAfter == 0) { // we're inserting after an lbrace if (initializer->members) { // we're inserting before a member (and not the rbrace) needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding; } } else { // we're inserting after a member, not after the lbrace if (endOfPreviousMember.isValid()) { // there already is a semicolon after the previous member if (insertAfter->next && insertAfter->next->member) { // and the after us there is a member, not an rbrace, so: needsTrailingSemicolon = m_propertyType == QmlRefactoring::ScriptBinding; } } else { // there is no semicolon after the previous member (probably because there is an rbrace after us/it, so: needsPreceedingSemicolon = true; } } } QString newPropertyTemplate; switch (m_propertyType) { case QmlRefactoring::ArrayBinding: newPropertyTemplate = QStringLiteral("%1: [\n%2\n]"); m_value = addIndentation(m_value, 4); break; case QmlRefactoring::ObjectBinding: newPropertyTemplate = QStringLiteral("%1: %2"); break; case QmlRefactoring::ScriptBinding: newPropertyTemplate = QStringLiteral("%1: %2"); break; default: Q_ASSERT(!"unknown property type"); } if (!m_dynamicTypeName.isEmpty()) newPropertyTemplate.prepend(QStringLiteral("property %1 ").arg(QString::fromUtf8(m_dynamicTypeName))); if (isOneLiner) { if (needsPreceedingSemicolon) newPropertyTemplate.prepend(QLatin1Char(';')); newPropertyTemplate.prepend(QLatin1Char(' ')); if (needsTrailingSemicolon) newPropertyTemplate.append(QLatin1Char(';')); depth = 0; } else { newPropertyTemplate.prepend(QLatin1Char('\n')); } const QString newPropertyText = addIndentation(newPropertyTemplate.arg(QString::fromLatin1(m_name), m_value), depth); replace(endOfPreviousMember.end(), 0, newPropertyText); setDidRewriting(true); }