예제 #1
0
static void debugCppSymbolRecursion(QTextStream &str, const Overview &o,
                                    const Symbol &s, bool doRecurse = true,
                                    int recursion = 0)
{
    for (int i = 0; i < recursion; i++)
        str << "  ";
    str << "Symbol: " << o.prettyName(s.name()) << " at line " << s.line();
    if (s.isFunction())
        str << " function";
    if (s.isClass())
        str << " class";
    if (s.isDeclaration())
        str << " declaration";
    if (s.isBlock())
        str << " block";
    if (doRecurse && s.isScope()) {
        const Scope *scoped = s.asScope();
        const int size =  scoped->memberCount();
        str << " scoped symbol of " << size << '\n';
        for (int m = 0; m < size; m++)
            debugCppSymbolRecursion(str, o, *scoped->memberAt(m), true, recursion + 1);
    } else {
        str << '\n';
    }
}
예제 #2
0
int OverviewModel::rowCount(const QModelIndex &parent) const
{
    if (hasDocument()) {
        if (!parent.isValid()) {
            return globalSymbolCount()+1; // account for no symbol item
        } else {
            if (!parent.parent().isValid() && parent.row() == 0) // account for no symbol item
                return 0;
            Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
            Q_ASSERT(parentSymbol);

            if (Template *t = parentSymbol->asTemplate())
                if (Symbol *templateParentSymbol = t->declaration())
                    parentSymbol = templateParentSymbol;

            if (Scope *parentScope = parentSymbol->asScope()) {
                if (!parentScope->isFunction() && !parentScope->isObjCMethod())
                    return parentScope->memberCount();
            }
            return 0;
        }
    }
    if (!parent.isValid())
        return 1; // account for no symbol item
    return 0;
}
예제 #3
0
QModelIndex OverviewModel::index(int row, int column, const QModelIndex &parent) const
{
    if (!parent.isValid()) {
        if (row == 0) // account for no symbol item
            return createIndex(row, column);
        Symbol *symbol = globalSymbolAt(row-1); // account for no symbol item
        return createIndex(row, column, symbol);
    } else {
        Symbol *parentSymbol = static_cast<Symbol *>(parent.internalPointer());
        Q_ASSERT(parentSymbol);

        Scope *scope = parentSymbol->asScope();
        Q_ASSERT(scope != 0);
        return createIndex(row, 0, scope->memberAt(row));
    }
}
예제 #4
0
/*!
 * Extract the function name including scope at the given position.
 *
 * Note that a function (scope) starts at the name of that function, not at the return type. The
 * implication is that this function will return an empty string when the line/column is on the
 * return type.
 *
 * \param line the line number, starting with line 1
 * \param column the column number, starting with column 1
 * \param lineOpeningDeclaratorParenthesis optional output parameter, the line of the opening
          parenthesis of the declarator starting with 1
 * \param lineClosingBrace optional output parameter, the line of the closing brace starting with 1
 */
QString Document::functionAt(int line, int column, int *lineOpeningDeclaratorParenthesis,
                             int *lineClosingBrace) const
{
    if (line < 1 || column < 1)
        return QString();

    Symbol *symbol = lastVisibleSymbolAt(line, column);
    if (!symbol)
        return QString();

    // Find the enclosing function scope (which might be several levels up, or we might be standing
    // on it)
    Scope *scope = symbol->asScope();
    if (!scope)
        scope = symbol->enclosingScope();

    while (scope && !scope->isFunction() )
        scope = scope->enclosingScope();

    if (!scope)
        return QString();

    // We found the function scope
    if (lineOpeningDeclaratorParenthesis) {
        unsigned line;
        translationUnit()->getPosition(scope->startOffset(), &line);
        *lineOpeningDeclaratorParenthesis = static_cast<int>(line);
    }

    if (lineClosingBrace) {
        unsigned line;
        translationUnit()->getPosition(scope->endOffset(), &line);
        *lineClosingBrace = static_cast<int>(line);
    }

    const QList<const Name *> fullyQualifiedName = LookupContext::fullyQualifiedName(scope);
    return Overview().prettyName(fullyQualifiedName);
}
/*! Handle declaration in if, while and for statements */
void PointerDeclarationFormatter::processIfWhileForStatement(ExpressionAST *expression,
                                                             Symbol *statementSymbol)
{
    CHECK_R(expression, "No expression");
    CHECK_R(statementSymbol, "No symbol");

    ConditionAST *condition = expression->asCondition();
    CHECK_R(condition, "No condition");
    DeclaratorAST *declarator = condition->declarator;
    CHECK_R(declarator, "No declarator");
    CHECK_R(declarator->ptr_operator_list, "No Pointer or references");
    CHECK_R(declarator->equal_token, "No equal token");
    Block *block = statementSymbol->asBlock();
    CHECK_R(block, "No block");
    CHECK_R(block->memberCount() > 0, "No block members");

    // Get the right symbol
    //
    // This is especially important for e.g.
    //
    //    for (char *s = 0; char *t = 0;) {}
    //
    // The declaration for 's' will be handled in visit(SimpleDeclarationAST *ast),
    // so handle declaration for 't' here.
    Scope::iterator it = block->lastMember() - 1;
    Symbol *symbol = *it;
    if (symbol && symbol->asScope()) { // True if there is a  "{ ... }" following.
        --it;
        symbol = *it;
    }

    // Specify activation range
    TokenRange range(condition->firstToken(), declarator->equal_token - 1);

    checkAndRewrite(declarator, symbol, range);
}