DebugVisitor: catch and show invalid token indizes
ClosedPublic

Authored by kossebau on May 29 2017, 2:52 PM.

Details

Summary

Current parsing logic can generate tokens with token range [0,-1]
(e.g. if some expected token at the start is not existing in the
input), so the debug logic needs to handle such invalid token indizes.

Diff Detail

Repository
R51 KDevelop: PG Qt
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.
kossebau created this revision.May 29 2017, 2:52 PM
Restricted Application added a subscriber: kdevelop-devel. · View Herald TranscriptMay 29 2017, 2:52 PM

Example output with an invalid token index:

QDEBUG : Css::TestParser::parser(one declaration without semicolon) start[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon) imports->importList[0, 0, 0] --- [invalid token index: -1]  ""
QDEBUG : Css::TestParser::parser(one declaration without semicolon) rules->ruleList[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)  importList[0, 0, 0] --- [invalid token index: -1]  ""
QDEBUG : Css::TestParser::parser(one declaration without semicolon)  ruleList[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)  rules[]->rule[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)   rule[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)   ruleset->ruleset[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)    ruleset[0, 0, 0] --- [14, 0, 14]  "body{color:red}"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)    selectors->selectorList[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)    declarations->declarationList[5, 0, 5] --- [11, 0, 11]  "color:red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)     selectorList[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)     selectors[]->selector[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)      selector[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)      simpleSelector->simpleSelectorWithWhitespace[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)       simpleSelectorWithWhitespace[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)       simpleSelector->simpleSelector[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)        simpleSelector[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)        element->elementName[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)         elementName[0, 0, 0] --- [0, 0, 0]  "body"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)     declarationList[5, 0, 5] --- [11, 0, 11]  "color:red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)     declarations[]->declaration[5, 0, 5] --- [11, 0, 11]  "color:red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)      declaration[5, 0, 5] --- [11, 0, 11]  "color:red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)      property->property[5, 0, 5] --- [5, 0, 5]  "color"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)      expr->expr[11, 0, 11] --- [11, 0, 11]  "red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)       property[5, 0, 5] --- [5, 0, 5]  "color"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)       expr[11, 0, 11] --- [11, 0, 11]  "red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)       terms[]->term[11, 0, 11] --- [11, 0, 11]  "red"
QDEBUG : Css::TestParser::parser(one declaration without semicolon)        term[11, 0, 11] --- [11, 0, 11]  "red"
kossebau added a comment.EditedMay 29 2017, 2:56 PM

Generated code example:

void printToken(const AstNode *node, const QString &mType, const QString &mName = QString())
{
    KDevPG::TokenStream::Token startToken;
    KDevPG::TokenStream::Token endToken;
    qint64 line, column;
    const bool isValidStartToken = (0 <= node->startToken && node->startToken < m_str->size());
    QString startTokenString;
    if (isValidStartToken)
    {
        startToken = m_str->at(node->startToken);
        m_str->startPosition(node->startToken, &line, &column);
        startTokenString = QString::number(startToken.begin) + QLatin1String(", ") + QString::number(line) + QLatin1String(", ") + QString::number(column);
    }
    else
    {
        startTokenString = QLatin1String("invalid token index: ") + QString::number(node->startToken);
    }
    const bool isValidEndToken = (0 <= node->endToken && node->endToken < m_str->size());
    QString endTokenString;
    if (isValidEndToken)
    {
        endToken = m_str->at(node->endToken);
        m_str->startPosition(node->endToken, &line, &column);
        endTokenString = QString::number(endToken.begin) + QLatin1String(", ") + QString::number(line) + QLatin1String(", ") + QString::number(column);
    }
    else
    {
        endTokenString = QLatin1String("invalid token index: ") + QString::number(node->endToken);
    }
    QString tokenString;
    if (!m_content.isEmpty() && isValidStartToken && isValidEndToken)
    {
        const int begin = startToken.begin;
        const int end = endToken.end;
        if (end-begin > 30)
        {
            tokenString = m_content.mid(begin, 10);
            tokenString += QStringLiteral(" ...");
            tokenString += QStringLiteral("%1 more").arg(end-begin-20);
            tokenString += QStringLiteral("... ");
            tokenString += m_content.midRef(end-10, 10);
        }
        else
        {
            tokenString = m_content.mid(begin, end-begin+1);
        }
        tokenString.replace('\n', QStringLiteral("\\n"));
        tokenString.replace('\r', QStringLiteral("\\r"));
    }
    qDebug() << QString(QString().fill(QLatin1Char(' '), m_indent) + mName + QLatin1String(!mName.isEmpty() ? "->" : "") + mType + QLatin1Char('[') + startTokenString + QLatin1String("] --- [") + endTokenString + QLatin1String("] ")).toUtf8().constData() << tokenString;
}

No-one actively interested in pg-qt these days? :) Will push this Friday then, if no-one objects.

kfunk accepted this revision.Jun 5 2017, 12:17 PM
kfunk added a subscriber: kfunk.

Looks good to me.

This revision is now accepted and ready to land.Jun 5 2017, 12:17 PM
This revision was automatically updated to reflect the committed changes.