diff --git a/src/plugins/cppeditor/cppcanonicalsymbol.cpp b/src/plugins/cppeditor/cppcanonicalsymbol.cpp new file mode 100644 index 00000000000..7bdf1bcac99 --- /dev/null +++ b/src/plugins/cppeditor/cppcanonicalsymbol.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** 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 +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "cppcanonicalsymbol.h" + +#include "cppeditor.h" + +#include +#include + +#include + +using namespace CPlusPlus; + +namespace CppEditor { +namespace Internal { + +CanonicalSymbol::CanonicalSymbol(CPPEditorWidget *editor, + const Document::Ptr &document, + const Snapshot &snapshot) + : m_editorWidget(editor), + m_document(document), + m_snapshot(snapshot) +{ + m_typeOfExpression.init(document, snapshot); + m_typeOfExpression.setExpandTemplates(true); +} + +const LookupContext &CanonicalSymbol::context() const +{ + return m_typeOfExpression.context(); +} + +Scope *CanonicalSymbol::getScopeAndExpression(const QTextCursor &cursor, QString *code) +{ + if (!m_document) + return 0; + + QTextCursor tc = cursor; + int line, column; + m_editorWidget->convertPosition(tc.position(), &line, &column); + ++column; // 1-based line and 1-based column + + int pos = tc.position(); + QTextDocument *textDocument = m_editorWidget->document(); + if (!CppTools::isValidIdentifierChar(textDocument->characterAt(pos))) + if (!(pos > 0 && CppTools::isValidIdentifierChar(textDocument->characterAt(pos - 1)))) + return 0; + + while (CppTools::isValidIdentifierChar(textDocument->characterAt(pos))) + ++pos; + tc.setPosition(pos); + + ExpressionUnderCursor expressionUnderCursor; + *code = expressionUnderCursor(tc); + return m_document->scopeAt(line, column); +} + +Symbol *CanonicalSymbol::operator()(const QTextCursor &cursor) +{ + QString code; + + if (Scope *scope = getScopeAndExpression(cursor, &code)) + return operator()(scope, code); + + return 0; +} + +Symbol *CanonicalSymbol::operator()(Scope *scope, const QString &code) +{ + return canonicalSymbol(scope, code, m_typeOfExpression); +} + +Symbol *CanonicalSymbol::canonicalSymbol(Scope *scope, const QString &code, + TypeOfExpression &typeOfExpression) +{ + const QList results = + typeOfExpression(code.toUtf8(), scope, TypeOfExpression::Preprocess); + + for (int i = results.size() - 1; i != -1; --i) { + const LookupItem &r = results.at(i); + Symbol *decl = r.declaration(); + + if (!(decl && decl->enclosingScope())) + break; + + if (Class *classScope = r.declaration()->enclosingScope()->asClass()) { + const Identifier *declId = decl->identifier(); + const Identifier *classId = classScope->identifier(); + + if (classId && classId->match(declId)) + continue; // skip it, it's a ctor or a dtor. + + if (Function *funTy = r.declaration()->type()->asFunctionType()) { + if (funTy->isVirtual()) + return r.declaration(); + } + } + } + + for (int i = 0; i < results.size(); ++i) { + const LookupItem &r = results.at(i); + + if (r.declaration()) + return r.declaration(); + } + + return 0; +} + +} // namespace Internal +} // namespace CppEditor diff --git a/src/plugins/cppeditor/cppcanonicalsymbol.h b/src/plugins/cppeditor/cppcanonicalsymbol.h new file mode 100644 index 00000000000..2c41c8f8326 --- /dev/null +++ b/src/plugins/cppeditor/cppcanonicalsymbol.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** 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 +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CPPCANONICALSYMBOL_H +#define CPPCANONICALSYMBOL_H + +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QTextCursor) + +namespace CppEditor { +namespace Internal { + +class CPPEditorWidget; + +class CanonicalSymbol +{ +public: + CanonicalSymbol(CPPEditorWidget *editorWidget, + const CPlusPlus::Document::Ptr &document, + const CPlusPlus::Snapshot &snapshot); + + const CPlusPlus::LookupContext &context() const; + + CPlusPlus::Scope *getScopeAndExpression(const QTextCursor &cursor, QString *code); + + CPlusPlus::Symbol *operator()(const QTextCursor &cursor); + CPlusPlus::Symbol *operator()(CPlusPlus::Scope *scope, const QString &code); + +public: + static CPlusPlus::Symbol *canonicalSymbol(CPlusPlus::Scope *scope, + const QString &code, + CPlusPlus::TypeOfExpression &typeOfExpression); + +private: + CPPEditorWidget *m_editorWidget; + + CPlusPlus::Document::Ptr m_document; + CPlusPlus::Snapshot m_snapshot; + CPlusPlus::TypeOfExpression m_typeOfExpression; +}; + +} // namespace Internal +} // namespace CppEditor + +#endif // CPPCANONICALSYMBOL_H diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index c0dc21f2e15..6507f6d4bea 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -30,10 +30,11 @@ #include "cppeditor.h" #include "cppautocompleter.h" +#include "cppcanonicalsymbol.h" +#include "cppdocumentationcommenthelper.h" #include "cppeditorconstants.h" #include "cppeditoroutline.h" #include "cppeditorplugin.h" -#include "cppdocumentationcommenthelper.h" #include "cppfollowsymbolundercursor.h" #include "cpphighlighter.h" #include "cpplocalrenaming.h" @@ -92,109 +93,6 @@ using namespace CppEditor::Internal; namespace { -class CanonicalSymbol -{ -public: - CanonicalSymbol(CPPEditorWidget *editor, - const Document::Ptr &document, - const Snapshot &snapshot) - : m_editor(editor), - m_document(document), - m_snapshot(snapshot) - { - m_typeOfExpression.init(document, snapshot); - m_typeOfExpression.setExpandTemplates(true); - } - - const LookupContext &context() const - { - return m_typeOfExpression.context(); - } - - Scope *getScopeAndExpression(const QTextCursor &cursor, QString *code) - { - if (!m_document) - return 0; - - QTextCursor tc = cursor; - int line, column; - m_editor->convertPosition(tc.position(), &line, &column); - ++column; // 1-based line and 1-based column - - int pos = tc.position(); - QTextDocument *textDocument = m_editor->document(); - if (!isValidIdentifierChar(textDocument->characterAt(pos))) - if (!(pos > 0 && isValidIdentifierChar(textDocument->characterAt(pos - 1)))) - return 0; - - while (isValidIdentifierChar(textDocument->characterAt(pos))) - ++pos; - tc.setPosition(pos); - - ExpressionUnderCursor expressionUnderCursor; - *code = expressionUnderCursor(tc); - return m_document->scopeAt(line, column); - } - - Symbol *operator()(const QTextCursor &cursor) - { - QString code; - - if (Scope *scope = getScopeAndExpression(cursor, &code)) - return operator()(scope, code); - - return 0; - } - - Symbol *operator()(Scope *scope, const QString &code) - { - return canonicalSymbol(scope, code, m_typeOfExpression); - } - - static Symbol *canonicalSymbol(Scope *scope, const QString &code, - TypeOfExpression &typeOfExpression) - { - const QList results = - typeOfExpression(code.toUtf8(), scope, TypeOfExpression::Preprocess); - - for (int i = results.size() - 1; i != -1; --i) { - const LookupItem &r = results.at(i); - Symbol *decl = r.declaration(); - - if (!(decl && decl->enclosingScope())) - break; - - if (Class *classScope = r.declaration()->enclosingScope()->asClass()) { - const Identifier *declId = decl->identifier(); - const Identifier *classId = classScope->identifier(); - - if (classId && classId->match(declId)) - continue; // skip it, it's a ctor or a dtor. - - if (Function *funTy = r.declaration()->type()->asFunctionType()) { - if (funTy->isVirtual()) - return r.declaration(); - } - } - } - - for (int i = 0; i < results.size(); ++i) { - const LookupItem &r = results.at(i); - - if (r.declaration()) - return r.declaration(); - } - - return 0; - } - -private: - CPPEditorWidget *m_editor; - TypeOfExpression m_typeOfExpression; - Document::Ptr m_document; - Snapshot m_snapshot; -}; - QTimer *newSingleShotTimer(QObject *parent, int msecInterval) { QTimer *timer = new QTimer(parent); diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro index 440d4b67549..f193965cff7 100644 --- a/src/plugins/cppeditor/cppeditor.pro +++ b/src/plugins/cppeditor/cppeditor.pro @@ -3,6 +3,7 @@ include(../../qtcreatorplugin.pri) HEADERS += \ cppautocompleter.h \ + cppcanonicalsymbol.h \ cppclasswizard.h \ cppcodemodelinspectordialog.h \ cppdocumentationcommenthelper.h \ @@ -38,6 +39,7 @@ HEADERS += \ SOURCES += \ cppautocompleter.cpp \ + cppcanonicalsymbol.cpp \ cppclasswizard.cpp \ cppcodemodelinspectordialog.cpp \ cppdocumentationcommenthelper.cpp \ diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 3b6979900bc..73dd841d4f0 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -20,6 +20,7 @@ QtcPlugin { files: [ "cppautocompleter.cpp", "cppautocompleter.h", + "cppcanonicalsymbol.cpp", "cppcanonicalsymbol.h", "cppclasswizard.cpp", "cppclasswizard.h", "cppcodemodelinspectordialog.cpp", "cppcodemodelinspectordialog.h", "cppcodemodelinspectordialog.ui", "cppdocumentationcommenthelper.cpp", "cppdocumentationcommenthelper.h",