Exemple #1
0
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);
}
void MoveObjectBeforeObjectVisitor::doMove()
{
    Q_ASSERT(movingObject);
    Q_ASSERT(!movingObjectParents.isEmpty());

    TextModifier::MoveInfo moveInfo;
    QmlJS::AST::Node *parent = movingObjectParent();
    QmlJS::AST::UiArrayMemberList *arrayMember = 0, *otherArrayMember = 0;
    QString separator;

    if (!inDefaultProperty) {
        QmlJS::AST::UiArrayBinding *initializer = QmlJS::AST::cast<QmlJS::AST::UiArrayBinding*>(parent);
        Q_ASSERT(initializer);

        otherArrayMember = 0;
        for (QmlJS::AST::UiArrayMemberList *cur = initializer->members; cur; cur = cur->next) {
            if (cur->member == movingObject) {
                arrayMember = cur;
                if (cur->next)
                    otherArrayMember = cur->next;
                break;
            }
            otherArrayMember = cur;
        }
        Q_ASSERT(arrayMember && otherArrayMember);
        separator = QStringLiteral(",");
    }

    moveInfo.objectStart = movingObject->firstSourceLocation().offset;
    moveInfo.objectEnd = movingObject->lastSourceLocation().end();

    int start = moveInfo.objectStart;
    int end = moveInfo.objectEnd;
    if (!inDefaultProperty) {
        if (arrayMember->commaToken.isValid())
            start = arrayMember->commaToken.begin();
        else
            end = otherArrayMember->commaToken.end();
    }

    includeSurroundingWhitespace(start, end);
    moveInfo.leadingCharsToRemove = moveInfo.objectStart - start;
    moveInfo.trailingCharsToRemove = end - moveInfo.objectEnd;

    if (beforeObject) {
        moveInfo.destination = beforeObject->firstSourceLocation().offset;
        int dummy = -1;
        includeSurroundingWhitespace(moveInfo.destination, dummy);

        moveInfo.prefixToInsert = QString(moveInfo.leadingCharsToRemove, QLatin1Char(' '));
        moveInfo.suffixToInsert = separator + QStringLiteral("\n\n");
    } else {
        const QmlJS::AST::SourceLocation insertionPoint = lastParentLocation();
        Q_ASSERT(insertionPoint.isValid());
        moveInfo.destination = insertionPoint.offset;
        int dummy = -1;
        includeSurroundingWhitespace(moveInfo.destination, dummy);

        moveInfo.prefixToInsert = separator + QString(moveInfo.leadingCharsToRemove, QLatin1Char(' '));
        moveInfo.suffixToInsert = QStringLiteral("\n");
    }

    move(moveInfo);
    setDidRewriting(true);
}