forked from qt-creator/qt-creator
Inital support for Q_D/Q_Q declarations.
This commit is contained in:
@@ -1462,6 +1462,10 @@ bool Preprocessor::isQtReservedWord(const QByteArray ¯oId) const
|
||||
return true;
|
||||
else if (size == 6 && macroId.at(0) == 'Q' && macroId == "Q_SLOT")
|
||||
return true;
|
||||
else if (size == 3 && macroId.at(0) == 'Q' && macroId == "Q_D")
|
||||
return true;
|
||||
else if (size == 3 && macroId.at(0) == 'Q' && macroId == "Q_Q")
|
||||
return true;
|
||||
else if (size == 6 && macroId.at(0) == 'S' && macroId == "SIGNAL")
|
||||
return true;
|
||||
else if (size == 4 && macroId.at(0) == 'S' && macroId == "SLOT")
|
||||
|
@@ -186,19 +186,20 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class FindUses: protected ASTVisitor
|
||||
class FindLocalUses: protected ASTVisitor
|
||||
{
|
||||
Scope *_functionScope;
|
||||
|
||||
FindScope findScope;
|
||||
|
||||
public:
|
||||
FindUses(TranslationUnit *translationUnit)
|
||||
: ASTVisitor(translationUnit)
|
||||
FindLocalUses(TranslationUnit *translationUnit)
|
||||
: ASTVisitor(translationUnit), hasD(false), hasQ(false)
|
||||
{ }
|
||||
|
||||
// local and external uses.
|
||||
SemanticInfo::LocalUseMap localUses;
|
||||
bool hasD;
|
||||
bool hasQ;
|
||||
|
||||
void operator()(FunctionDefinitionAST *ast)
|
||||
{
|
||||
@@ -357,6 +358,16 @@ protected:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(QtMemberDeclarationAST *ast)
|
||||
{
|
||||
if (tokenKind(ast->q_token) == T_Q_D)
|
||||
hasD = true;
|
||||
else
|
||||
hasQ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visit(ExpressionOrDeclarationStatementAST *ast)
|
||||
{
|
||||
accept(ast->declaration);
|
||||
@@ -929,6 +940,7 @@ void CPPEditor::updateMethodBoxIndex()
|
||||
}
|
||||
|
||||
void CPPEditor::highlightUses(const QList<SemanticInfo::Use> &uses,
|
||||
const SemanticInfo &semanticInfo,
|
||||
QList<QTextEdit::ExtraSelection> *selections)
|
||||
{
|
||||
bool isUnused = false;
|
||||
@@ -951,6 +963,14 @@ void CPPEditor::highlightUses(const QList<SemanticInfo::Use> &uses,
|
||||
sel.cursor.setPosition(anchor);
|
||||
sel.cursor.setPosition(position, QTextCursor::KeepAnchor);
|
||||
|
||||
if (isUnused) {
|
||||
if (semanticInfo.hasQ && sel.cursor.selectedText() == QLatin1String("q"))
|
||||
continue; // skip q
|
||||
|
||||
else if (semanticInfo.hasD && sel.cursor.selectedText() == QLatin1String("d"))
|
||||
continue; // skip d
|
||||
}
|
||||
|
||||
selections->append(sel);
|
||||
}
|
||||
}
|
||||
@@ -1953,14 +1973,12 @@ void CPPEditor::updateSemanticInfo(const SemanticInfo &semanticInfo)
|
||||
}
|
||||
}
|
||||
|
||||
if (uses.size() == 1) {
|
||||
if (uses.size() == 1)
|
||||
// it's an unused declaration
|
||||
highlightUses(uses, &unusedSelections);
|
||||
} else if (good) {
|
||||
QList<QTextEdit::ExtraSelection> selections;
|
||||
highlightUses(uses, &selections);
|
||||
m_renameSelections += selections;
|
||||
}
|
||||
highlightUses(uses, semanticInfo, &unusedSelections);
|
||||
|
||||
else if (good && m_renameSelections.isEmpty())
|
||||
highlightUses(uses, semanticInfo, &m_renameSelections);
|
||||
}
|
||||
|
||||
setExtraSelections(UnusedSymbolSelection, unusedSelections);
|
||||
@@ -2078,7 +2096,7 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
|
||||
FunctionDefinitionUnderCursor functionDefinitionUnderCursor(translationUnit);
|
||||
FunctionDefinitionAST *currentFunctionDefinition = functionDefinitionUnderCursor(ast, source.line, source.column);
|
||||
|
||||
FindUses useTable(translationUnit);
|
||||
FindLocalUses useTable(translationUnit);
|
||||
useTable(currentFunctionDefinition);
|
||||
|
||||
SemanticInfo semanticInfo;
|
||||
@@ -2086,6 +2104,8 @@ SemanticInfo SemanticHighlighter::semanticInfo(const Source &source)
|
||||
semanticInfo.snapshot = snapshot;
|
||||
semanticInfo.doc = doc;
|
||||
semanticInfo.localUses = useTable.localUses;
|
||||
semanticInfo.hasQ = useTable.hasQ;
|
||||
semanticInfo.hasD = useTable.hasD;
|
||||
|
||||
return semanticInfo;
|
||||
}
|
||||
|
@@ -79,10 +79,12 @@ public:
|
||||
typedef QHashIterator<CPlusPlus::Symbol *, QList<Use> > LocalUseIterator;
|
||||
|
||||
SemanticInfo()
|
||||
: revision(-1)
|
||||
: revision(-1), hasQ(false), hasD(false)
|
||||
{ }
|
||||
|
||||
int revision;
|
||||
bool hasQ: 1;
|
||||
bool hasD: 1;
|
||||
CPlusPlus::Snapshot snapshot;
|
||||
CPlusPlus::Document::Ptr doc;
|
||||
LocalUseMap localUses;
|
||||
@@ -253,6 +255,7 @@ private:
|
||||
SemanticHighlighter::Source currentSource(bool force = false);
|
||||
|
||||
void highlightUses(const QList<SemanticInfo::Use> &uses,
|
||||
const SemanticInfo &semanticInfo,
|
||||
QList<QTextEdit::ExtraSelection> *selections);
|
||||
|
||||
void createToolBar(CPPEditorEditable *editable);
|
||||
|
@@ -246,7 +246,21 @@ unsigned QtMethodAST::lastToken() const
|
||||
return method_token + 1;
|
||||
}
|
||||
|
||||
unsigned QtMemberDeclarationAST::firstToken() const
|
||||
{
|
||||
return q_token;
|
||||
}
|
||||
|
||||
unsigned QtMemberDeclarationAST::lastToken() const
|
||||
{
|
||||
if (rparen_token)
|
||||
return rparen_token + 1;
|
||||
else if (type_id)
|
||||
return type_id->lastToken();
|
||||
else if (lparen_token)
|
||||
return lparen_token + 1;
|
||||
return q_token + 1;
|
||||
}
|
||||
|
||||
unsigned BinaryExpressionAST::firstToken() const
|
||||
{
|
||||
|
@@ -246,6 +246,7 @@ public:
|
||||
virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; }
|
||||
virtual PostfixExpressionAST *asPostfixExpression() { return 0; }
|
||||
virtual PtrOperatorAST *asPtrOperator() { return 0; }
|
||||
virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return 0; }
|
||||
virtual QtMethodAST *asQtMethod() { return 0; }
|
||||
virtual QualifiedNameAST *asQualifiedName() { return 0; }
|
||||
virtual ReferenceAST *asReference() { return 0; }
|
||||
@@ -582,6 +583,25 @@ protected:
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT QtMemberDeclarationAST: public StatementAST
|
||||
{
|
||||
public:
|
||||
unsigned q_token;
|
||||
unsigned lparen_token;
|
||||
ExpressionAST *type_id;
|
||||
unsigned rparen_token;
|
||||
|
||||
public:
|
||||
virtual QtMemberDeclarationAST *asQtMemberDeclaration() { return this; }
|
||||
|
||||
virtual unsigned firstToken() const;
|
||||
virtual unsigned lastToken() const;
|
||||
|
||||
protected:
|
||||
virtual void accept0(ASTVisitor *visitor);
|
||||
virtual bool match0(AST *, ASTMatcher *);
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT BinaryExpressionAST: public ExpressionAST
|
||||
{
|
||||
public:
|
||||
|
@@ -128,6 +128,14 @@ bool QtMethodAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QtMemberDeclarationAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (QtMemberDeclarationAST *_other = pattern->asQtMemberDeclaration())
|
||||
return matcher->match(this, _other);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BinaryExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
|
||||
{
|
||||
if (BinaryExpressionAST *_other = pattern->asBinaryExpression())
|
||||
|
@@ -274,6 +274,25 @@ bool ASTMatcher::match(QtMethodAST *node, QtMethodAST *pattern)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(QtMemberDeclarationAST *node, QtMemberDeclarationAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
(void) pattern;
|
||||
|
||||
pattern->q_token = node->q_token;
|
||||
|
||||
pattern->lparen_token = node->lparen_token;
|
||||
|
||||
if (! pattern->type_id)
|
||||
pattern->type_id = node->type_id;
|
||||
else if (! AST::match(node->type_id, pattern->type_id, this))
|
||||
return false;
|
||||
|
||||
pattern->rparen_token = node->rparen_token;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ASTMatcher::match(BinaryExpressionAST *node, BinaryExpressionAST *pattern)
|
||||
{
|
||||
(void) node;
|
||||
|
@@ -135,6 +135,7 @@ public:
|
||||
virtual bool match(UsingDirectiveAST *node, UsingDirectiveAST *pattern);
|
||||
virtual bool match(WhileStatementAST *node, WhileStatementAST *pattern);
|
||||
virtual bool match(QtMethodAST *node, QtMethodAST *pattern);
|
||||
virtual bool match(QtMemberDeclarationAST *node, QtMemberDeclarationAST *pattern);
|
||||
virtual bool match(ObjCClassDeclarationAST *node, ObjCClassDeclarationAST *pattern);
|
||||
virtual bool match(ObjCClassForwardDeclarationAST *node, ObjCClassForwardDeclarationAST *pattern);
|
||||
virtual bool match(ObjCProtocolDeclarationAST *node, ObjCProtocolDeclarationAST *pattern);
|
||||
|
@@ -131,6 +131,14 @@ void QtMethodAST::accept0(ASTVisitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void QtMemberDeclarationAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
accept(type_id, visitor);
|
||||
}
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
void BinaryExpressionAST::accept0(ASTVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
|
@@ -198,6 +198,7 @@ public:
|
||||
virtual bool visit(UsingDirectiveAST *) { return true; }
|
||||
virtual bool visit(WhileStatementAST *) { return true; }
|
||||
virtual bool visit(QtMethodAST *) { return true; }
|
||||
virtual bool visit(QtMemberDeclarationAST *) { return true; }
|
||||
|
||||
// ObjC++
|
||||
virtual bool visit(ObjCClassDeclarationAST *) { return true; }
|
||||
@@ -323,6 +324,7 @@ public:
|
||||
virtual void endVisit(UsingDirectiveAST *) { }
|
||||
virtual void endVisit(WhileStatementAST *) { }
|
||||
virtual void endVisit(QtMethodAST *) { }
|
||||
virtual void endVisit(QtMemberDeclarationAST *) { }
|
||||
|
||||
// ObjC++
|
||||
virtual void endVisit(ObjCClassDeclarationAST *) { }
|
||||
|
@@ -162,6 +162,7 @@ class PostfixAST;
|
||||
class PostfixDeclaratorAST;
|
||||
class PostfixExpressionAST;
|
||||
class PtrOperatorAST;
|
||||
class QtMemberDeclarationAST;
|
||||
class QtMethodAST;
|
||||
class QualifiedNameAST;
|
||||
class ReferenceAST;
|
||||
|
@@ -54,6 +54,9 @@
|
||||
#include "CoreTypes.h"
|
||||
#include "Control.h"
|
||||
#include "Symbols.h"
|
||||
#include "Names.h"
|
||||
#include "Literals.h"
|
||||
#include <string>
|
||||
|
||||
using namespace CPlusPlus;
|
||||
|
||||
@@ -307,4 +310,34 @@ bool CheckStatement::visit(WhileStatementAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckStatement::visit(QtMemberDeclarationAST *ast)
|
||||
{
|
||||
Name *name = 0;
|
||||
|
||||
if (tokenKind(ast->q_token) == T_Q_D)
|
||||
name = control()->nameId(control()->findOrInsertIdentifier("d"));
|
||||
else
|
||||
name = control()->nameId(control()->findOrInsertIdentifier("q"));
|
||||
|
||||
FullySpecifiedType declTy = semantic()->check(ast->type_id, _scope);
|
||||
|
||||
if (tokenKind(ast->q_token) == T_Q_D) {
|
||||
if (NamedType *namedTy = declTy->asNamedType()) {
|
||||
if (NameId *nameId = namedTy->name()->asNameId()) {
|
||||
std::string privateClass;
|
||||
privateClass += nameId->identifier()->chars();
|
||||
privateClass += "Private";
|
||||
|
||||
Name *privName = control()->nameId(control()->findOrInsertIdentifier(privateClass.c_str(), privateClass.size()));
|
||||
declTy.setType(control()->namedType(privName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Declaration *symbol = control()->newDeclaration(/*generated*/ 0, name);
|
||||
symbol->setType(control()->pointerType(declTy));
|
||||
|
||||
_scope->enterSymbol(symbol);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@@ -88,6 +88,7 @@ protected:
|
||||
virtual bool visit(TryBlockStatementAST *ast);
|
||||
virtual bool visit(CatchClauseAST *ast);
|
||||
virtual bool visit(WhileStatementAST *ast);
|
||||
virtual bool visit(QtMemberDeclarationAST *ast);
|
||||
|
||||
private:
|
||||
StatementAST *_statement;
|
||||
|
@@ -65,7 +65,7 @@ static inline int classify2(const char *s, bool) {
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
|
||||
static inline int classify3(const char *s, bool) {
|
||||
static inline int classify3(const char *s, bool q) {
|
||||
if (s[0] == 'a') {
|
||||
if (s[1] == 's') {
|
||||
if (s[2] == 'm') {
|
||||
@@ -101,6 +101,16 @@ static inline int classify3(const char *s, bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (q && s[0] == 'Q') {
|
||||
if (s[1] == '_') {
|
||||
if (s[2] == 'D') {
|
||||
return T_Q_D;
|
||||
}
|
||||
else if (s[2] == 'Q') {
|
||||
return T_Q_Q;
|
||||
}
|
||||
}
|
||||
}
|
||||
return T_IDENTIFIER;
|
||||
}
|
||||
|
||||
|
@@ -2104,6 +2104,16 @@ bool Parser::parseStatement(StatementAST *&node)
|
||||
if (objCEnabled())
|
||||
return parseObjCSynchronizedStatement(node);
|
||||
|
||||
case T_Q_D:
|
||||
case T_Q_Q: {
|
||||
QtMemberDeclarationAST *ast = new (_pool) QtMemberDeclarationAST;
|
||||
ast->q_token = consumeToken();
|
||||
match(T_LPAREN, &ast->lparen_token);
|
||||
parseTypeId(ast->type_id);
|
||||
match(T_RPAREN, &ast->rparen_token);
|
||||
node = ast;
|
||||
} return true;
|
||||
|
||||
default:
|
||||
if (LA() == T_IDENTIFIER && LA(2) == T_COLON)
|
||||
return parseLabeledStatement(node);
|
||||
|
@@ -91,7 +91,7 @@ static const char *token_names[] = {
|
||||
("@protected"), ("@protocol"), ("@public"), ("@required"), ("@selector"),
|
||||
("@synchronized"), ("@synthesize"), ("@throw"), ("@try"),
|
||||
|
||||
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"), ("Q_FOREACH")
|
||||
("SIGNAL"), ("SLOT"), ("Q_SIGNAL"), ("Q_SLOT"), ("signals"), ("slots"), ("Q_FOREACH"), ("Q_D"), ("Q_Q")
|
||||
};
|
||||
|
||||
Token::Token() :
|
||||
|
@@ -236,8 +236,10 @@ enum Kind {
|
||||
T_Q_SIGNALS,
|
||||
T_Q_SLOTS,
|
||||
T_Q_FOREACH,
|
||||
T_Q_D,
|
||||
T_Q_Q,
|
||||
|
||||
T_LAST_KEYWORD = T_Q_FOREACH,
|
||||
T_LAST_KEYWORD = T_Q_Q,
|
||||
|
||||
// aliases
|
||||
T_OR = T_PIPE_PIPE,
|
||||
|
@@ -100,7 +100,7 @@ class FindASTNodes: protected ASTVisitor
|
||||
{
|
||||
public:
|
||||
FindASTNodes(Document::Ptr doc, QTextDocument *document)
|
||||
: ASTVisitor(doc->control()), document(document)
|
||||
: ASTVisitor(doc->translationUnit()), document(document)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -159,8 +159,8 @@ class Accept0CG: protected ASTVisitor
|
||||
QTextStream *out;
|
||||
|
||||
public:
|
||||
Accept0CG(const QDir &cplusplusDir, Control *control)
|
||||
: ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
|
||||
Accept0CG(const QDir &cplusplusDir, TranslationUnit *unit)
|
||||
: ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
|
||||
{ }
|
||||
|
||||
void operator()(AST *ast)
|
||||
@@ -296,8 +296,8 @@ class Match0CG: protected ASTVisitor
|
||||
QTextStream *out;
|
||||
|
||||
public:
|
||||
Match0CG(const QDir &cplusplusDir, Control *control)
|
||||
: ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
|
||||
Match0CG(const QDir &cplusplusDir, TranslationUnit *unit)
|
||||
: ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
|
||||
{ }
|
||||
|
||||
void operator()(AST *ast)
|
||||
@@ -406,8 +406,8 @@ class MatcherCPPCG: protected ASTVisitor
|
||||
QTextStream *out;
|
||||
|
||||
public:
|
||||
MatcherCPPCG(const QDir &cplusplusDir, Control *control)
|
||||
: ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0)
|
||||
MatcherCPPCG(const QDir &cplusplusDir, TranslationUnit *unit)
|
||||
: ASTVisitor(unit), _cplusplusDir(cplusplusDir), out(0)
|
||||
{ }
|
||||
|
||||
void operator()(AST *ast)
|
||||
@@ -560,7 +560,7 @@ class RemoveCastMethods: protected ASTVisitor
|
||||
{
|
||||
public:
|
||||
RemoveCastMethods(Document::Ptr doc, QTextDocument *document)
|
||||
: ASTVisitor(doc->control()), document(document) {}
|
||||
: ASTVisitor(doc->translationUnit()), document(document) {}
|
||||
|
||||
QList<QTextCursor> operator()(AST *ast)
|
||||
{
|
||||
@@ -666,13 +666,13 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir)
|
||||
out << document.toPlainText();
|
||||
}
|
||||
|
||||
Accept0CG cg(cplusplusDir, AST_h_document->control());
|
||||
Accept0CG cg(cplusplusDir, AST_h_document->translationUnit());
|
||||
cg(AST_h_document->translationUnit()->ast());
|
||||
|
||||
Match0CG cg2(cplusplusDir, AST_h_document->control());
|
||||
Match0CG cg2(cplusplusDir, AST_h_document->translationUnit());
|
||||
cg2(AST_h_document->translationUnit()->ast());
|
||||
|
||||
MatcherCPPCG cg3(cplusplusDir, AST_h_document->control());
|
||||
MatcherCPPCG cg3(cplusplusDir, AST_h_document->translationUnit());
|
||||
cg3(AST_h_document->translationUnit()->ast());
|
||||
|
||||
return astDerivedClasses;
|
||||
@@ -682,7 +682,7 @@ class FindASTForwards: protected ASTVisitor
|
||||
{
|
||||
public:
|
||||
FindASTForwards(Document::Ptr doc, QTextDocument *document)
|
||||
: ASTVisitor(doc->control()), document(document)
|
||||
: ASTVisitor(doc->translationUnit()), document(document)
|
||||
{}
|
||||
|
||||
QList<QTextCursor> operator()(AST *ast)
|
||||
@@ -887,5 +887,5 @@ int main(int argc, char *argv[])
|
||||
astDerivedClasses.sort();
|
||||
generateASTFwd_h(snapshot, cplusplusDir, astDerivedClasses);
|
||||
|
||||
generateASTPatternBuilder_h(cplusplusDir);
|
||||
//generateASTPatternBuilder_h(cplusplusDir);
|
||||
}
|
||||
|
Reference in New Issue
Block a user