Commit 2b532c73 authored by hjk's avatar hjk

CPlusPlus: Make (sub-)languague selection more generic

Change-Id: I4e2df6992b446adec662ab07671acd41715e41fd
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 0a600e04
......@@ -347,7 +347,8 @@ FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType
std::swap(_declaratorId, declaratorId);
bool isAuto = false;
if (translationUnit()->cxx0xEnabled())
const bool cxx11Enabled = translationUnit()->languageFeatures().cxx11Enabled;
if (cxx11Enabled)
isAuto = type.isAuto();
for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
......@@ -369,8 +370,7 @@ FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType
}
if (!type->isFunctionType()) {
ExpressionTy initializer = this->expression(ast->initializer);
if (translationUnit()->cxx0xEnabled() && isAuto) {
if (cxx11Enabled && isAuto) {
type = initializer;
type.setAuto(true);
}
......@@ -1249,7 +1249,7 @@ bool Bind::visit(ForeachStatementAST *ast)
DeclaratorIdAST *declaratorId = 0;
type = this->declarator(ast->declarator, type, &declaratorId);
const StringLiteral *initializer = 0;
if (type.isAuto() && translationUnit()->cxx0xEnabled()) {
if (type.isAuto() && translationUnit()->languageFeatures().cxx11Enabled) {
ExpressionTy exprType = this->expression(ast->expression);
ArrayType* arrayType = 0;
......@@ -1299,7 +1299,7 @@ bool Bind::visit(RangeBasedForStatementAST *ast)
DeclaratorIdAST *declaratorId = 0;
type = this->declarator(ast->declarator, type, &declaratorId);
const StringLiteral *initializer = 0;
if (type.isAuto() && translationUnit()->cxx0xEnabled()) {
if (type.isAuto() && translationUnit()->languageFeatures().cxx11Enabled) {
ExpressionTy exprType = this->expression(ast->expression);
ArrayType* arrayType = 0;
......@@ -2722,7 +2722,7 @@ bool Bind::visit(SimpleSpecifierAST *ast)
break;
case T_AUTO:
if (!translationUnit()->cxx0xEnabled()) {
if (!translationUnit()->languageFeatures().cxx11Enabled) {
if (_type.isAuto())
translationUnit()->error(ast->specifier_token, "duplicate `%s'", spell(ast->specifier_token));
}
......
This diff is collapsed.
......@@ -81,24 +81,6 @@ int Lexer::state() const
void Lexer::setState(int state)
{ _state = state; }
bool Lexer::qtMocRunEnabled() const
{ return f._qtMocRunEnabled; }
void Lexer::setQtMocRunEnabled(bool onoff)
{ f._qtMocRunEnabled = onoff; }
bool Lexer::cxx0xEnabled() const
{ return f._cxx0xEnabled; }
void Lexer::setCxxOxEnabled(bool onoff)
{ f._cxx0xEnabled = onoff; }
bool Lexer::objCEnabled() const
{ return f._objCEnabled; }
void Lexer::setObjCEnabled(bool onoff)
{ f._objCEnabled = onoff; }
bool Lexer::isIncremental() const
{ return f._isIncremental; }
......@@ -557,7 +539,7 @@ void Lexer::scan_helper(Token *tok)
break;
default: {
if (f._objCEnabled) {
if (_languageFeatures.objCEnabled) {
if (ch == '@' && _yychar >= 'a' && _yychar <= 'z') {
const char *yytext = _currentChar;
......@@ -780,7 +762,7 @@ void Lexer::scanIdentifier(Token *tok, unsigned extraProcessedChars)
yyinp();
int yylen = _currentChar - yytext;
if (f._scanKeywords)
tok->f.kind = classify(yytext, yylen, f._qtMocRunEnabled, f._cxx0xEnabled);
tok->f.kind = classify(yytext, yylen, _languageFeatures);
else
tok->f.kind = T_IDENTIFIER;
......
......@@ -45,15 +45,6 @@ public:
Control *control() const { return _control; }
TranslationUnit *translationUnit() const;
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
bool cxx0xEnabled() const;
void setCxxOxEnabled(bool onoff);
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
void scan(Token *tok);
inline void operator()(Token *tok)
......@@ -82,10 +73,13 @@ public:
bool isIncremental() const;
void setIncremental(bool isIncremental);
LanguageFeatures languageFeatures() const { return _languageFeatures; }
void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
private:
void scan_helper(Token *tok);
void setSource(const char *firstChar, const char *lastChar);
static int classify(const char *string, int length, bool q, bool cxx0x);
static int classify(const char *string, int length, LanguageFeatures features);
static int classifyObjCAtKeyword(const char *s, int n);
static int classifyOperator(const char *string, int length);
......@@ -111,9 +105,6 @@ private:
unsigned _scanCommentTokens: 1;
unsigned _scanKeywords: 1;
unsigned _scanAngleStringLiteralTokens: 1;
unsigned _qtMocRunEnabled: 1;
unsigned _cxx0xEnabled: 1;
unsigned _objCEnabled: 1;
};
TranslationUnit *_translationUnit;
......@@ -129,6 +120,8 @@ private:
Flags f;
};
unsigned _currentLine;
LanguageFeatures _languageFeatures;
};
} // namespace CPlusPlus
......
This diff is collapsed.
......@@ -36,15 +36,6 @@ public:
Parser(TranslationUnit *translationUnit);
~Parser();
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
bool cxx0xEnabled() const;
void setCxxOxEnabled(bool onoff);
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
bool parseTranslationUnit(TranslationUnitAST *&node);
public:
......@@ -315,11 +306,9 @@ private:
TranslationUnit *_translationUnit;
Control *_control;
MemoryPool *_pool;
LanguageFeatures _languageFeatures;
unsigned _tokenIndex;
bool _templateArguments: 1;
bool _qtMocRunEnabled: 1;
bool _cxx0xEnabled: 1;
bool _objCEnabled: 1;
bool _inFunctionBody: 1;
bool _inObjCImplementationContext: 1;
bool _inExpressionStatement: 1;
......
......@@ -373,6 +373,22 @@ public:
};
};
struct LanguageFeatures
{
LanguageFeatures() : flags(0) {}
union {
unsigned int flags;
struct {
unsigned int qtEnabled : 1; // If Qt is used.
unsigned int qtMocRunEnabled : 1;
unsigned int qtKeywordsEnabled : 1; // If Qt is used but QT_NO_KEYWORDS defined
unsigned int cxx11Enabled : 1;
unsigned int objCEnabled : 1;
};
};
};
} // namespace CPlusPlus
......
......@@ -63,24 +63,6 @@ TranslationUnit::~TranslationUnit()
delete _pool;
}
bool TranslationUnit::qtMocRunEnabled() const
{ return f._qtMocRunEnabled; }
void TranslationUnit::setQtMocRunEnabled(bool onoff)
{ f._qtMocRunEnabled = onoff; }
bool TranslationUnit::cxx0xEnabled() const
{ return f._cxx0xEnabled; }
void TranslationUnit::setCxxOxEnabled(bool onoff)
{ f._cxx0xEnabled = onoff; }
bool TranslationUnit::objCEnabled() const
{ return f._objCEnabled; }
void TranslationUnit::setObjCEnabled(bool onoff)
{ f._objCEnabled = onoff; }
Control *TranslationUnit::control() const
{ return _control; }
......@@ -157,9 +139,7 @@ void TranslationUnit::tokenize()
f._tokenized = true;
Lexer lex(this);
lex.setQtMocRunEnabled(f._qtMocRunEnabled);
lex.setCxxOxEnabled(f._cxx0xEnabled);
lex.setObjCEnabled(f._objCEnabled);
lex.setLanguageFeatures(_languageFeatures);
lex.setScanCommentTokens(true);
std::stack<unsigned> braces;
......@@ -319,10 +299,6 @@ bool TranslationUnit::parse(ParseMode mode)
f._parsed = true;
Parser parser(this);
parser.setQtMocRunEnabled(f._qtMocRunEnabled);
parser.setCxxOxEnabled(f._cxx0xEnabled);
parser.setObjCEnabled(f._objCEnabled);
bool parsed = false;
switch (mode) {
......
......@@ -87,15 +87,6 @@ public:
return previous;
}
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool onoff);
bool cxx0xEnabled() const;
void setCxxOxEnabled(bool onoff);
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
void warning(unsigned index, const char *fmt, ...);
void error(unsigned index, const char *fmt, ...);
void fatal(unsigned index, const char *fmt, ...);
......@@ -151,6 +142,9 @@ public:
bool maybeSplitGreaterGreaterToken(unsigned tokenIndex);
LanguageFeatures languageFeatures() const { return _languageFeatures; }
void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
private:
struct PPLine {
unsigned offset;
......@@ -203,14 +197,12 @@ private:
unsigned _parsed: 1;
unsigned _blockErrors: 1;
unsigned _skipFunctionBody: 1;
unsigned _qtMocRunEnabled: 1;
unsigned _cxx0xEnabled: 1;
unsigned _objCEnabled: 1;
};
union {
unsigned _flags;
Flags f;
};
LanguageFeatures _languageFeatures;
};
} // namespace CPlusPlus
......
......@@ -45,9 +45,14 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor,
, _block(cursor.block())
, _maxBlockCount(maxBlockCount)
{
_tokenize.setQtMocRunEnabled(true);
// FIXME: Why these defaults?
LanguageFeatures features;
features.qtMocRunEnabled = true;
features.qtEnabled = true;
features.qtKeywordsEnabled = true;
features.objCEnabled = true;
_tokenize.setLanguageFeatures(features);
_tokenize.setSkipComments(skipComments);
_tokenize.setObjCEnabled(true);
_text = _block.text().left(cursor.position() - cursor.block().position());
if (! suffix.isEmpty())
......
......@@ -284,10 +284,14 @@ Document::Document(const QString &fileName)
const QByteArray localFileName = fileName.toUtf8();
const StringLiteral *fileId = _control->stringLiteral(localFileName.constData(),
localFileName.size());
LanguageFeatures features;
features.qtEnabled = true;
features.qtMocRunEnabled = true;
features.qtKeywordsEnabled = true;
features.cxx11Enabled = true;
features.objCEnabled = true;
_translationUnit = new TranslationUnit(_control, fileId);
_translationUnit->setQtMocRunEnabled(true);
_translationUnit->setCxxOxEnabled(true);
_translationUnit->setObjCEnabled(true);
_translationUnit->setLanguageFeatures(features);
(void) _control->switchTranslationUnit(_translationUnit);
}
......
......@@ -40,46 +40,12 @@ using namespace CPlusPlus;
SimpleLexer::SimpleLexer()
: _lastState(0),
_skipComments(false),
_qtMocRunEnabled(true),
_objCEnabled(false),
_endedJoined(false),
_cxx0xEnabled(false)
{
}
_endedJoined(false)
{}
SimpleLexer::~SimpleLexer()
{ }
bool SimpleLexer::qtMocRunEnabled() const
{
return _qtMocRunEnabled;
}
void SimpleLexer::setQtMocRunEnabled(bool enabled)
{
_qtMocRunEnabled = enabled;
}
bool SimpleLexer::objCEnabled() const
{
return _objCEnabled;
}
void SimpleLexer::setObjCEnabled(bool onoff)
{
_objCEnabled = onoff;
}
bool SimpleLexer::cxx0xEnabled() const
{
return _cxx0xEnabled;
}
void SimpleLexer::setCxx0xEnabled(bool enabled)
{
_cxx0xEnabled = enabled;
}
bool SimpleLexer::skipComments() const
{
return _skipComments;
......@@ -104,11 +70,8 @@ QList<Token> SimpleLexer::operator()(const QString &text, int state)
const char *lastChar = firstChar + bytes.size();
Lexer lex(firstChar, lastChar);
lex.setQtMocRunEnabled(_qtMocRunEnabled);
lex.setObjCEnabled(_objCEnabled);
lex.setLanguageFeatures(_languageFeatures);
lex.setStartWithNewline(true);
lex.setObjCEnabled(_objCEnabled);
lex.setCxxOxEnabled(_cxx0xEnabled);
if (! _skipComments)
lex.setScanCommentTokens(true);
......@@ -137,7 +100,7 @@ QList<Token> SimpleLexer::operator()(const QString &text, int state)
else if (inPreproc && tokens.size() == 1 && tk.is(T_IDENTIFIER) &&
spell == QLatin1String("include_next"))
lex.setScanAngleStringLiteralTokens(true);
else if (_objCEnabled
else if (_languageFeatures.objCEnabled
&& inPreproc && tokens.size() == 1 && tk.is(T_IDENTIFIER) &&
spell == QLatin1String("import"))
lex.setScanAngleStringLiteralTokens(true);
......@@ -165,8 +128,13 @@ Token SimpleLexer::tokenAt(const QString &text,
int state,
bool qtMocRunEnabled)
{
// FIXME: Check default values.
LanguageFeatures features;
features.qtMocRunEnabled = qtMocRunEnabled;
features.qtEnabled = qtMocRunEnabled;
features.qtKeywordsEnabled = qtMocRunEnabled;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(qtMocRunEnabled);
tokenize.setLanguageFeatures(features);
const QList<Token> tokens = tokenize(text, state);
const int tokenIdx = tokenAt(tokens, offset);
return (tokenIdx == -1) ? Token() : tokens.at(tokenIdx);
......
......@@ -30,6 +30,7 @@
#define CPLUSPLUS_SIMPLELEXER_H
#include <cplusplus/CPlusPlusForwardDeclarations.h>
#include <cplusplus/Token.h>
#include <QString>
#include <QList>
......@@ -48,14 +49,8 @@ public:
bool skipComments() const;
void setSkipComments(bool skipComments);
bool qtMocRunEnabled() const;
void setQtMocRunEnabled(bool enabled);
bool objCEnabled() const;
void setObjCEnabled(bool onoff);
bool cxx0xEnabled() const;
void setCxx0xEnabled(bool enabled);
LanguageFeatures languageFeatures() const { return _languageFeatures; }
void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
bool endedJoined() const;
......@@ -74,11 +69,9 @@ public:
private:
int _lastState;
LanguageFeatures _languageFeatures;
bool _skipComments: 1;
bool _qtMocRunEnabled: 1;
bool _objCEnabled: 1;
bool _endedJoined: 1;
bool _cxx0xEnabled: 1;
};
} // namespace CPlusPlus
......
......@@ -101,10 +101,14 @@ QString CppAutoCompleter::insertParagraphSeparator(const QTextCursor &cursor) co
bool CppAutoCompleter::isInCommentHelper(const QTextCursor &cursor, Token *retToken) const
{
LanguageFeatures features;
features.qtEnabled = false;
features.qtKeywordsEnabled = false;
features.qtMocRunEnabled = false;
features.cxx11Enabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(false);
tokenize.setObjCEnabled(false);
tokenize.setCxx0xEnabled(true);
tokenize.setLanguageFeatures(features);
const int prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF;
const QList<Token> tokens = tokenize(cursor.block().text(), prevState);
......
......@@ -327,8 +327,13 @@ BaseTextEditorWidget::Link FollowSymbolUnderCursor::findLink(const QTextCursor &
int beginOfToken = 0;
int endOfToken = 0;
LanguageFeatures features;
features.qtEnabled = true;
features.qtKeywordsEnabled = true;
features.qtMocRunEnabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(true);
tokenize.setLanguageFeatures(features);
const QString blockText = cursor.block().text();
const QList<Token> tokens = tokenize(blockText,
BackwardsScanner::previousBlockState(cursor.block()));
......
......@@ -74,10 +74,12 @@ void CppHighlighter::highlightBlock(const QString &text)
int braceDepth = initialBraceDepth;
// FIXME: Check defaults or get from document.
LanguageFeatures features;
features.cxx11Enabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(false);
tokenize.setObjCEnabled(false);
tokenize.setCxx0xEnabled(true);
tokenize.setLanguageFeatures(features);
int initialState = state;
const QList<Token> tokens = tokenize(text, initialState);
......
......@@ -1055,9 +1055,14 @@ int CodeFormatter::tokenizeBlock(const QTextBlock &block, bool *endedJoined)
startState = 0;
QTC_ASSERT(startState != -1, return 0);
LanguageFeatures features;
features.qtEnabled = true;
features.qtMocRunEnabled = true;
features.qtKeywordsEnabled = true;
features.objCEnabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(true);
tokenize.setObjCEnabled(true);
tokenize.setLanguageFeatures(features);
m_currentLine = block.text();
// to determine whether a line was joined, Tokenizer needs a
......
......@@ -616,7 +616,6 @@ bool isQPrivateSignal(const Symbol *symbol)
// ----------------------------
CppCompletionAssistProcessor::CppCompletionAssistProcessor()
: m_startPosition(-1)
, m_objcEnabled(true)
, m_snippetCollector(QLatin1String(CppEditor::Constants::CPP_SNIPPETS_GROUP_ID),
QIcon(QLatin1String(":/texteditor/images/snippet.png")))
, preprocessorCompletions(QStringList()
......@@ -634,7 +633,13 @@ CppCompletionAssistProcessor::CppCompletionAssistProcessor()
<< QLatin1String("endif"))
, m_model(new CppAssistProposalModel)
, m_hintProposal(0)
{}
{
// FIXME: C++11?
m_languageFeatures.objCEnabled = true;
m_languageFeatures.qtEnabled = true;
m_languageFeatures.qtKeywordsEnabled = true;
m_languageFeatures.qtMocRunEnabled = true;
}
CppCompletionAssistProcessor::~CppCompletionAssistProcessor()
{}
......@@ -683,10 +688,16 @@ bool CppCompletionAssistProcessor::accepts() const
QTextCursor tc(m_interface->textDocument());
tc.setPosition(pos);
LanguageFeatures features;
features.qtEnabled = true;
features.qtMocRunEnabled = true;
features.qtKeywordsEnabled = true;
features.objCEnabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(true);
tokenize.setObjCEnabled(true);
tokenize.setLanguageFeatures(features);
tokenize.setSkipComments(false);
const QList<Token> &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);
......@@ -703,7 +714,7 @@ bool CppCompletionAssistProcessor::accepts() const
line.midRef(idToken.begin(), idToken.end() - idToken.begin());
if (identifier == QLatin1String("include")
|| identifier == QLatin1String("include_next")
|| (m_objcEnabled && identifier == QLatin1String("import"))) {
|| (m_languageFeatures.objCEnabled && identifier == QLatin1String("import"))) {
return true;
}
}
......@@ -787,8 +798,7 @@ int CppCompletionAssistProcessor::startOfOperator(int pos,
}
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(true);
tokenize.setObjCEnabled(true);
tokenize.setLanguageFeatures(m_languageFeatures);
tokenize.setSkipComments(false);
const QList<Token> &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block()));
const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1)); // get the token at the left of the cursor
......@@ -879,7 +889,7 @@ int CppCompletionAssistProcessor::findStartOfName(int pos) const
int CppCompletionAssistProcessor::startCompletionHelper()
{
if (m_objcEnabled) {
if (m_languageFeatures.objCEnabled) {
if (tryObjCCompletion())
return m_startPosition;
}
......@@ -1193,7 +1203,7 @@ void CppCompletionAssistProcessor::completePreprocessor()
bool CppCompletionAssistProcessor::objcKeywordsWanted() const
{
if (!m_objcEnabled)
if (!m_languageFeatures.objCEnabled)
return false;
const QString fileName = m_interface->fileName();
......
......@@ -152,7 +152,7 @@ private:
QSet<QString> *definedMacros);
int m_startPosition;
bool m_objcEnabled;
CPlusPlus::LanguageFeatures m_languageFeatures;
QScopedPointer<const CppCompletionAssistInterface> m_interface;
QList<TextEditor::BasicProposalItem *> m_completions;
TextEditor::SnippetAssistCollector m_snippetCollector;
......
......@@ -73,11 +73,14 @@ QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highligh
if (isQtKeyword(QStringRef(&name)))
continue;
//Filter out C++ keywords
// Filter out C++ keywords
// FIXME: Check default values or get from document.
LanguageFeatures features;
features.cxx11Enabled = true;
SimpleLexer tokenize;
tokenize.setQtMocRunEnabled(false);
tokenize.setObjCEnabled(false);
tokenize.setCxx0xEnabled(true);
tokenize.setLanguageFeatures(features);
const QList<Token> tokens = tokenize(name);
if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword()))
continue;
......
......@@ -45,16 +45,19 @@ class tst_AST: public QObject
Control control;
public:
TranslationUnit *parse(const QByteArray &source,
TranslationUnit::ParseMode mode,
bool blockErrors = false,
bool qtMocRun = false)
{
const StringLiteral *fileId = control.stringLiteral("<stdin>");