2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2010-08-13 16:38:45 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2010-08-13 16:38:45 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2010-08-13 16:38:45 +02:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2010-08-13 16:38:45 +02:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2010-12-17 16:01:08 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2010-08-13 16:38:45 +02:00
|
|
|
|
|
|
|
|
#include "cppelementevaluator.h"
|
|
|
|
|
|
2015-03-05 08:22:48 +01:00
|
|
|
#include <cpptools/cppmodelmanager.h>
|
2011-07-08 09:56:02 +02:00
|
|
|
#include <cpptools/cpptoolsreuse.h>
|
2015-10-09 18:13:49 +02:00
|
|
|
#include <cpptools/symbolfinder.h>
|
2013-04-02 11:52:31 +02:00
|
|
|
#include <cpptools/typehierarchybuilder.h>
|
2013-03-27 18:54:03 +01:00
|
|
|
|
2015-02-26 13:22:35 +01:00
|
|
|
#include <texteditor/textdocument.h>
|
|
|
|
|
|
2010-08-13 16:38:45 +02:00
|
|
|
#include <cplusplus/ExpressionUnderCursor.h>
|
2013-03-27 18:54:03 +01:00
|
|
|
#include <cplusplus/Icons.h>
|
|
|
|
|
#include <cplusplus/TypeOfExpression.h>
|
2010-08-13 16:38:45 +02:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QDir>
|
|
|
|
|
#include <QSet>
|
|
|
|
|
#include <QQueue>
|
2010-08-13 16:38:45 +02:00
|
|
|
|
|
|
|
|
using namespace CPlusPlus;
|
|
|
|
|
|
2018-01-11 17:06:26 +01:00
|
|
|
namespace CppTools {
|
2014-08-27 10:01:27 +02:00
|
|
|
|
|
|
|
|
static QStringList stripName(const QString &name)
|
|
|
|
|
{
|
|
|
|
|
QStringList all;
|
|
|
|
|
all << name;
|
|
|
|
|
int colonColon = 0;
|
|
|
|
|
const int size = name.size();
|
|
|
|
|
while ((colonColon = name.indexOf(QLatin1String("::"), colonColon)) != -1) {
|
|
|
|
|
all << name.right(size - colonColon - 2);
|
|
|
|
|
colonColon += 2;
|
2010-10-01 11:15:28 +02:00
|
|
|
}
|
2014-08-27 10:01:27 +02:00
|
|
|
return all;
|
2010-08-13 16:38:45 +02:00
|
|
|
}
|
|
|
|
|
|
2018-01-19 09:36:46 +01:00
|
|
|
CppElement::CppElement() : helpCategory(TextEditor::HelpItem::Unknown)
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
CppElement::~CppElement()
|
|
|
|
|
{}
|
|
|
|
|
|
2018-03-08 19:25:04 +01:00
|
|
|
CppClass *CppElement::toCppClass()
|
|
|
|
|
{
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-19 09:36:46 +01:00
|
|
|
class Unknown : public CppElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit Unknown(const QString &type) : type(type)
|
|
|
|
|
{
|
|
|
|
|
tooltip = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
QString type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppInclude : public CppElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppInclude(const Document::Include &includeFile)
|
|
|
|
|
: path(QDir::toNativeSeparators(includeFile.resolvedFileName()))
|
|
|
|
|
, fileName(Utils::FileName::fromString(includeFile.resolvedFileName()).fileName())
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Brief;
|
|
|
|
|
helpIdCandidates = QStringList(fileName);
|
|
|
|
|
helpMark = fileName;
|
|
|
|
|
link = Utils::Link(path);
|
|
|
|
|
tooltip = path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
QString path;
|
|
|
|
|
QString fileName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppMacro : public CppElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppMacro(const Macro ¯o)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Macro;
|
|
|
|
|
const QString macroName = QString::fromUtf8(macro.name(), macro.name().size());
|
|
|
|
|
helpIdCandidates = QStringList(macroName);
|
|
|
|
|
helpMark = macroName;
|
|
|
|
|
link = Utils::Link(macro.fileName(), macro.line());
|
|
|
|
|
tooltip = macro.toStringWithLineBreaks();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// CppDeclarableElement
|
|
|
|
|
CppDeclarableElement::CppDeclarableElement(Symbol *declaration)
|
|
|
|
|
: CppElement()
|
|
|
|
|
, declaration(declaration)
|
|
|
|
|
, icon(Icons::iconForSymbol(declaration))
|
|
|
|
|
{
|
|
|
|
|
Overview overview;
|
|
|
|
|
overview.showArgumentNames = true;
|
|
|
|
|
overview.showReturnTypes = true;
|
|
|
|
|
name = overview.prettyName(declaration->name());
|
|
|
|
|
if (declaration->enclosingScope()->isClass() ||
|
|
|
|
|
declaration->enclosingScope()->isNamespace() ||
|
|
|
|
|
declaration->enclosingScope()->isEnum()) {
|
|
|
|
|
qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration));
|
|
|
|
|
helpIdCandidates = stripName(qualifiedName);
|
|
|
|
|
} else {
|
|
|
|
|
qualifiedName = name;
|
|
|
|
|
helpIdCandidates.append(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tooltip = overview.prettyType(declaration->type(), qualifiedName);
|
2018-02-02 12:52:07 +01:00
|
|
|
link = declaration->toLink();
|
2018-01-19 09:36:46 +01:00
|
|
|
helpMark = name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class CppNamespace : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppNamespace(Symbol *declaration)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::ClassOrNamespace;
|
|
|
|
|
tooltip = qualifiedName;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CppClass::CppClass(Symbol *declaration) : CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::ClassOrNamespace;
|
|
|
|
|
tooltip = qualifiedName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CppClass::operator==(const CppClass &other)
|
|
|
|
|
{
|
|
|
|
|
return this->declaration == other.declaration;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-08 19:25:04 +01:00
|
|
|
CppClass *CppClass::toCppClass()
|
|
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-19 09:36:46 +01:00
|
|
|
void CppClass::lookupBases(Symbol *declaration, const LookupContext &context)
|
|
|
|
|
{
|
|
|
|
|
typedef QPair<ClassOrNamespace *, CppClass *> Data;
|
|
|
|
|
|
|
|
|
|
if (ClassOrNamespace *clazz = context.lookupType(declaration)) {
|
|
|
|
|
QSet<ClassOrNamespace *> visited;
|
|
|
|
|
|
|
|
|
|
QQueue<Data> q;
|
|
|
|
|
q.enqueue(qMakePair(clazz, this));
|
|
|
|
|
while (!q.isEmpty()) {
|
|
|
|
|
Data current = q.dequeue();
|
|
|
|
|
clazz = current.first;
|
|
|
|
|
visited.insert(clazz);
|
|
|
|
|
const QList<ClassOrNamespace *> &bases = clazz->usings();
|
|
|
|
|
foreach (ClassOrNamespace *baseClass, bases) {
|
|
|
|
|
const QList<Symbol *> &symbols = baseClass->symbols();
|
|
|
|
|
foreach (Symbol *symbol, symbols) {
|
|
|
|
|
if (symbol->isClass() && (
|
|
|
|
|
clazz = context.lookupType(symbol)) &&
|
|
|
|
|
!visited.contains(clazz)) {
|
|
|
|
|
CppClass baseCppClass(symbol);
|
|
|
|
|
CppClass *cppClass = current.second;
|
|
|
|
|
cppClass->bases.append(baseCppClass);
|
|
|
|
|
q.enqueue(qMakePair(clazz, &cppClass->bases.last()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CppClass::lookupDerived(Symbol *declaration, const Snapshot &snapshot)
|
|
|
|
|
{
|
|
|
|
|
typedef QPair<CppClass *, CppTools::TypeHierarchy> Data;
|
|
|
|
|
|
|
|
|
|
CppTools::TypeHierarchyBuilder builder(declaration, snapshot);
|
|
|
|
|
const CppTools::TypeHierarchy &completeHierarchy = builder.buildDerivedTypeHierarchy();
|
|
|
|
|
|
|
|
|
|
QQueue<Data> q;
|
|
|
|
|
q.enqueue(qMakePair(this, completeHierarchy));
|
|
|
|
|
while (!q.isEmpty()) {
|
|
|
|
|
const Data ¤t = q.dequeue();
|
|
|
|
|
CppClass *clazz = current.first;
|
|
|
|
|
const CppTools::TypeHierarchy &classHierarchy = current.second;
|
|
|
|
|
foreach (const CppTools::TypeHierarchy &derivedHierarchy, classHierarchy.hierarchy()) {
|
|
|
|
|
clazz->derived.append(CppClass(derivedHierarchy.symbol()));
|
|
|
|
|
q.enqueue(qMakePair(&clazz->derived.last(), derivedHierarchy));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class CppFunction : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppFunction(Symbol *declaration)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Function;
|
|
|
|
|
|
|
|
|
|
const FullySpecifiedType &type = declaration->type();
|
|
|
|
|
|
|
|
|
|
// Functions marks can be found either by the main overload or signature based
|
|
|
|
|
// (with no argument names and no return). Help ids have no signature at all.
|
|
|
|
|
Overview overview;
|
|
|
|
|
overview.showDefaultArguments = false;
|
|
|
|
|
helpMark = overview.prettyType(type, name);
|
|
|
|
|
|
|
|
|
|
overview.showFunctionSignatures = false;
|
|
|
|
|
helpIdCandidates.append(overview.prettyName(declaration->name()));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppEnum : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppEnum(Enum *declaration)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Enum;
|
|
|
|
|
tooltip = qualifiedName;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppTypedef : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppTypedef(Symbol *declaration)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Typedef;
|
|
|
|
|
tooltip = Overview().prettyType(declaration->type(), qualifiedName);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppVariable : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppVariable(Symbol *declaration, const LookupContext &context, Scope *scope)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
const FullySpecifiedType &type = declaration->type();
|
|
|
|
|
|
|
|
|
|
const Name *typeName = 0;
|
|
|
|
|
if (type->isNamedType()) {
|
|
|
|
|
typeName = type->asNamedType()->name();
|
|
|
|
|
} else if (type->isPointerType() || type->isReferenceType()) {
|
|
|
|
|
FullySpecifiedType associatedType;
|
|
|
|
|
if (type->isPointerType())
|
|
|
|
|
associatedType = type->asPointerType()->elementType();
|
|
|
|
|
else
|
|
|
|
|
associatedType = type->asReferenceType()->elementType();
|
|
|
|
|
if (associatedType->isNamedType())
|
|
|
|
|
typeName = associatedType->asNamedType()->name();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeName) {
|
|
|
|
|
if (ClassOrNamespace *clazz = context.lookupType(typeName, scope)) {
|
|
|
|
|
if (!clazz->symbols().isEmpty()) {
|
|
|
|
|
Overview overview;
|
|
|
|
|
Symbol *symbol = clazz->symbols().at(0);
|
|
|
|
|
const QString &name = overview.prettyName(
|
|
|
|
|
LookupContext::fullyQualifiedName(symbol));
|
|
|
|
|
if (!name.isEmpty()) {
|
|
|
|
|
tooltip = name;
|
|
|
|
|
helpCategory = TextEditor::HelpItem::ClassOrNamespace;
|
|
|
|
|
const QStringList &allNames = stripName(name);
|
|
|
|
|
if (!allNames.isEmpty()) {
|
|
|
|
|
helpMark = allNames.last();
|
|
|
|
|
helpIdCandidates = allNames;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class CppEnumerator : public CppDeclarableElement
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
explicit CppEnumerator(EnumeratorDeclaration *declaration)
|
|
|
|
|
: CppDeclarableElement(declaration)
|
|
|
|
|
{
|
|
|
|
|
helpCategory = TextEditor::HelpItem::Enum;
|
|
|
|
|
|
|
|
|
|
Overview overview;
|
|
|
|
|
|
|
|
|
|
Symbol *enumSymbol = declaration->enclosingScope();
|
|
|
|
|
const QString enumName = overview.prettyName(LookupContext::fullyQualifiedName(enumSymbol));
|
|
|
|
|
const QString enumeratorName = overview.prettyName(declaration->name());
|
|
|
|
|
QString enumeratorValue;
|
|
|
|
|
if (const StringLiteral *value = declaration->constantValue())
|
|
|
|
|
enumeratorValue = QString::fromUtf8(value->chars(), value->size());
|
|
|
|
|
|
|
|
|
|
helpMark = overview.prettyName(enumSymbol->name());
|
|
|
|
|
|
|
|
|
|
tooltip = enumeratorName;
|
|
|
|
|
if (!enumName.isEmpty())
|
|
|
|
|
tooltip.prepend(enumName + QLatin1Char(' '));
|
|
|
|
|
if (!enumeratorValue.isEmpty())
|
|
|
|
|
tooltip.append(QLatin1String(" = ") + enumeratorValue);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-09-26 11:37:54 +02:00
|
|
|
CppElementEvaluator::CppElementEvaluator(TextEditor::TextEditorWidget *editor) :
|
2010-08-13 16:38:45 +02:00
|
|
|
m_editor(editor),
|
2014-09-15 00:12:27 +02:00
|
|
|
m_modelManager(CppTools::CppModelManager::instance()),
|
2010-08-13 16:38:45 +02:00
|
|
|
m_tc(editor->textCursor()),
|
2011-07-08 09:56:02 +02:00
|
|
|
m_lookupBaseClasses(false),
|
|
|
|
|
m_lookupDerivedClasses(false)
|
2010-08-13 16:38:45 +02:00
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
void CppElementEvaluator::setTextCursor(const QTextCursor &tc)
|
|
|
|
|
{ m_tc = tc; }
|
|
|
|
|
|
|
|
|
|
void CppElementEvaluator::setLookupBaseClasses(const bool lookup)
|
|
|
|
|
{ m_lookupBaseClasses = lookup; }
|
|
|
|
|
|
2011-07-08 09:56:02 +02:00
|
|
|
void CppElementEvaluator::setLookupDerivedClasses(const bool lookup)
|
|
|
|
|
{ m_lookupDerivedClasses = lookup; }
|
|
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
// @todo: Consider refactoring code from CppEditor::findLinkAt into here.
|
2011-01-17 16:29:57 +01:00
|
|
|
void CppElementEvaluator::execute()
|
2010-08-13 16:38:45 +02:00
|
|
|
{
|
2011-01-17 16:29:57 +01:00
|
|
|
clear();
|
|
|
|
|
|
2010-08-13 16:38:45 +02:00
|
|
|
if (!m_modelManager)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const Snapshot &snapshot = m_modelManager->snapshot();
|
2015-02-01 19:19:32 +02:00
|
|
|
Document::Ptr doc = snapshot.document(m_editor->textDocument()->filePath());
|
2010-08-13 16:38:45 +02:00
|
|
|
if (!doc)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int line = 0;
|
|
|
|
|
int column = 0;
|
|
|
|
|
const int pos = m_tc.position();
|
|
|
|
|
m_editor->convertPosition(pos, &line, &column);
|
|
|
|
|
|
2011-08-24 12:01:50 +02:00
|
|
|
checkDiagnosticMessage(pos);
|
2010-08-13 16:38:45 +02:00
|
|
|
|
2011-01-17 16:29:57 +01:00
|
|
|
if (!matchIncludeFile(doc, line) && !matchMacroInUse(doc, pos)) {
|
2011-07-08 09:56:02 +02:00
|
|
|
CppTools::moveCursorToEndOfIdentifier(&m_tc);
|
2010-08-13 16:38:45 +02:00
|
|
|
|
2011-01-17 16:29:57 +01:00
|
|
|
// Fetch the expression's code
|
2015-02-26 09:14:38 +02:00
|
|
|
ExpressionUnderCursor expressionUnderCursor(doc->languageFeatures());
|
2011-01-17 16:29:57 +01:00
|
|
|
const QString &expression = expressionUnderCursor(m_tc);
|
2018-11-02 14:17:12 +01:00
|
|
|
Scope *scope = doc->scopeAt(line, column - 1);
|
2010-08-13 16:38:45 +02:00
|
|
|
|
2011-01-17 16:29:57 +01:00
|
|
|
TypeOfExpression typeOfExpression;
|
|
|
|
|
typeOfExpression.init(doc, snapshot);
|
2013-01-19 13:17:34 +01:00
|
|
|
// make possible to instantiate templates
|
|
|
|
|
typeOfExpression.setExpandTemplates(true);
|
2012-01-12 17:35:37 +01:00
|
|
|
const QList<LookupItem> &lookupItems = typeOfExpression(expression.toUtf8(), scope);
|
2011-01-17 16:29:57 +01:00
|
|
|
if (lookupItems.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
const LookupItem &lookupItem = lookupItems.first(); // ### TODO: select best candidate.
|
2013-08-18 21:47:14 +02:00
|
|
|
handleLookupItemMatch(snapshot, lookupItem, typeOfExpression.context(), scope);
|
2010-08-13 16:38:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-08-24 12:01:50 +02:00
|
|
|
void CppElementEvaluator::checkDiagnosticMessage(int pos)
|
2010-08-13 16:38:45 +02:00
|
|
|
{
|
2011-08-24 12:01:50 +02:00
|
|
|
foreach (const QTextEdit::ExtraSelection &sel,
|
2014-09-26 11:37:54 +02:00
|
|
|
m_editor->extraSelections(TextEditor::TextEditorWidget::CodeWarningsSelection)) {
|
2011-08-24 12:01:50 +02:00
|
|
|
if (pos >= sel.cursor.selectionStart() && pos <= sel.cursor.selectionEnd()) {
|
|
|
|
|
m_diagnosis = sel.format.toolTip();
|
2011-01-17 16:29:57 +01:00
|
|
|
break;
|
2010-08-13 16:38:45 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-04 17:01:07 +02:00
|
|
|
bool CppElementEvaluator::matchIncludeFile(const Document::Ptr &document, unsigned line)
|
2010-08-13 16:38:45 +02:00
|
|
|
{
|
2013-07-25 11:21:31 +02:00
|
|
|
foreach (const Document::Include &includeFile, document->resolvedIncludes()) {
|
2010-08-13 16:38:45 +02:00
|
|
|
if (includeFile.line() == line) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppInclude(includeFile));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-04 17:01:07 +02:00
|
|
|
bool CppElementEvaluator::matchMacroInUse(const Document::Ptr &document, unsigned pos)
|
2010-08-13 16:38:45 +02:00
|
|
|
{
|
|
|
|
|
foreach (const Document::MacroUse &use, document->macroUses()) {
|
2014-05-09 10:04:13 -04:00
|
|
|
if (use.containsUtf16charOffset(pos)) {
|
|
|
|
|
const unsigned begin = use.utf16charsBegin();
|
|
|
|
|
if (pos < begin + use.macro().nameToQString().size()) {
|
2010-08-13 16:38:45 +02:00
|
|
|
m_element = QSharedPointer<CppElement>(new CppMacro(use.macro()));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CppElementEvaluator::handleLookupItemMatch(const Snapshot &snapshot,
|
|
|
|
|
const LookupItem &lookupItem,
|
2013-08-18 21:47:14 +02:00
|
|
|
const LookupContext &context,
|
|
|
|
|
const Scope *scope)
|
2010-08-13 16:38:45 +02:00
|
|
|
{
|
|
|
|
|
Symbol *declaration = lookupItem.declaration();
|
|
|
|
|
if (!declaration) {
|
|
|
|
|
const QString &type = Overview().prettyType(lookupItem.type(), QString());
|
2013-08-18 21:47:14 +02:00
|
|
|
// special case for bug QTCREATORBUG-4780
|
|
|
|
|
if (scope && scope->isFunction()
|
2014-05-15 12:00:13 -04:00
|
|
|
&& lookupItem.type().match(scope->asFunction()->returnType())) {
|
2013-08-18 21:47:14 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2010-08-13 16:38:45 +02:00
|
|
|
m_element = QSharedPointer<CppElement>(new Unknown(type));
|
|
|
|
|
} else {
|
|
|
|
|
const FullySpecifiedType &type = declaration->type();
|
|
|
|
|
if (declaration->isNamespace()) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppNamespace(declaration));
|
2011-07-08 09:56:02 +02:00
|
|
|
} else if (declaration->isClass()
|
|
|
|
|
|| declaration->isForwardClassDeclaration()
|
|
|
|
|
|| (declaration->isTemplate() && declaration->asTemplate()->declaration()
|
|
|
|
|
&& (declaration->asTemplate()->declaration()->isClass()
|
|
|
|
|
|| declaration->asTemplate()->declaration()->isForwardClassDeclaration()))) {
|
2013-11-19 18:12:20 +01:00
|
|
|
LookupContext contextToUse = context;
|
2015-10-09 18:13:49 +02:00
|
|
|
if (declaration->isForwardClassDeclaration()) {
|
|
|
|
|
const auto symbolFinder = m_modelManager->symbolFinder();
|
|
|
|
|
Symbol *classDeclaration = symbolFinder->findMatchingClassDeclaration(declaration,
|
|
|
|
|
snapshot);
|
|
|
|
|
if (classDeclaration) {
|
2010-08-13 16:38:45 +02:00
|
|
|
declaration = classDeclaration;
|
2013-11-19 18:12:20 +01:00
|
|
|
const QString fileName = QString::fromUtf8(declaration->fileName(),
|
|
|
|
|
declaration->fileNameLength());
|
|
|
|
|
const Document::Ptr declarationDocument = snapshot.document(fileName);
|
|
|
|
|
if (declarationDocument != context.thisDocument())
|
|
|
|
|
contextToUse = LookupContext(declarationDocument, snapshot);
|
2012-01-20 14:43:21 +01:00
|
|
|
}
|
2015-10-09 18:13:49 +02:00
|
|
|
}
|
2013-11-19 18:12:20 +01:00
|
|
|
|
2010-08-13 16:38:45 +02:00
|
|
|
CppClass *cppClass = new CppClass(declaration);
|
|
|
|
|
if (m_lookupBaseClasses)
|
2013-11-19 18:12:20 +01:00
|
|
|
cppClass->lookupBases(declaration, contextToUse);
|
2011-07-08 09:56:02 +02:00
|
|
|
if (m_lookupDerivedClasses)
|
|
|
|
|
cppClass->lookupDerived(declaration, snapshot);
|
2010-08-13 16:38:45 +02:00
|
|
|
m_element = QSharedPointer<CppElement>(cppClass);
|
2011-06-09 09:30:32 +02:00
|
|
|
} else if (Enum *enumDecl = declaration->asEnum()) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppEnum(enumDecl));
|
|
|
|
|
} else if (EnumeratorDeclaration *enumerator = dynamic_cast<EnumeratorDeclaration *>(declaration)) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppEnumerator(enumerator));
|
2010-08-13 16:38:45 +02:00
|
|
|
} else if (declaration->isTypedef()) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppTypedef(declaration));
|
2011-07-08 09:56:02 +02:00
|
|
|
} else if (declaration->isFunction()
|
|
|
|
|
|| (type.isValid() && type->isFunctionType())
|
|
|
|
|
|| declaration->isTemplate()) {
|
2010-08-13 16:38:45 +02:00
|
|
|
m_element = QSharedPointer<CppElement>(new CppFunction(declaration));
|
|
|
|
|
} else if (declaration->isDeclaration() && type.isValid()) {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(
|
|
|
|
|
new CppVariable(declaration, context, lookupItem.scope()));
|
|
|
|
|
} else {
|
|
|
|
|
m_element = QSharedPointer<CppElement>(new CppDeclarableElement(declaration));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-01-17 16:29:57 +01:00
|
|
|
bool CppElementEvaluator::identifiedCppElement() const
|
|
|
|
|
{
|
|
|
|
|
return !m_element.isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QSharedPointer<CppElement> &CppElementEvaluator::cppElement() const
|
|
|
|
|
{
|
|
|
|
|
return m_element;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CppElementEvaluator::hasDiagnosis() const
|
|
|
|
|
{
|
|
|
|
|
return !m_diagnosis.isEmpty();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString &CppElementEvaluator::diagnosis() const
|
|
|
|
|
{
|
|
|
|
|
return m_diagnosis;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
void CppElementEvaluator::clear()
|
2011-01-17 16:29:57 +01:00
|
|
|
{
|
|
|
|
|
m_element.clear();
|
|
|
|
|
m_diagnosis.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-11 17:06:26 +01:00
|
|
|
} // namespace CppTools
|