void insertInto(UiObjectInitializer *ast) { if (targetPropertyName.isEmpty()) { // insert as UiObjectDefinition: UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, propertyOrder); if (insertAfter && insertAfter->member) { moveInfo.destination = insertAfter->member->lastSourceLocation().end(); moveInfo.prefixToInsert = QStringLiteral("\n\n"); } else { moveInfo.destination = ast->lbraceToken.end(); moveInfo.prefixToInsert = QStringLiteral("\n"); } move(moveInfo); setDidRewriting(true); return; } // see if we need to insert into an UiArrayBinding: for (UiObjectMemberList *iter = ast->members; iter; iter = iter->next) { UiObjectMember *member = iter->member; if (UiArrayBinding *arrayBinding = cast<UiArrayBinding*>(member)) { if (toString(arrayBinding->qualifiedId) == targetPropertyName) { appendToArray(arrayBinding); setDidRewriting(true); return; } } } { // insert (create) a UiObjectBinding: UiObjectMemberList *insertAfter = searchMemberToInsertAfter(ast->members, targetPropertyName, propertyOrder); moveInfo.prefixToInsert = QStringLiteral("\n") + targetPropertyName + (targetIsArrayBinding ? QStringLiteral(": [") : QStringLiteral(": ")); moveInfo.suffixToInsert = targetIsArrayBinding ? QStringLiteral("\n]") : QStringLiteral(""); if (insertAfter && insertAfter->member) moveInfo.destination = insertAfter->member->lastSourceLocation().end(); else moveInfo.destination = ast->lbraceToken.end(); move(moveInfo); setDidRewriting(true); } }
// 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); }