forked from qt-creator/qt-creator
Introduced token caching to prevent repetetive tokenizing.
Also removed TokenUnderCursor as it's functionality is in the token cache. Reviewed-by: ckamm
This commit is contained in:
@@ -50,7 +50,6 @@
|
||||
#include <cplusplus/Overview.h>
|
||||
#include <cplusplus/ExpressionUnderCursor.h>
|
||||
#include <cplusplus/BackwardsScanner.h>
|
||||
#include <cplusplus/TokenUnderCursor.h>
|
||||
#include <cplusplus/LookupContext.h>
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -65,7 +64,6 @@
|
||||
#include <utils/faketooltip.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtGui/QAction>
|
||||
@@ -454,7 +452,8 @@ QIcon CppCodeCompletion::iconForSymbol(Symbol *symbol) const
|
||||
/*
|
||||
Searches backwards for an access operator.
|
||||
*/
|
||||
static int startOfOperator(TextEditor::ITextEditable *editor,
|
||||
static int startOfOperator(TokenCache *tokenCache,
|
||||
TextEditor::ITextEditable *editor,
|
||||
int pos, unsigned *kind,
|
||||
bool wantFunctionCall)
|
||||
{
|
||||
@@ -547,15 +546,14 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
|
||||
}
|
||||
|
||||
if (completionKind == T_COMMA) {
|
||||
ExpressionUnderCursor expressionUnderCursor;
|
||||
ExpressionUnderCursor expressionUnderCursor(tokenCache);
|
||||
if (expressionUnderCursor.startOfFunctionCall(tc) == -1) {
|
||||
completionKind = T_EOF_SYMBOL;
|
||||
start = pos;
|
||||
}
|
||||
}
|
||||
|
||||
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
|
||||
const SimpleToken tk = tokenUnderCursor(tc);
|
||||
const SimpleToken tk = tokenCache->tokenUnderCursor(tc);
|
||||
|
||||
if (completionKind == T_DOXY_COMMENT && !(tk.is(T_DOXY_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))) {
|
||||
completionKind = T_EOF_SYMBOL;
|
||||
@@ -575,7 +573,7 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
|
||||
start = pos;
|
||||
}
|
||||
else if (completionKind == T_LPAREN) {
|
||||
const QList<SimpleToken> &tokens = tokenUnderCursor.tokens();
|
||||
const QList<SimpleToken> &tokens = tokenCache->tokensForBlock(tc.block());
|
||||
int i = 0;
|
||||
for (; i < tokens.size(); ++i) {
|
||||
const SimpleToken &token = tokens.at(i);
|
||||
@@ -597,11 +595,11 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
|
||||
// Check for include preprocessor directive
|
||||
else if (completionKind == T_STRING_LITERAL || completionKind == T_ANGLE_STRING_LITERAL || completionKind == T_SLASH) {
|
||||
bool include = false;
|
||||
const QList<SimpleToken> &tokens = tokenUnderCursor.tokens();
|
||||
const QList<SimpleToken> &tokens = tokenCache->tokensForBlock(tc.block());
|
||||
if (tokens.size() >= 3) {
|
||||
if (tokens.at(0).is(T_POUND) && tokens.at(1).is(T_IDENTIFIER) && (tokens.at(2).is(T_STRING_LITERAL) ||
|
||||
tokens.at(2).is(T_ANGLE_STRING_LITERAL))) {
|
||||
QStringRef directive = tokens.at(1).text();
|
||||
QString directive = tokenCache->text(tc.block(), 1);
|
||||
if (directive == QLatin1String("include") ||
|
||||
directive == QLatin1String("include_next") ||
|
||||
directive == QLatin1String("import")) {
|
||||
@@ -634,9 +632,10 @@ int CppCodeCompletion::startPosition() const
|
||||
bool CppCodeCompletion::triggersCompletion(TextEditor::ITextEditable *editor)
|
||||
{
|
||||
const int pos = editor->position();
|
||||
TokenCache *tokenCache = m_manager->tokenCache(editor);
|
||||
unsigned token = T_EOF_SYMBOL;
|
||||
|
||||
if (startOfOperator(editor, pos, &token, /*want function call=*/ true) != pos) {
|
||||
if (startOfOperator(tokenCache, editor, pos, &token, /*want function call=*/ true) != pos) {
|
||||
if (token == T_POUND) {
|
||||
if (TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget())) {
|
||||
QTextCursor tc(edit->document());
|
||||
@@ -684,7 +683,8 @@ int CppCodeCompletion::startCompletionHelper(TextEditor::ITextEditable *editor)
|
||||
while (editor->characterAt(endOfOperator - 1).isSpace())
|
||||
--endOfOperator;
|
||||
|
||||
int endOfExpression = startOfOperator(editor, endOfOperator,
|
||||
TokenCache *tokenCache = m_manager->tokenCache(editor);
|
||||
int endOfExpression = startOfOperator(tokenCache, editor, endOfOperator,
|
||||
&m_completionOperator,
|
||||
/*want function call =*/ true);
|
||||
|
||||
@@ -725,7 +725,7 @@ int CppCodeCompletion::startCompletionHelper(TextEditor::ITextEditable *editor)
|
||||
return m_startPosition;
|
||||
}
|
||||
|
||||
ExpressionUnderCursor expressionUnderCursor;
|
||||
ExpressionUnderCursor expressionUnderCursor(m_manager->tokenCache(editor));
|
||||
QTextCursor tc(edit->document());
|
||||
|
||||
if (m_completionOperator == T_COMMA) {
|
||||
@@ -800,14 +800,8 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
qDebug() << "scope:" << scope->owner()->fileName() << scope->owner()->line() << scope->owner()->column();
|
||||
|
||||
QList<LookupItem> results = typeOfExpression(expression, scope, TypeOfExpression::Preprocess);
|
||||
|
||||
if (debug)
|
||||
qDebug() << "got:" << results.size() << "results";
|
||||
|
||||
if (results.isEmpty()) {
|
||||
if (m_completionOperator == T_SIGNAL || m_completionOperator == T_SLOT) {
|
||||
if (! (expression.isEmpty() || expression == QLatin1String("this"))) {
|
||||
@@ -828,7 +822,8 @@ int CppCodeCompletion::startCompletionInternal(TextEditor::BaseTextEditor *edit,
|
||||
QTextCursor tc(edit->document());
|
||||
tc.setPosition(index);
|
||||
|
||||
ExpressionUnderCursor expressionUnderCursor;
|
||||
TokenCache *tokenCache = m_manager->tokenCache(edit->editableInterface());
|
||||
ExpressionUnderCursor expressionUnderCursor(tokenCache);
|
||||
const QString baseExpression = expressionUnderCursor(tc);
|
||||
|
||||
// Resolve the type of this expression
|
||||
@@ -1084,7 +1079,8 @@ bool CppCodeCompletion::completeConstructorOrFunction(const QList<LookupItem> &r
|
||||
|
||||
QTextCursor tc(edit->document());
|
||||
tc.setPosition(endOfExpression);
|
||||
BackwardsScanner bs(tc);
|
||||
TokenCache *tokenCache = m_manager->tokenCache(m_editor);
|
||||
BackwardsScanner bs(tokenCache, tc);
|
||||
const int startToken = bs.startToken();
|
||||
const int lineStartToken = bs.startOfLine(startToken);
|
||||
// make sure the required tokens are actually available
|
||||
@@ -1143,8 +1139,8 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults)
|
||||
{
|
||||
const LookupContext &context = typeOfExpression.context();
|
||||
|
||||
if (debug)
|
||||
qDebug() << Q_FUNC_INFO << __LINE__;
|
||||
// if (debug)
|
||||
// qDebug() << Q_FUNC_INFO << __LINE__;
|
||||
|
||||
if (baseResults.isEmpty())
|
||||
return false;
|
||||
@@ -1156,8 +1152,8 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults)
|
||||
if (ClassOrNamespace *binding = resolveExpression.baseExpression(baseResults,
|
||||
m_completionOperator,
|
||||
&replacedDotOperator)) {
|
||||
if (debug)
|
||||
qDebug() << "cool we got a binding for the base expression";
|
||||
// if (debug)
|
||||
// qDebug() << "cool we got a binding for the base expression";
|
||||
|
||||
if (replacedDotOperator && binding) {
|
||||
// Replace . with ->
|
||||
@@ -1173,10 +1169,10 @@ bool CppCodeCompletion::completeMember(const QList<LookupItem> &baseResults)
|
||||
return ! m_completions.isEmpty();
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
Overview oo;
|
||||
qDebug() << "hmm, got:" << oo(baseResults.first().type());
|
||||
}
|
||||
// if (debug) {
|
||||
// Overview oo;
|
||||
// qDebug() << "hmm, got:" << oo(baseResults.first().type());
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -962,6 +962,9 @@ bool CppModelManager::isCppEditor(Core::IEditor *editor) const
|
||||
return editor->context().contains(uid);
|
||||
}
|
||||
|
||||
TokenCache *CppModelManager::tokenCache(TextEditor::ITextEditor *editor) const
|
||||
{ return editorSupport(editor)->tokenCache(); }
|
||||
|
||||
void CppModelManager::emitDocumentUpdated(Document::Ptr doc)
|
||||
{ emit documentUpdated(doc); }
|
||||
|
||||
|
||||
@@ -108,6 +108,8 @@ public:
|
||||
CppEditorSupport *editorSupport(TextEditor::ITextEditor *editor) const
|
||||
{ return m_editorSupport.value(editor); }
|
||||
|
||||
virtual CPlusPlus::TokenCache *tokenCache(TextEditor::ITextEditor *editor) const;
|
||||
|
||||
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
void stopEditorSelectionsUpdate()
|
||||
|
||||
@@ -44,16 +44,25 @@ namespace Core {
|
||||
|
||||
namespace CPlusPlus {
|
||||
class LookupContext;
|
||||
class TokenCache;
|
||||
}
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class Project;
|
||||
}
|
||||
|
||||
namespace TextEditor {
|
||||
class ITextEditor;
|
||||
}
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
class AbstractEditorSupport;
|
||||
|
||||
namespace Internal {
|
||||
class CppEditorSupport;
|
||||
}
|
||||
|
||||
class CPPTOOLS_EXPORT CppModelManagerInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -136,6 +145,8 @@ public:
|
||||
|
||||
virtual void findMacroUsages(const CPlusPlus::Macro ¯o) = 0;
|
||||
|
||||
virtual CPlusPlus::TokenCache *tokenCache(TextEditor::ITextEditor *editor) const = 0;
|
||||
|
||||
Q_SIGNALS:
|
||||
void documentUpdated(CPlusPlus::Document::Ptr doc);
|
||||
|
||||
|
||||
@@ -67,8 +67,12 @@ void CppEditorSupport::setTextEditor(TextEditor::ITextEditor *textEditor)
|
||||
{
|
||||
_textEditor = textEditor;
|
||||
|
||||
if (! _textEditor)
|
||||
if (_textEditor) {
|
||||
if (TextEditor::BaseTextEditor *ed = qobject_cast<TextEditor::BaseTextEditor *>(_textEditor->widget()))
|
||||
_tokenCache.setDocument(ed->document());
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
connect(_textEditor, SIGNAL(contentsChanged()), this, SIGNAL(contentsChanged()));
|
||||
connect(this, SIGNAL(contentsChanged()), this, SLOT(updateDocument()));
|
||||
@@ -96,6 +100,11 @@ unsigned CppEditorSupport::editorRevision() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
TokenCache *CppEditorSupport::tokenCache()
|
||||
{
|
||||
return &_tokenCache;
|
||||
}
|
||||
|
||||
int CppEditorSupport::updateDocumentInterval() const
|
||||
{ return _updateDocumentInterval; }
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <QSharedPointer>
|
||||
#include <QTextCursor>
|
||||
#include <cplusplus/CppDocument.h>
|
||||
#include <cplusplus/TokenCache.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QTimer;
|
||||
@@ -72,6 +73,8 @@ public:
|
||||
QString contents();
|
||||
unsigned editorRevision() const;
|
||||
|
||||
CPlusPlus::TokenCache *tokenCache();
|
||||
|
||||
Q_SIGNALS:
|
||||
void contentsChanged();
|
||||
|
||||
@@ -89,6 +92,7 @@ private:
|
||||
QFuture<void> _documentParser;
|
||||
QString _cachedContents;
|
||||
unsigned _revision;
|
||||
CPlusPlus::TokenCache _tokenCache;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
Reference in New Issue
Block a user