Commit fd00ec23 authored by Erik Verbruggen's avatar Erik Verbruggen

Added ObjC keyword highlighting in the semantic pass.

parent bb4b88c8
......@@ -58,6 +58,7 @@
#include <cplusplus/TokenCache.h>
#include <cpptools/cppmodelmanagerinterface.h>
#include <cpptools/cpptoolsconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
......@@ -603,6 +604,7 @@ CPPEditor::CPPEditor(QWidget *parent)
, m_inRename(false)
, m_inRenameChanged(false)
, m_firstRenameChange(false)
, m_objcEnabled(false)
{
m_initialized = false;
qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo");
......@@ -738,6 +740,20 @@ CppTools::CppModelManagerInterface *CPPEditor::modelManager() const
return m_modelManager;
}
void CPPEditor::setMimeType(const QString &mt)
{
BaseTextEditor::setMimeType(mt);
setObjCEnabled(mt == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE);
}
void CPPEditor::setObjCEnabled(bool onoff)
{
m_objcEnabled = onoff;
}
bool CPPEditor::isObjCEnabled() const
{ return m_objcEnabled; }
void CPPEditor::startRename()
{
m_inRenameChanged = false;
......@@ -1771,6 +1787,7 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
m_occurrencesUnusedFormat.setToolTip(tr("Unused variable"));
m_occurrenceRenameFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_OCCURRENCES_RENAME));
m_typeFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_TYPE));
m_keywordFormat = fs.toTextCharFormat(QLatin1String(TextEditor::Constants::C_KEYWORD));
// only set the background, we do not want to modify foreground properties set by the syntax highlighter or the link
m_occurrencesFormat.clearForeground();
......@@ -1911,6 +1928,36 @@ void CPPEditor::updateSemanticInfo(const SemanticInfo &semanticInfo)
}
setExtraSelections(TypeSelection, typeSelections);
// ### extract common parts from the previous loop and the next one
QList<QTextEdit::ExtraSelection> objcKeywords;
if (isObjCEnabled()) {
foreach (const SemanticInfo::Use &use, semanticInfo.objcKeywords) {
QTextCursor cursor(document());
if (currentLine != use.line) {
int delta = use.line - currentLine;
if (delta >= 0) {
while (delta--)
currentBlock = currentBlock.next();
} else {
currentBlock = document()->findBlockByNumber(use.line - 1);
}
currentLine = use.line;
}
cursor.setPosition(currentBlock.position() + use.column - 1);
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, use.length);
QTextEdit::ExtraSelection sel;
sel.cursor = cursor;
sel.format = m_keywordFormat;
objcKeywords.append(sel);
}
}
setExtraSelections(ObjCSelection, objcKeywords);
}
setExtraSelections(UnusedSymbolSelection, unusedSelections);
......@@ -1925,6 +1972,100 @@ void CPPEditor::updateSemanticInfo(const SemanticInfo &semanticInfo)
m_lastSemanticInfo.forced = false; // clear the forced flag
}
namespace {
class FindObjCKeywords: public ASTVisitor
{
public:
FindObjCKeywords(TranslationUnit *unit)
: ASTVisitor(unit)
{}
QList<SemanticInfo::Use> operator()()
{
_keywords.clear();
accept(translationUnit()->ast());
return _keywords;
}
virtual bool visit(ObjCClassDeclarationAST *ast)
{
addToken(ast->interface_token);
addToken(ast->implementation_token);
addToken(ast->end_token);
return true;
}
virtual bool visit(ObjCClassForwardDeclarationAST *ast)
{ addToken(ast->class_token); return true; }
virtual bool visit(ObjCProtocolDeclarationAST *ast)
{ addToken(ast->protocol_token); addToken(ast->end_token); return true; }
virtual bool visit(ObjCProtocolForwardDeclarationAST *ast)
{ addToken(ast->protocol_token); return true; }
virtual bool visit(ObjCProtocolExpressionAST *ast)
{ addToken(ast->protocol_token); return true; }
virtual bool visit(ObjCTypeNameAST *) { return true; }
virtual bool visit(ObjCEncodeExpressionAST *ast)
{ addToken(ast->encode_token); return true; }
virtual bool visit(ObjCSelectorExpressionAST *ast)
{ addToken(ast->selector_token); return true; }
virtual bool visit(ObjCVisibilityDeclarationAST *ast)
{ addToken(ast->visibility_token); return true; }
virtual bool visit(ObjCPropertyAttributeAST *ast)
{
const Identifier *attrId = identifier(ast->attribute_identifier_token);
if (attrId == control()->objcAssignId()
|| attrId == control()->objcCopyId()
|| attrId == control()->objcGetterId()
|| attrId == control()->objcNonatomicId()
|| attrId == control()->objcReadonlyId()
|| attrId == control()->objcReadwriteId()
|| attrId == control()->objcRetainId()
|| attrId == control()->objcSetterId())
addToken(ast->attribute_identifier_token);
return true;
}
virtual bool visit(ObjCPropertyDeclarationAST *ast)
{ addToken(ast->property_token); return true; }
virtual bool visit(ObjCSynthesizedPropertiesDeclarationAST *ast)
{ addToken(ast->synthesized_token); return true; }
virtual bool visit(ObjCDynamicPropertiesDeclarationAST *ast)
{ addToken(ast->dynamic_token); return true; }
virtual bool visit(ObjCFastEnumerationAST *ast)
{ addToken(ast->for_token); addToken(ast->in_token); return true; }
virtual bool visit(ObjCSynchronizedStatementAST *ast)
{ addToken(ast->synchronized_token); return true; }
protected:
void addToken(unsigned token)
{
if (token) {
SemanticInfo::Use use;
getTokenStartPosition(token, &use.line, &use.column);
use.length = tokenAt(token).length();
_keywords.append(use);
}
}
private:
QList<SemanticInfo::Use> _keywords;
};
} // anonymous namespace
SemanticHighlighter::Source CPPEditor::currentSource(bool force)
{
int line = 0, column = 0;
......@@ -2015,7 +2156,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
Snapshot snapshot;
Document::Ptr doc;
QList<Document::DiagnosticMessage> diagnosticMessages;
QList<SemanticInfo::Use> typeUsages;
QList<SemanticInfo::Use> typeUsages, objcKeywords;
LookupContext context;
if (! source.force && revision == source.revision) {
......@@ -2024,6 +2165,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
doc = m_lastSemanticInfo.doc;
diagnosticMessages = m_lastSemanticInfo.diagnosticMessages;
typeUsages = m_lastSemanticInfo.typeUsages;
objcKeywords = m_lastSemanticInfo.objcKeywords;
context = m_lastSemanticInfo.context;
m_mutex.unlock();
}
......@@ -2043,6 +2185,9 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
typeUsages.clear();
foreach (const CheckUndefinedSymbols::Use &use, checkUndefinedSymbols.typeUsages()) // ### remove me
typeUsages.append(SemanticInfo::Use(use.line, use.column, use.length));
FindObjCKeywords findObjCKeywords(unit);
objcKeywords = findObjCKeywords();
}
}
......@@ -2065,6 +2210,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
semanticInfo.forced = source.force;
semanticInfo.diagnosticMessages = diagnosticMessages;
semanticInfo.typeUsages = typeUsages;
semanticInfo.objcKeywords = objcKeywords;
semanticInfo.context = context;
return semanticInfo;
......
......@@ -93,6 +93,7 @@ public:
CPlusPlus::LookupContext context;
LocalUseMap localUses; // ### rename
QList<Use> typeUsages;
QList<Use> objcKeywords;
QList<CPlusPlus::Document::DiagnosticMessage> diagnosticMessages;
};
......@@ -203,6 +204,11 @@ public:
CppTools::CppModelManagerInterface *modelManager() const;
virtual void setMimeType(const QString &mt);
void setObjCEnabled(bool onoff);
bool isObjCEnabled() const;
public Q_SLOTS:
virtual void setFontSettings(const TextEditor::FontSettings &);
void setSortedMethodOverview(bool sort);
......@@ -297,6 +303,7 @@ private:
QTextCharFormat m_occurrencesUnusedFormat;
QTextCharFormat m_occurrenceRenameFormat;
QTextCharFormat m_typeFormat;
QTextCharFormat m_keywordFormat;
QList<QTextEdit::ExtraSelection> m_renameSelections;
int m_currentRenameSelection;
......@@ -307,6 +314,7 @@ private:
SemanticHighlighter *m_semanticHighlighter;
SemanticInfo m_lastSemanticInfo;
QList<TextEditor::QuickFixOperation::Ptr> m_quickFixes;
bool m_objcEnabled;
bool m_initialized;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment