void addLogSourceEntry(const QString &text, const TokenContainer &tokenContainer, const int index)
{
    Logger *logger = Logger::instance();
    int line = tokenContainer.line(index);
    int col = tokenContainer.column(index);
    SourcePointLogEntry *logEntry =
                new SourcePointLogEntry(QLatin1String("Info"), QLatin1String("Porting"),
                                        logger->globalState.value(QLatin1String("currentFileName")),
                                        line, col, text);
    logger->addEntry(logEntry);
}
bool GenericTokenReplacement::doReplace(const TokenContainer &tokenContainer,
                            int index, TextReplacements &textReplacements)
{
    QByteArray tokenText = tokenContainer.text(index);
    if(tokenText == oldToken){
        addLogSourceEntry(QString::fromLatin1(tokenText + QByteArray(" -> ") + newToken), tokenContainer, index);
        TokenEngine::Token token = tokenContainer.token(index);
        textReplacements.insert(newToken, token.start, token.length);
        return true;
    }
    return false;

}
Exemple #3
0
QVector<Type> RppLexer::lex(const TokenContainer &tokenContainer)
{
    QVector<Type> tokenTypes;
    const int numTokens = tokenContainer.count();
    tokenTypes.reserve(numTokens);
    QByteArray text = tokenContainer.fullText();
    m_buffer = text.constData();
    for(int t=0; t<numTokens; ++t) {
        TokenEngine::Token token = tokenContainer.token(t);
        tokenTypes.append(indentify(token.start, token.length));
    }
    return tokenTypes;
}
/*
    Replace a class name token. If the class name is a scope specifier (a "qualifier")
    in a qualified name, we check if qualified name will be replaced by a porting rule.
    If so, we don't do the class name replacement.
*/
bool ClassNameReplacement::doReplace(const TokenContainer &tokenContainer, int index, TextReplacements &textReplacements)
{
    QByteArray tokenText = tokenContainer.text(index);
    if(tokenText != oldToken)
        return false;

    QualifiedNameParser nameParser(tokenContainer, index);
    if(nameParser.isPartOfQualifiedName() &&
       nameParser.peek(QualifiedNameParser::Right) != -1) {
        int nameTokenIndex = nameParser.peek(QualifiedNameParser::Right);
        QByteArray name = tokenContainer.text(nameTokenIndex); 
        TextReplacements textReplacements;
        QList<TokenReplacement*> tokenReplacements
            = PortingRules::instance()->getTokenReplacementRules();
        bool changed = false;
        foreach(TokenReplacement *tokenReplacement, tokenReplacements) {
            changed = tokenReplacement->doReplace(tokenContainer, nameTokenIndex, textReplacements);
            if(changed)
                break;
        }
void RppTreeEvaluator::evaluateText(const Text *textLine)
{
    const int numTokens = textLine->count();
    const TokenContainer tokenContainer = textLine->text().tokenContainer(0);

    int t = 0;
    int startTokenRun = 0;
    while(t < numTokens) {
        const Token *currentToken = textLine->token(t);
        int currentContainerIndex = currentToken->index();
        //handle macro replacements
        if(currentToken->toIdToken()) {
            const int tokenIndex = currentToken->index();
            const QByteArray tokenText = tokenContainer.tempText(tokenIndex);
            if(m_activeDefinitions->contains(tokenText)) {
                //crate section
                TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun);
                m_tokenSections.append(section);
                //evaluate macro
                const int oldContainerIndex = currentContainerIndex;
                TokenContainer evaluatedText = evaluateMacro(tokenContainer, currentContainerIndex);
                TokenSection evalSection(evaluatedText, 0, evaluatedText.count());
                m_tokenSections.append(evalSection);
                t += currentContainerIndex - oldContainerIndex;
                startTokenRun = t;
            }
            ++t;
            continue;
        }

        //handle comments
        if(currentToken->toLineComment() || currentToken->toMultiLineComment()) {
            //create section
            TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun );
            m_tokenSections.append(section);
            t++; //skip comment
            startTokenRun = t;
            t++;
            continue;
        }

        // handle escaped newlines
		if (currentContainerIndex + 1 < numTokens) {
            const TokenTempRef tokenRef1 = tokenContainer.tokenTempRef(currentContainerIndex);
            const TokenTempRef tokenRef2 = tokenContainer.tokenTempRef(currentContainerIndex + 1);
			// This is i slight hack. We want to check if the next token is a newline token,
			// but since we don't have any lexical info at this point we just check if it starts
			// with \r or \n
			if (tokenRef1.at(0) == '\\' && (tokenRef2.at(0) == '\n' || tokenRef2.at(0) == '\r')) {
				//create section
                TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun );
                m_tokenSections.append(section);
                t += 2;
                startTokenRun = t;
                t++;
                continue;
            }
        }

        t++;
    }
    //round up any tokens at the end and put them in a section
    if(t - startTokenRun > 1) {
        TokenSection section(tokenContainer, textLine->token(startTokenRun)->index(), t - startTokenRun );
        m_tokenSections.append(section);
    }

    m_tokenSections.append(*newlineSection);
}
/*
    Recursively evaluates an Expression
*/
int RppTreeEvaluator::evaluateExpression(Expression *expression)
{
    if (IntLiteral *e = expression->toIntLiteral()) {
        return e->value();
    } else if (StringLiteral *e = expression->toStringLiteral()) {
        return e->value().size();
    } else if (MacroReference *e = expression->toMacroReference()) {
       switch(e->type()) {
           case MacroReference::DefinedRef: {
               return m_activeDefinitions->contains(e->name().fullText()) ? 1 : 0;
           } case MacroReference::ValueRef: {
               const QByteArray identifier = e->name().fullText();
               if (m_activeDefinitions->contains(identifier)) {
                   int token = e->name().containerIndex(0);
                   TokenContainer value = evaluateMacro(e->name().tokenContainer(token), token);
                   return QString(QLatin1String(value.fullText())).toInt(0, 0);
               } else {
                   return 0; // error
               }
           }
           default: Q_ASSERT(0);
        }
    } else if (MacroFunctionReference *e = expression->toMacroFunctionReference()) {
        Q_UNUSED(e);
        //TODO handle MacroFunctionReference
//        DefineDirective *def = e->findDefinition(e->name());
//        Q_ASSERT(def->toMacroFunctionDefinition());
//        qWarning("not implemented yet");
        return 0;
    } else if (UnaryExpression *e = expression->toUnaryExpression()) {
        int result = evaluateExpression(e->expression());
        switch (e->op()) {
            case '+': return + result;
            case '-': return - result;
            case '!': return ! result;
            case '~': return ~ result;
            default:  Q_ASSERT(0);
        }
    } else if (BinaryExpression *e = expression->toBinaryExpression()) {
        int v1 = evaluateExpression(e->leftExpression());
        int v2 = evaluateExpression(e->rightExpression());

        switch (e->op()) {
            case '/': { return v2 ? v1 / v2 : 0; } //avoid division by zero
            case '*':                  return v1 * v2;
            case '%': { return v2 ? v1 % v2 : 0; } //avoid modulus by zero
            case '+':                  return v1 + v2;
            case '-':                  return v1 - v2;
            case '<':                  return v1 < v2;
            case '>':                  return v1 > v2;
            case '&':                  return v1 & v2;
            case '^':                  return v1 ^ v2;
            case '|':                  return v1 | v2;
            case Expression::LtEqOp:   return v1 <= v2;
            case Expression::GtEqOp:   return v1 >= v2;
            case Expression::EqOp:     return v1 == v2;
            case Expression::NotEqOp:  return v1 != v2;
            case Expression::AndOp:    return v1 && v2;
            case Expression::OrOp:     return v1 || v2;
            case Expression::LShiftOp: return v1 << v2;
            case Expression::RShiftOp: return v1 >> v2;
            default:    Q_ASSERT(0);
        }

    } else if ( ConditionalExpression *e = expression->toConditionalExpression()){