forked from qt-creator/qt-creator
CppEditor: Squash three copies of the "is in comment or string" check
Change-Id: Id6c4e35ae2d3b3031e5c95ea04f5b971bef58389 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#include <cppeditor/cppdoxygen.h>
|
#include <cppeditor/cppdoxygen.h>
|
||||||
#include <cppeditor/cppmodelmanager.h>
|
#include <cppeditor/cppmodelmanager.h>
|
||||||
|
#include <cppeditor/cpptoolsreuse.h>
|
||||||
#include <cppeditor/editordocumenthandle.h>
|
#include <cppeditor/editordocumenthandle.h>
|
||||||
|
|
||||||
#include <texteditor/codeassist/assistproposalitem.h>
|
#include <texteditor/codeassist/assistproposalitem.h>
|
||||||
@@ -44,10 +45,7 @@
|
|||||||
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
|
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
|
||||||
#include <cplusplus/BackwardsScanner.h>
|
|
||||||
#include <cplusplus/ExpressionUnderCursor.h>
|
|
||||||
#include <cplusplus/Icons.h>
|
#include <cplusplus/Icons.h>
|
||||||
#include <cplusplus/SimpleLexer.h>
|
|
||||||
|
|
||||||
#include <clangsupport/filecontainer.h>
|
#include <clangsupport/filecontainer.h>
|
||||||
|
|
||||||
@@ -431,37 +429,8 @@ bool ClangCompletionAssistProcessor::accepts() const
|
|||||||
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
|
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
|
||||||
const QChar firstCharacter = m_interface->characterAt(startOfName);
|
const QChar firstCharacter = m_interface->characterAt(startOfName);
|
||||||
if (firstCharacter.isLetter() || firstCharacter == QLatin1Char('_')) {
|
if (firstCharacter.isLetter() || firstCharacter == QLatin1Char('_')) {
|
||||||
// Finally check that we're not inside a comment or string (code copied from startOfOperator)
|
return !CppEditor::isInCommentOrString(m_interface.data(),
|
||||||
QTextCursor tc(m_interface->textDocument());
|
m_interface->languageFeatures());
|
||||||
tc.setPosition(pos);
|
|
||||||
|
|
||||||
SimpleLexer tokenize;
|
|
||||||
LanguageFeatures lf = tokenize.languageFeatures();
|
|
||||||
lf.qtMocRunEnabled = true;
|
|
||||||
lf.objCEnabled = true;
|
|
||||||
tokenize.setLanguageFeatures(lf);
|
|
||||||
tokenize.setSkipComments(false);
|
|
||||||
const Tokens &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block()));
|
|
||||||
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
|
||||||
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
|
||||||
|
|
||||||
if (!tk.isComment() && !tk.isLiteral()) {
|
|
||||||
return true;
|
|
||||||
} else if (tk.isLiteral()
|
|
||||||
&& tokens.size() == 3
|
|
||||||
&& tokens.at(0).kind() == T_POUND
|
|
||||||
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
|
||||||
const QString &line = tc.block().text();
|
|
||||||
const Token &idToken = tokens.at(1);
|
|
||||||
QStringView identifier = Utils::midView(line,
|
|
||||||
idToken.utf16charsBegin(),
|
|
||||||
idToken.utf16chars());
|
|
||||||
if (identifier == QLatin1String("include")
|
|
||||||
|| identifier == QLatin1String("include_next")
|
|
||||||
|| (m_interface->objcEnabled() && identifier == QLatin1String("import"))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -35,11 +35,9 @@
|
|||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
#include <coreplugin/find/searchresultitem.h>
|
#include <coreplugin/find/searchresultitem.h>
|
||||||
#include <coreplugin/find/searchresultwindow.h>
|
#include <coreplugin/find/searchresultwindow.h>
|
||||||
#include <cplusplus/BackwardsScanner.h>
|
|
||||||
#include <cplusplus/FindUsages.h>
|
#include <cplusplus/FindUsages.h>
|
||||||
#include <cplusplus/Icons.h>
|
#include <cplusplus/Icons.h>
|
||||||
#include <cplusplus/MatchingText.h>
|
#include <cplusplus/MatchingText.h>
|
||||||
#include <cplusplus/SimpleLexer.h>
|
|
||||||
#include <cppeditor/cppeditorconstants.h>
|
#include <cppeditor/cppeditorconstants.h>
|
||||||
#include <cppeditor/cppcodemodelsettings.h>
|
#include <cppeditor/cppcodemodelsettings.h>
|
||||||
#include <cppeditor/cppcompletionassistprocessor.h>
|
#include <cppeditor/cppcompletionassistprocessor.h>
|
||||||
@@ -98,13 +96,6 @@ static Q_LOGGING_CATEGORY(clangdLogHighlight, "qtc.clangcodemodel.clangd.highlig
|
|||||||
static Q_LOGGING_CATEGORY(clangdLogTiming, "qtc.clangcodemodel.clangd.timing", QtWarningMsg);
|
static Q_LOGGING_CATEGORY(clangdLogTiming, "qtc.clangcodemodel.clangd.timing", QtWarningMsg);
|
||||||
static QString indexingToken() { return "backgroundIndexProgress"; }
|
static QString indexingToken() { return "backgroundIndexProgress"; }
|
||||||
|
|
||||||
static QStringView subView(const QString &s, qsizetype start)
|
|
||||||
{
|
|
||||||
if (start < 0 || start > s.length())
|
|
||||||
return {};
|
|
||||||
return QStringView(s).mid(start);
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringView subViewLen(const QString &s, qsizetype start, qsizetype length)
|
static QStringView subViewLen(const QString &s, qsizetype start, qsizetype length)
|
||||||
{
|
{
|
||||||
if (start < 0 || length < 0 || start + length > s.length())
|
if (start < 0 || length < 0 || start + length > s.length())
|
||||||
@@ -2646,36 +2637,9 @@ bool ClangdClient::ClangdCompletionAssistProvider::isContinuationChar(const QCha
|
|||||||
bool ClangdClient::ClangdCompletionAssistProvider::isInCommentOrString(
|
bool ClangdClient::ClangdCompletionAssistProvider::isInCommentOrString(
|
||||||
const AssistInterface *interface) const
|
const AssistInterface *interface) const
|
||||||
{
|
{
|
||||||
QTextCursor tc(interface->textDocument());
|
LanguageFeatures features = LanguageFeatures::defaultFeatures();
|
||||||
tc.setPosition(interface->position());
|
features.objCEnabled = CppEditor::ProjectFile::isObjC(interface->filePath().toString());
|
||||||
|
return CppEditor::isInCommentOrString(interface, features);
|
||||||
SimpleLexer tokenize;
|
|
||||||
tokenize.setSkipComments(false);
|
|
||||||
const Tokens &tokens = tokenize(tc.block().text(),
|
|
||||||
BackwardsScanner::previousBlockState(tc.block()));
|
|
||||||
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
|
||||||
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
|
||||||
|
|
||||||
if (tk.isComment())
|
|
||||||
return true;
|
|
||||||
if (!tk.isLiteral())
|
|
||||||
return false;
|
|
||||||
if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
|
|
||||||
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
|
||||||
const QString &line = tc.block().text();
|
|
||||||
const Token &idToken = tokens.at(1);
|
|
||||||
QStringView identifier = idToken.utf16charsEnd() > line.size()
|
|
||||||
? subView(line, idToken.utf16charsBegin())
|
|
||||||
: subViewLen(line, idToken.utf16charsBegin(),
|
|
||||||
idToken.utf16chars());
|
|
||||||
if (identifier == QLatin1String("include")
|
|
||||||
|| identifier == QLatin1String("include_next")
|
|
||||||
|| (CppEditor::ProjectFile::isObjC(interface->filePath().toString())
|
|
||||||
&& identifier == QLatin1String("import"))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||||
|
@@ -858,38 +858,8 @@ bool InternalCppCompletionAssistProcessor::accepts() const
|
|||||||
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
|
if (pos - startOfName >= TextEditorSettings::completionSettings().m_characterThreshold) {
|
||||||
const QChar firstCharacter = m_interface->characterAt(startOfName);
|
const QChar firstCharacter = m_interface->characterAt(startOfName);
|
||||||
if (isValidFirstIdentifierChar(firstCharacter)) {
|
if (isValidFirstIdentifierChar(firstCharacter)) {
|
||||||
// Finally check that we're not inside a comment or string (code copied from startOfOperator)
|
return !isInCommentOrString(m_interface.data(),
|
||||||
QTextCursor tc(m_interface->textDocument());
|
m_interface->languageFeatures());
|
||||||
tc.setPosition(pos);
|
|
||||||
|
|
||||||
SimpleLexer tokenize;
|
|
||||||
tokenize.setLanguageFeatures(m_interface->languageFeatures());
|
|
||||||
tokenize.setSkipComments(false);
|
|
||||||
|
|
||||||
const Tokens &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block()));
|
|
||||||
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
|
||||||
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
|
||||||
|
|
||||||
if (!tk.isComment() && !tk.isLiteral()) {
|
|
||||||
return true;
|
|
||||||
} else if (tk.isLiteral()
|
|
||||||
&& tokens.size() == 3
|
|
||||||
&& tokens.at(0).kind() == T_POUND
|
|
||||||
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
|
||||||
const QString &line = tc.block().text();
|
|
||||||
const Token &idToken = tokens.at(1);
|
|
||||||
QStringView identifier = idToken.utf16charsEnd() > line.size()
|
|
||||||
? QStringView(line).mid(
|
|
||||||
idToken.utf16charsBegin())
|
|
||||||
: QStringView(line)
|
|
||||||
.mid(idToken.utf16charsBegin(),
|
|
||||||
idToken.utf16chars());
|
|
||||||
if (identifier == QLatin1String("include")
|
|
||||||
|| identifier == QLatin1String("include_next")
|
|
||||||
|| (m_interface->languageFeatures().objCEnabled && identifier == QLatin1String("import"))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,11 +39,15 @@
|
|||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include <texteditor/codeassist/assistinterface.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
|
|
||||||
#include <cplusplus/Overview.h>
|
#include <cplusplus/BackwardsScanner.h>
|
||||||
#include <cplusplus/LookupContext.h>
|
#include <cplusplus/LookupContext.h>
|
||||||
|
#include <cplusplus/Overview.h>
|
||||||
|
#include <cplusplus/SimpleLexer.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/porting.h>
|
||||||
#include <utils/textutils.h>
|
#include <utils/textutils.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
@@ -300,6 +304,40 @@ const Macro *findCanonicalMacro(const QTextCursor &cursor, Document::Ptr documen
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInCommentOrString(const TextEditor::AssistInterface *interface,
|
||||||
|
CPlusPlus::LanguageFeatures features)
|
||||||
|
{
|
||||||
|
QTextCursor tc(interface->textDocument());
|
||||||
|
tc.setPosition(interface->position());
|
||||||
|
|
||||||
|
SimpleLexer tokenize;
|
||||||
|
features.qtMocRunEnabled = true;
|
||||||
|
tokenize.setLanguageFeatures(features);
|
||||||
|
tokenize.setSkipComments(false);
|
||||||
|
const Tokens &tokens = tokenize(tc.block().text(),
|
||||||
|
BackwardsScanner::previousBlockState(tc.block()));
|
||||||
|
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1));
|
||||||
|
const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
|
||||||
|
|
||||||
|
if (tk.isComment())
|
||||||
|
return true;
|
||||||
|
if (!tk.isLiteral())
|
||||||
|
return false;
|
||||||
|
if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND
|
||||||
|
&& tokens.at(1).kind() == T_IDENTIFIER) {
|
||||||
|
const QString &line = tc.block().text();
|
||||||
|
const Token &idToken = tokens.at(1);
|
||||||
|
QStringView identifier = Utils::midView(line, idToken.utf16charsBegin(),
|
||||||
|
idToken.utf16chars());
|
||||||
|
if (identifier == QLatin1String("include")
|
||||||
|
|| identifier == QLatin1String("include_next")
|
||||||
|
|| (features.objCEnabled && identifier == QLatin1String("import"))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
CppCodeModelSettings *codeModelSettings()
|
CppCodeModelSettings *codeModelSettings()
|
||||||
{
|
{
|
||||||
return Internal::CppEditorPlugin::instance()->codeModelSettings();
|
return Internal::CppEditorPlugin::instance()->codeModelSettings();
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include <cplusplus/ASTVisitor.h>
|
#include <cplusplus/ASTVisitor.h>
|
||||||
#include <cplusplus/CppDocument.h>
|
#include <cplusplus/CppDocument.h>
|
||||||
|
#include <cplusplus/Token.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QChar;
|
class QChar;
|
||||||
@@ -48,6 +49,8 @@ class Symbol;
|
|||||||
class LookupContext;
|
class LookupContext;
|
||||||
} // namespace CPlusPlus
|
} // namespace CPlusPlus
|
||||||
|
|
||||||
|
namespace TextEditor { class AssistInterface; }
|
||||||
|
|
||||||
namespace CppEditor {
|
namespace CppEditor {
|
||||||
class CppRefactoringFile;
|
class CppRefactoringFile;
|
||||||
class ProjectInfo;
|
class ProjectInfo;
|
||||||
@@ -71,6 +74,9 @@ bool CPPEDITOR_EXPORT isOwnershipRAIIType(CPlusPlus::Symbol *symbol,
|
|||||||
const CPlusPlus::Macro CPPEDITOR_EXPORT *findCanonicalMacro(const QTextCursor &cursor,
|
const CPlusPlus::Macro CPPEDITOR_EXPORT *findCanonicalMacro(const QTextCursor &cursor,
|
||||||
CPlusPlus::Document::Ptr document);
|
CPlusPlus::Document::Ptr document);
|
||||||
|
|
||||||
|
bool CPPEDITOR_EXPORT isInCommentOrString(const TextEditor::AssistInterface *interface,
|
||||||
|
CPlusPlus::LanguageFeatures features);
|
||||||
|
|
||||||
enum class CacheUsage { ReadWrite, ReadOnly };
|
enum class CacheUsage { ReadWrite, ReadOnly };
|
||||||
|
|
||||||
QString CPPEDITOR_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = nullptr,
|
QString CPPEDITOR_EXPORT correspondingHeaderOrSource(const QString &fileName, bool *wasHeader = nullptr,
|
||||||
|
Reference in New Issue
Block a user