Exemplo n.º 1
0
bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
{
    unsigned sourceLocation = locationOfDeclaratorId(ast->declarator);
    if (! sourceLocation) {
        if (ast->declarator)
            sourceLocation = ast->declarator->firstToken();
        else
            sourceLocation = ast->firstToken();
    }

    const Name *argName = 0;
    FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope);
    FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(),
                                                 _scope, &argName);
    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
    Argument *arg = control()->newArgument(sourceLocation, argName);
    ast->symbol = arg;
    if (ast->expression) {
        unsigned startOfExpression = ast->expression->firstToken();
        unsigned endOfExpression = ast->expression->lastToken();
        std::string buffer;
        for (unsigned index = startOfExpression; index != endOfExpression; ++index) {
            const Token &tk = tokenAt(index);
            if (tk.whitespace() || tk.newline())
                buffer += ' ';
            buffer += tk.spell();
        }
        const StringLiteral *initializer = control()->findOrInsertStringLiteral(buffer.c_str(), buffer.size());
        arg->setInitializer(initializer);
    }
    arg->setType(argTy);
    _scope->enterSymbol(arg);
    return false;
}
Exemplo n.º 2
0
bool CheckExpression::visit(TypeIdAST *ast)
{
    FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope);
    FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(), _scope);
    _fullySpecifiedType = declTy;
    return false;
}
Exemplo n.º 3
0
bool CheckDeclaration::visit(ExceptionDeclarationAST *ast)
{
    FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope);
    FullySpecifiedType qualTy = ty.qualifiedType();

    Name *name = 0;
    FullySpecifiedType declTy = semantic()->check(ast->declarator, qualTy,
                                                  _scope, &name);

    unsigned location = locationOfDeclaratorId(ast->declarator);
    if (! location) {
        if (ast->declarator)
            location = ast->declarator->firstToken();
        else
            location = ast->firstToken();
    }

    Declaration *symbol = control()->newDeclaration(location, name);
    symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
    symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
    symbol->setType(declTy);
    _scope->enterSymbol(symbol);

    return false;
}
Exemplo n.º 4
0
static QStringList collectFieldNames(ClassSpecifierAST *classAST, bool onlyTokensAndASTNodes)
{
    QStringList fields;
    Overview oo;
    Class *clazz = classAST->symbol;
    for (unsigned i = 0; i < clazz->memberCount(); ++i) {
        Symbol *s = clazz->memberAt(i);
        if (Declaration *decl = s->asDeclaration()) {
            const QString declName = oo(decl->name());
            const FullySpecifiedType ty = decl->type();
            if (const PointerType *ptrTy = ty->asPointerType()) {
                if (onlyTokensAndASTNodes) {
                    if (const NamedType *namedTy = ptrTy->elementType()->asNamedType()) {
                        if (oo(namedTy->name()).endsWith(QLatin1String("AST")))
                            fields.append(declName);
                    }
                } else {
                    fields.append(declName);
                }
            } else if (ty.isUnsigned()) {
                fields.append(declName);
            }
        }
    }
    return fields;
}
Exemplo n.º 5
0
bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast)
{
    if (!ast->method_prototype)
        return false;

    FullySpecifiedType ty = semantic()->check(ast->method_prototype, _scope);
    ObjCMethod *methodType = ty.type()->asObjCMethodType();
    if (!methodType)
        return false;

    Symbol *symbol;
    if (ast->function_body) {
        if (!semantic()->skipFunctionBodies()) {
            semantic()->check(ast->function_body, methodType->members());
        }

        symbol = methodType;
    } else {
        Declaration *decl = control()->newDeclaration(ast->firstToken(), methodType->name());
        decl->setType(methodType);
        symbol = decl;
    }

    symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
    symbol->setEndOffset(tokenAt(ast->lastToken()).offset);
    symbol->setVisibility(semantic()->currentVisibility());

    if (semantic()->isObjCClassMethod(ast->method_prototype->method_type_token))
        symbol->setStorage(Symbol::Static);

    _scope->enterSymbol(symbol);

    return false;
}
Exemplo n.º 6
0
bool CheckStatement::visit(QtMemberDeclarationAST *ast)
{
    const Name *name = 0;

    if (tokenKind(ast->q_token) == T_Q_D)
        name = control()->nameId(control()->findOrInsertIdentifier("d"));
    else
        name = control()->nameId(control()->findOrInsertIdentifier("q"));

    FullySpecifiedType declTy = semantic()->check(ast->type_id, _scope);

    if (tokenKind(ast->q_token) == T_Q_D) {
        if (NamedType *namedTy = declTy->asNamedType()) {
            if (const NameId *nameId = namedTy->name()->asNameId()) {
                std::string privateClass;
                privateClass += nameId->identifier()->chars();
                privateClass += "Private";

                const Name *privName = control()->nameId(control()->findOrInsertIdentifier(privateClass.c_str(),
                                                                                           privateClass.size()));
                declTy.setType(control()->namedType(privName));
            }
        }
    }

    Declaration *symbol = control()->newDeclaration(/*generated*/ 0, name);
    symbol->setType(control()->pointerType(declTy));

    _scope->enterSymbol(symbol);

    return false;
}
Exemplo n.º 7
0
 void accept(const FullySpecifiedType &ty)
 {
     TypeVisitor::accept(ty.type());
     unsigned flags = ty.flags();
     flags |= temps.back().flags();
     temps.back().setFlags(flags);
 }
Exemplo n.º 8
0
void TypePrettyPrinter::prependSpaceBeforeIndirection(const FullySpecifiedType &type)
{
    const bool elementTypeIsPointerOrReference = type.type()->isPointerType()
        || type.type()->isReferenceType();
    const bool elementIsConstPointerOrReference = elementTypeIsPointerOrReference && type.isConst();
    const bool shouldBindToLeftSpecifier = _overview->starBindFlags & Overview::BindToLeftSpecifier;
    if (elementIsConstPointerOrReference && ! shouldBindToLeftSpecifier)
        _text.prepend(QLatin1String(" "));
}
Exemplo n.º 9
0
bool CheckExpression::visit(CastExpressionAST *ast)
{
    FullySpecifiedType castTy = semantic()->check(ast->type_id, _scope);
    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
    if (_checkOldStyleCasts && ! castTy->isVoidType())
        translationUnit()->warning(ast->firstToken(),
                                   "ugly old style cast");
    return false;
}
Exemplo n.º 10
0
void CloneType::visit(NamedType *type)
{
    const Name *name = _clone->name(type->name(), _subst);
    FullySpecifiedType ty;
    if (_subst)
        ty = _subst->apply(name);
    if (! ty.isValid())
        ty = _control->namedType(name);
    _type.setType(ty.type());
}
Exemplo n.º 11
0
 virtual void visit(NamedType *type)
 {
     FullySpecifiedType ty = rewrite->env->apply(type->name(), rewrite);
     if (! ty->isUndefinedType()) {
         temps.append(ty);
     } else {
         const Name *name = rewrite->rewriteName(type->name());
         temps.append(control()->namedType(name));
     }
 }
Exemplo n.º 12
0
bool CheckExpression::visit(ConditionAST *ast)
{
    FullySpecifiedType typeSpecTy = semantic()->check(ast->type_specifier_list, _scope);
    const Name *name = 0;
    FullySpecifiedType declTy = semantic()->check(ast->declarator, typeSpecTy.qualifiedType(),
                                                  _scope, &name);
    Declaration *decl = control()->newDeclaration(ast->declarator->firstToken(), name);
    decl->setType(declTy);
    _scope->enterSymbol(decl);
    return false;
}
Exemplo n.º 13
0
void TypePrettyPrinter::outCV(const FullySpecifiedType &ty)
{
    if (ty.isConst() && ty.isVolatile())
        _text += QLatin1String("const volatile");

    else if (ty.isConst())
        _text += QLatin1String("const");

    else if (ty.isVolatile())
        _text += QLatin1String("volatile");
}
Exemplo n.º 14
0
void TypePrettyPrinter::prependCv(const FullySpecifiedType &ty)
{
    if (ty.isVolatile()) {
        prependWordSeparatorSpace();
        _text.prepend("volatile");
    }

    if (ty.isConst()) {
        prependWordSeparatorSpace();
        _text.prepend("const");
    }
}
Exemplo n.º 15
0
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty)
{
    if (ty.isSigned())
        _text += QLatin1String("signed ");

    else if (ty.isUnsigned())
        _text += QLatin1String("unsigned ");

    const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType;
    _fullySpecifiedType = ty;
    accept(ty.type());
    _fullySpecifiedType = previousFullySpecifiedType;
}
Exemplo n.º 16
0
FullySpecifiedType SubstitutionEnvironment::apply(const Name *name, Rewrite *rewrite) const
{
    if (name) {
        for (int index = _substs.size() - 1; index != -1; --index) {
            const Substitution *subst = _substs.at(index);

            FullySpecifiedType ty = subst->apply(name, rewrite);
            if (! ty->isUndefinedType())
                return ty;
        }
    }

    return FullySpecifiedType();
}
Exemplo n.º 17
0
FullySpecifiedType FullySpecifiedType::qualifiedType() const
{
    FullySpecifiedType ty = *this;
    ty.setFriend(false);
    ty.setRegister(false);
    ty.setStatic(false);
    ty.setExtern(false);
    ty.setMutable(false);
    ty.setTypedef(false);

    ty.setInline(false);
    ty.setVirtual(false);
    ty.setExplicit(false);
    return ty;
}
Exemplo n.º 18
0
std::string TypeNameSpeller::spellTypeName(const FullySpecifiedType& fullType,
                                           const CPlusPlus::Scope* scope,
                                           std::string* alpha)
{
    spelling_.clear();
    alpha_ = alpha;

    if (fullType.isUnsigned())
        spelling_.append("unsigned ");

    scope_ = scope;
    accept(fullType.type());

    return spelling_;
}
Exemplo n.º 19
0
bool FullySpecifiedType::match(const FullySpecifiedType &otherTy, TypeMatcher *matcher) const
{
    if (_flags != otherTy._flags)
        return false;

    return type()->matchType(otherTy.type(), matcher);
}
Exemplo n.º 20
0
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty)
{
    const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType;
    _fullySpecifiedType = ty;
    accept(ty.type());
    _fullySpecifiedType = previousFullySpecifiedType;
}
Exemplo n.º 21
0
QList<Function *> FunctionUtils::overrides(Function *function, Class *functionsClass,
                                           Class *staticClass, const Snapshot &snapshot)
{
    QList<Function *> result;
    QTC_ASSERT(function && functionsClass && staticClass, return result);

    FullySpecifiedType referenceType = function->type();
    const Name *referenceName = function->name();
    QTC_ASSERT(referenceName && referenceType.isValid(), return result);

    // Find overrides
    TypeHierarchyBuilder builder(staticClass, snapshot);
    const TypeHierarchy &staticClassHierarchy = builder.buildDerivedTypeHierarchy();

    QList<TypeHierarchy> l;
    if (functionsClass != staticClass)
        l.append(TypeHierarchy(functionsClass));
    l.append(staticClassHierarchy);

    while (!l.isEmpty()) {
        // Add derived
        const TypeHierarchy hierarchy = l.takeFirst();
        QTC_ASSERT(hierarchy.symbol(), continue);
        Class *c = hierarchy.symbol()->asClass();
        QTC_ASSERT(c, continue);

        foreach (const TypeHierarchy &t, hierarchy.hierarchy()) {
            if (!l.contains(t))
                l << t;
        }

        // Check member functions
        for (int i = 0, total = c->memberCount(); i < total; ++i) {
            Symbol *candidate = c->memberAt(i);
            const Name *candidateName = candidate->name();
            Function *candidateFunc = candidate->type()->asFunctionType();
            if (!candidateName || !candidateFunc)
                continue;
            if (candidateName->match(referenceName)
                    && candidateFunc->isSignatureEqualTo(function)) {
                result << candidateFunc;
            }
        }
    }

    return result;
}
Exemplo n.º 22
0
bool CheckExpression::visit(QtMethodAST *ast)
{
    const Name *name = 0;
    Scope dummy;
    FullySpecifiedType methTy = semantic()->check(ast->declarator, FullySpecifiedType(),
                                                  &dummy, &name);
    Function *fty = methTy->asFunctionType();
    if (! fty)
        translationUnit()->warning(ast->firstToken(), "expected a function declarator");
    else {
        for (unsigned i = 0; i < fty->argumentCount(); ++i) {
            Symbol *arg = fty->argumentAt(i);
            if (arg->name())
                translationUnit()->warning(arg->sourceLocation(),
                                           "argument should be anonymous");
        }
    }
    return false;
}
Exemplo n.º 23
0
void TypePrettyPrinter::applyPtrOperators(bool wantSpace)
{
    if (wantSpace && !_ptrOperators.isEmpty())
        space();

    for (int i = _ptrOperators.size() - 1; i != -1; --i) {
        const FullySpecifiedType op = _ptrOperators.at(i);

        if (op->isPointerType()) {
            _text += QLatin1Char('*');
            outCV(op);
        } else if (op->isReferenceType()) {
            _text += QLatin1Char('&');
        } else if (const PointerToMemberType *memPtrTy = op->asPointerToMemberType()) {
            space();
            _text += _overview->prettyName(memPtrTy->memberName());
            _text += QLatin1Char('*');
            outCV(op);
        }
    }
}
/*! Rewrite/format the given type and name. */
QString PointerDeclarationFormatter::rewriteDeclaration(FullySpecifiedType type, const Name *name)
    const
{
    CHECK_RV(type.isValid(), "Invalid type", QString());

    const char *identifier = 0;
    if (const Name *declarationName = name) {
        if (const Identifier *id = declarationName->identifier())
            identifier = id->chars();
    }

    return m_overview.prettyType(type, QLatin1String(identifier));
}
Exemplo n.º 25
0
bool CheckDeclaration::visit(ParameterDeclarationAST *ast)
{
    unsigned sourceLocation = locationOfDeclaratorId(ast->declarator);
    if (! sourceLocation) {
        if (ast->declarator)
            sourceLocation = ast->declarator->firstToken();
        else
            sourceLocation = ast->firstToken();
    }

    Name *argName = 0;
    FullySpecifiedType ty = semantic()->check(ast->type_specifier, _scope);
    FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(),
                                                 _scope, &argName);
    FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
    Argument *arg = control()->newArgument(sourceLocation, argName);
    ast->symbol = arg;
    if (ast->expression)
        arg->setInitializer(true);
    arg->setType(argTy);
    _scope->enterSymbol(arg);
    return false;
}
Exemplo n.º 26
0
bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
{
    FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope);
    FullySpecifiedType qualTy = ty.qualifiedType();
    Name *name = 0;
    FullySpecifiedType funTy = semantic()->check(ast->declarator, qualTy,
                                                 _scope, &name);
    if (! (funTy && funTy->isFunctionType())) {
        translationUnit()->error(ast->firstToken(),
                                 "expected a function prototype");
        return false;
    }

    Function *fun = funTy->asFunctionType();
    fun->setVirtual(ty.isVirtual());
    fun->setStartOffset(tokenAt(ast->firstToken()).offset);
    fun->setEndOffset(tokenAt(ast->lastToken()).offset);
    if (ast->declarator)
        fun->setSourceLocation(ast->declarator->firstToken());
    fun->setName(name);
    fun->setTemplateParameters(_templateParameters);
    fun->setVisibility(semantic()->currentVisibility());
    fun->setMethodKey(semantic()->currentMethodKey());

    const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
    const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;

    if (isQ_SIGNAL)
        fun->setMethodKey(Function::SignalMethod);
    else if (isQ_SLOT)
        fun->setMethodKey(Function::SlotMethod);

    checkFunctionArguments(fun);

    ast->symbol = fun;
    _scope->enterSymbol(fun);

    if (! semantic()->skipFunctionBodies()) {
        if (ast->ctor_initializer) {
            bool looksLikeCtor = false;
            if (ty.isValid() || ! fun->identity())
                looksLikeCtor = false;
            else if (fun->identity()->isNameId() || fun->identity()->isTemplateNameId())
                looksLikeCtor = true;

            if (! looksLikeCtor) {
                translationUnit()->error(ast->ctor_initializer->firstToken(),
                                         "only constructors take base initializers");
            }
            accept(ast->ctor_initializer);
        }

        const int previousVisibility = semantic()->switchVisibility(Symbol::Public);
        const int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod);

        semantic()->check(ast->function_body, fun->members());

        semantic()->switchMethodKey(previousMethodKey);
        semantic()->switchVisibility(previousVisibility);
    }

    return false;
}
Exemplo n.º 27
0
SymbolInfo::ElementType SymbolInfo::elementTypeFromSymbol( const CPlusPlus::Symbol *symbol )
{
	if (const Template *templ = symbol->asTemplate()) {
		if (Symbol *decl = templ->declaration())
			return elementTypeFromSymbol(decl);
	}

	FullySpecifiedType symbolType = symbol->type();
	if (symbol->isFunction() || (symbol->isDeclaration() && symbolType &&
		symbolType->isFunctionType()))
	{
		const CPlusPlus::Function *func = symbol->asFunction();
		if (!func)
			func = symbol->type()->asFunctionType();

		if (func->isSlot() ) {
			if (func->isPublic())
				return SymbolInfo::SlotPublic;
			else if (func->isProtected())
				return SymbolInfo::SlotProtected;
			else if (func->isPrivate())
				return SymbolInfo::SlotPrivate;
		} else if (func->isSignal()) {
			return SymbolInfo::Signal;
		} else if (symbol->isPublic()) {
			return SymbolInfo::FuncPublic;
		} else if (symbol->isProtected()) {
			return SymbolInfo::FuncProtected;
		} else if (symbol->isPrivate()) {
			return SymbolInfo::FuncPrivate;
		}
	} else if (symbol->enclosingScope() && symbol->enclosingScope()->isEnum()) {
		return SymbolInfo::Enumerator;
	} else if (symbol->isDeclaration() || symbol->isArgument()) {
		if (symbol->isPublic())
			return SymbolInfo::VarPublic;
		else if (symbol->isProtected())
			return SymbolInfo::VarProtected;
		else if (symbol->isPrivate())
			return SymbolInfo::VarPrivate;
	} else if (symbol->isEnum()) {
		return SymbolInfo::Enum;
	} else if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
		return SymbolInfo::Class;
	} else if (symbol->isObjCClass() || symbol->isObjCForwardClassDeclaration()) {
		return SymbolInfo::Class;
	} else if (symbol->isObjCProtocol() || symbol->isObjCForwardProtocolDeclaration()) {
		return SymbolInfo::Class;
	} else if (symbol->isObjCMethod()) {
		return SymbolInfo::FuncPublic;
	} else if (symbol->isNamespace()) {
		return SymbolInfo::Namespace;
	} else if (symbol->isTypenameArgument()) {
		return SymbolInfo::Class;
	} else if (symbol->isUsingNamespaceDirective() ||
		symbol->isUsingDeclaration()) {
			// TODO: Might be nice to have a different icons for these things
			return SymbolInfo::Namespace;
	} else if (symbol->isBlock()){
		return SymbolInfo::Block;
	}

	return SymbolInfo::Unknown;
}
Exemplo n.º 28
0
bool CheckDeclaration::visit(SimpleDeclarationAST *ast)
{
    FullySpecifiedType ty = semantic()->check(ast->decl_specifier_seq, _scope);
    FullySpecifiedType qualTy = ty.qualifiedType();

    if (_templateParameters && ty) {
        if (Class *klass = ty->asClassType()) {
            klass->setTemplateParameters(_templateParameters);
        }
    }

    if (! ast->declarators && ast->decl_specifier_seq && ! ast->decl_specifier_seq->next) {
        if (ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_seq->asElaboratedTypeSpecifier()) {

            unsigned sourceLocation = elab_type_spec->firstToken();

            if (elab_type_spec->name)
                sourceLocation = elab_type_spec->name->firstToken();

            Name *name = semantic()->check(elab_type_spec->name, _scope);
            ForwardClassDeclaration *symbol =
                    control()->newForwardClassDeclaration(sourceLocation, name);

            if (_templateParameters) {
                symbol->setTemplateParameters(_templateParameters);
                _templateParameters = 0;
            }

            _scope->enterSymbol(symbol);
            return false;
        }
    }

    const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT;
    const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL;

    List<Declaration *> **decl_it = &ast->symbols;
    for (DeclaratorListAST *it = ast->declarators; it; it = it->next) {
        Name *name = 0;
        FullySpecifiedType declTy = semantic()->check(it->declarator, qualTy,
                                                      _scope, &name);

        unsigned location = locationOfDeclaratorId(it->declarator);
        if (! location) {
            if (it->declarator)
                location = it->declarator->firstToken();
            else
                location = ast->firstToken();
        }

        Function *fun = 0;
        if (declTy && 0 != (fun = declTy->asFunctionType())) {
            fun->setSourceLocation(location);
            fun->setScope(_scope);
            fun->setName(name);
            fun->setMethodKey(semantic()->currentMethodKey());
            fun->setVirtual(ty.isVirtual());
            if (isQ_SIGNAL)
                fun->setMethodKey(Function::SignalMethod);
            else if (isQ_SLOT)
                fun->setMethodKey(Function::SlotMethod);
            fun->setVisibility(semantic()->currentVisibility());
        } else if (semantic()->currentMethodKey() != Function::NormalMethod) {
            translationUnit()->warning(ast->firstToken(),
                                       "expected a function declaration");
        }

        Declaration *symbol = control()->newDeclaration(location, name);
        symbol->setStartOffset(tokenAt(ast->firstToken()).offset);
        symbol->setEndOffset(tokenAt(ast->lastToken()).offset);

        symbol->setType(control()->integerType(IntegerType::Int));
        symbol->setType(declTy);

        if (_templateParameters && it == ast->declarators && ty && ! ty->isClassType())
            symbol->setTemplateParameters(_templateParameters);

        symbol->setVisibility(semantic()->currentVisibility());

        if (ty.isFriend())
            symbol->setStorage(Symbol::Friend);
        else if (ty.isRegister())
            symbol->setStorage(Symbol::Register);
        else if (ty.isStatic())
            symbol->setStorage(Symbol::Static);
        else if (ty.isExtern())
            symbol->setStorage(Symbol::Extern);
        else if (ty.isMutable())
            symbol->setStorage(Symbol::Mutable);
        else if (ty.isTypedef())
            symbol->setStorage(Symbol::Typedef);

        if (it->declarator && it->declarator->initializer) {
            FullySpecifiedType initTy = semantic()->check(it->declarator->initializer, _scope);
        }

        *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>();
        (*decl_it)->value = symbol;
        decl_it = &(*decl_it)->next;

        _scope->enterSymbol(symbol);
    }
    return false;
}
/*!
    Performs some further checks and rewrites the type and name of \a symbol
    into the substitution range in the file specified by \a tokenRange.
 */
void PointerDeclarationFormatter::checkAndRewrite(DeclaratorAST *declarator,
                                                  Symbol *symbol,
                                                  TokenRange tokenRange,
                                                  unsigned charactersToRemove)
{
    CHECK_R(tokenRange.end > 0, "TokenRange invalid1");
    CHECK_R(tokenRange.start < tokenRange.end, "TokenRange invalid2");
    CHECK_R(symbol, "No symbol");

    // Check for expanded tokens
    for (unsigned token = tokenRange.start; token <= tokenRange.end; ++token)
        CHECK_R(!tokenAt(token).expanded(), "Token is expanded");

    Range range(m_cppRefactoringFile->startOf(tokenRange.start),
                m_cppRefactoringFile->endOf(tokenRange.end));

    CHECK_R(range.start >= 0 && range.end > 0, "ChangeRange invalid1");
    CHECK_R(range.start < range.end, "ChangeRange invalid2");

    // Check range with respect to cursor position / selection
    if (m_cursorHandling == RespectCursor) {
        const QTextCursor cursor = m_cppRefactoringFile->cursor();
        if (cursor.hasSelection()) {
            CHECK_R(cursor.selectionStart() <= range.start, "Change not in selection range");
            CHECK_R(range.end <= cursor.selectionEnd(), "Change not in selection range");
        } else {
            CHECK_R(range.start <= cursor.selectionStart(), "Cursor before activation range");
            CHECK_R(cursor.selectionEnd() <= range.end, "Cursor after activation range");
        }
    }

    FullySpecifiedType type = symbol->type();
    if (Function *function = type->asFunctionType())
        type = function->returnType();

    // Check if pointers or references are involved
    const QString originalDeclaration = m_cppRefactoringFile->textOf(range);
    CHECK_R(originalDeclaration.contains(QLatin1Char('&'))
            || originalDeclaration.contains(QLatin1Char('*')), "No pointer or references");

    // Does the rewritten declaration (part) differs from the original source (part)?
    QString rewrittenDeclaration;
    const Name *name = symbol->name();
    if (name) {
        if (name->isOperatorNameId()
                || (name->isQualifiedNameId()
                    && name->asQualifiedNameId()->name()->isOperatorNameId())) {
            const QString operatorText = m_cppRefactoringFile->textOf(declarator->core_declarator);
            m_overview.includeWhiteSpaceInOperatorName = operatorText.contains(QLatin1Char(' '));
        }
    }
    rewrittenDeclaration = m_overview.prettyType(type, name);
    rewrittenDeclaration.remove(0, charactersToRemove);

    CHECK_R(originalDeclaration != rewrittenDeclaration, "Rewritten is same as original");
    CHECK_R(rewrittenDeclaration.contains(QLatin1Char('&'))
            || rewrittenDeclaration.contains(QLatin1Char('*')),
            "No pointer or references in rewritten declaration");

    if (DEBUG_OUTPUT) {
        qDebug("==> Rewritten: \"%s\" --> \"%s\"", originalDeclaration.toLatin1().constData(),
               rewrittenDeclaration.toLatin1().constData());
    }

    // Creating the replacement in the changeset may fail due to operations
    // in the changeset that overlap with the current range.
    //
    // Consider this case:
    //
    //    void (*foo)(char * s) = 0;
    //
    // First visit(SimpleDeclarationAST *ast) will be called. It creates a
    // replacement that also includes the parameter.
    // Next visit(ParameterDeclarationAST *ast) is called with the
    // original source. It tries to create an replacement operation
    // at this position and fails due to overlapping ranges (the
    // simple declaration range includes parameter declaration range).
    ChangeSet change(m_changeSet);
    if (change.replace(range, rewrittenDeclaration))
        m_changeSet = change;
    else if (DEBUG_OUTPUT)
        qDebug() << "Replacement operation failed";
}
Exemplo n.º 30
0
Icons::IconType Icons::iconTypeForSymbol(const Symbol *symbol)
{
    if (const Template *templ = symbol->asTemplate()) {
        if (Symbol *decl = templ->declaration())
            return iconTypeForSymbol(decl);
    }

    FullySpecifiedType symbolType = symbol->type();
    if (symbol->isFunction() || (symbol->isDeclaration() && symbolType &&
                                 symbolType->isFunctionType()))
    {
        const Function *function = symbol->asFunction();
        if (!function)
            function = symbol->type()->asFunctionType();

        if (function->isSlot()) {
            if (function->isPublic())
                return SlotPublicIconType;
            else if (function->isProtected())
                return SlotProtectedIconType;
            else if (function->isPrivate())
                return SlotPrivateIconType;
        } else if (function->isSignal()) {
            return SignalIconType;
        } else if (symbol->isPublic()) {
            return FuncPublicIconType;
        } else if (symbol->isProtected()) {
            return FuncProtectedIconType;
        } else if (symbol->isPrivate()) {
            return FuncPrivateIconType;
        }
    } else if (symbol->enclosingScope() && symbol->enclosingScope()->isEnum()) {
        return EnumeratorIconType;
    } else if (symbol->isDeclaration() || symbol->isArgument()) {
        if (symbol->isPublic())
            return VarPublicIconType;
        else if (symbol->isProtected())
            return VarProtectedIconType;
        else if (symbol->isPrivate())
            return VarPrivateIconType;
    } else if (symbol->isEnum()) {
        return EnumIconType;
    } else if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
        return ClassIconType;
    } else if (symbol->isObjCClass() || symbol->isObjCForwardClassDeclaration()) {
        return ClassIconType;
    } else if (symbol->isObjCProtocol() || symbol->isObjCForwardProtocolDeclaration()) {
        return ClassIconType;
    } else if (symbol->isObjCMethod()) {
        return FuncPublicIconType;
    } else if (symbol->isNamespace()) {
        return NamespaceIconType;
    } else if (symbol->isTypenameArgument()) {
        return ClassIconType;
    } else if (symbol->isUsingNamespaceDirective() ||
               symbol->isUsingDeclaration()) {
        // TODO: Might be nice to have a different icons for these things
        return NamespaceIconType;
    }

    return UnknownIconType;
}