forked from qt-creator/qt-creator
C++: Store lambda captures in the code model.
Done-with: Erik Verbruggen Task-number: QTCREATORBUG-7968 Task-number: QTCREATORBUG-7949 Change-Id: I0cf727052d0a3536ed96ee894b18768c9538c213 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
This commit is contained in:
10
src/libs/3rdparty/cplusplus/AST.cpp
vendored
10
src/libs/3rdparty/cplusplus/AST.cpp
vendored
@@ -403,12 +403,22 @@ unsigned CallAST::lastToken() const
|
|||||||
/** \generated */
|
/** \generated */
|
||||||
unsigned CaptureAST::firstToken() const
|
unsigned CaptureAST::firstToken() const
|
||||||
{
|
{
|
||||||
|
if (amper_token)
|
||||||
|
return amper_token;
|
||||||
|
if (identifier)
|
||||||
|
if (unsigned candidate = identifier->firstToken())
|
||||||
|
return candidate;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \generated */
|
/** \generated */
|
||||||
unsigned CaptureAST::lastToken() const
|
unsigned CaptureAST::lastToken() const
|
||||||
{
|
{
|
||||||
|
if (identifier)
|
||||||
|
if (unsigned candidate = identifier->lastToken())
|
||||||
|
return candidate;
|
||||||
|
if (amper_token)
|
||||||
|
return amper_token + 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
src/libs/3rdparty/cplusplus/AST.h
vendored
6
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -4394,8 +4394,14 @@ protected:
|
|||||||
|
|
||||||
class CaptureAST: public AST
|
class CaptureAST: public AST
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
unsigned amper_token;
|
||||||
|
NameAST *identifier;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CaptureAST()
|
CaptureAST()
|
||||||
|
: amper_token(0)
|
||||||
|
, identifier(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual CaptureAST *asCapture() { return this; }
|
virtual CaptureAST *asCapture() { return this; }
|
||||||
|
|||||||
3
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
3
src/libs/3rdparty/cplusplus/ASTClone.cpp
vendored
@@ -1703,6 +1703,9 @@ LambdaCaptureAST *LambdaCaptureAST::clone(MemoryPool *pool) const
|
|||||||
CaptureAST *CaptureAST::clone(MemoryPool *pool) const
|
CaptureAST *CaptureAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
CaptureAST *ast = new (pool) CaptureAST;
|
CaptureAST *ast = new (pool) CaptureAST;
|
||||||
|
ast->amper_token = amper_token;
|
||||||
|
if (identifier)
|
||||||
|
ast->identifier = identifier->clone(pool);
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
7
src/libs/3rdparty/cplusplus/ASTMatcher.cpp
vendored
@@ -2898,6 +2898,13 @@ bool ASTMatcher::match(CaptureAST *node, CaptureAST *pattern)
|
|||||||
(void) node;
|
(void) node;
|
||||||
(void) pattern;
|
(void) pattern;
|
||||||
|
|
||||||
|
pattern->amper_token = node->amper_token;
|
||||||
|
|
||||||
|
if (! pattern->identifier)
|
||||||
|
pattern->identifier = node->identifier;
|
||||||
|
else if (! AST::match(node->identifier, pattern->identifier, this))
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1107,9 +1107,10 @@ public:
|
|||||||
return __ast;
|
return __ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureAST *Capture()
|
CaptureAST *Capture(NameAST *identifier = 0)
|
||||||
{
|
{
|
||||||
CaptureAST *__ast = new (&pool) CaptureAST;
|
CaptureAST *__ast = new (&pool) CaptureAST;
|
||||||
|
__ast->identifier = identifier;
|
||||||
return __ast;
|
return __ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
1
src/libs/3rdparty/cplusplus/ASTVisit.cpp
vendored
@@ -1237,6 +1237,7 @@ void LambdaCaptureAST::accept0(ASTVisitor *visitor)
|
|||||||
void CaptureAST::accept0(ASTVisitor *visitor)
|
void CaptureAST::accept0(ASTVisitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
|
accept(identifier, visitor);
|
||||||
}
|
}
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|||||||
2
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
2
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -1069,7 +1069,7 @@ void Bind::capture(CaptureAST *ast)
|
|||||||
if (! ast)
|
if (! ast)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// See QTCREATORBUG-7968
|
name(ast->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bind::visit(LambdaDeclaratorAST *ast)
|
bool Bind::visit(LambdaDeclaratorAST *ast)
|
||||||
|
|||||||
43
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
43
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -6294,43 +6294,56 @@ bool Parser::parseLambdaCapture(LambdaCaptureAST *&node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parseCapture(CaptureAST *&)
|
bool Parser::parseCapture(CaptureAST *&node)
|
||||||
{
|
{
|
||||||
// See QTCREATORBUG-7968
|
|
||||||
|
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|
||||||
|
if (LA() == T_THIS) {
|
||||||
|
consumeToken();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LA() == T_AMPER)
|
||||||
|
consumeToken();
|
||||||
|
|
||||||
if (LA() == T_IDENTIFIER) {
|
if (LA() == T_IDENTIFIER) {
|
||||||
consumeToken();
|
SimpleNameAST *ast = new (_pool) SimpleNameAST;
|
||||||
return true;
|
ast->identifier_token = consumeToken();
|
||||||
|
|
||||||
} else if (LA() == T_AMPER && LA(2) == T_IDENTIFIER) {
|
node = new (_pool) CaptureAST;
|
||||||
consumeToken();
|
node->identifier = ast;
|
||||||
consumeToken();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} else if (LA() == T_THIS) {
|
|
||||||
consumeToken();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parseCaptureList(CaptureListAST *&)
|
bool Parser::parseCaptureList(CaptureListAST *&node)
|
||||||
{
|
{
|
||||||
DEBUG_THIS_RULE();
|
DEBUG_THIS_RULE();
|
||||||
|
|
||||||
CaptureAST *capture = 0;
|
CaptureAST *capture = 0;
|
||||||
|
|
||||||
if (parseCapture(capture)) {
|
if (parseCapture(capture)) {
|
||||||
|
node = new (_pool) CaptureListAST;
|
||||||
|
node->value = capture;
|
||||||
|
|
||||||
|
CaptureListAST **l = &node->next;
|
||||||
while (LA() == T_COMMA) {
|
while (LA() == T_COMMA) {
|
||||||
consumeToken(); // consume `,'
|
consumeToken(); // consume `,'
|
||||||
|
CaptureAST *capture = 0;
|
||||||
parseCapture(capture);
|
parseCapture(capture);
|
||||||
|
if (capture) {
|
||||||
|
*l = new (_pool) CaptureListAST;
|
||||||
|
(*l)->value = capture;
|
||||||
|
l = &(*l)->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node)
|
bool Parser::parseLambdaDeclarator(LambdaDeclaratorAST *&node)
|
||||||
|
|||||||
@@ -869,7 +869,7 @@ void FindUsages::capture(CaptureAST *ast)
|
|||||||
if (! ast)
|
if (! ast)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// See QTCREATORBUG-7968
|
this->name(ast->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FindUsages::visit(LambdaDeclaratorAST *ast)
|
bool FindUsages::visit(LambdaDeclaratorAST *ast)
|
||||||
|
|||||||
@@ -127,6 +127,11 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool visit(CaptureAST *ast)
|
||||||
|
{
|
||||||
|
return checkLocalUse(ast->identifier, ast->firstToken());
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool visit(IdExpressionAST *ast)
|
virtual bool visit(IdExpressionAST *ast)
|
||||||
{
|
{
|
||||||
return checkLocalUse(ast->name, ast->firstToken());
|
return checkLocalUse(ast->name, ast->firstToken());
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ class tst_FindUsages: public QObject
|
|||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void inlineMethod();
|
void inlineMethod();
|
||||||
// void lambdaArg();
|
void lambdaCaptureByValue();
|
||||||
|
void lambdaCaptureByReference();
|
||||||
|
|
||||||
// Qt keywords
|
// Qt keywords
|
||||||
void qproperty_1();
|
void qproperty_1();
|
||||||
@@ -124,15 +125,46 @@ void tst_FindUsages::inlineMethod()
|
|||||||
QCOMPARE(findUsages.references().size(), 2);
|
QCOMPARE(findUsages.references().size(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* see QTCREATORBUG-7968 */
|
void tst_FindUsages::lambdaCaptureByValue()
|
||||||
void tst_FindUsages::lambdaArg()
|
|
||||||
{
|
{
|
||||||
const QByteArray src = "\n"
|
const QByteArray src = "\n"
|
||||||
"void f() {\n"
|
"void f() {\n"
|
||||||
" int test;\n"
|
" int test;\n"
|
||||||
" [test] { ++test; };\n"
|
" [test] { ++test; };\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
Document::Ptr doc = Document::create("lambdaArg");
|
Document::Ptr doc = Document::create("lambdaCaptureByValue");
|
||||||
|
doc->setUtf8Source(src);
|
||||||
|
doc->parse();
|
||||||
|
doc->check();
|
||||||
|
|
||||||
|
QVERIFY(doc->diagnosticMessages().isEmpty());
|
||||||
|
QCOMPARE(doc->globalSymbolCount(), 1U);
|
||||||
|
|
||||||
|
Snapshot snapshot;
|
||||||
|
snapshot.insert(doc);
|
||||||
|
|
||||||
|
Function *f = doc->globalSymbolAt(0)->asFunction();
|
||||||
|
QVERIFY(f);
|
||||||
|
QCOMPARE(f->memberCount(), 1U);
|
||||||
|
Block *b = f->memberAt(0)->asBlock();
|
||||||
|
QCOMPARE(b->memberCount(), 2U);
|
||||||
|
Declaration *d = b->memberAt(0)->asDeclaration();
|
||||||
|
QVERIFY(d);
|
||||||
|
QCOMPARE(d->name()->identifier()->chars(), "test");
|
||||||
|
|
||||||
|
FindUsages findUsages(src, doc, snapshot);
|
||||||
|
findUsages(d);
|
||||||
|
QCOMPARE(findUsages.usages().size(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_FindUsages::lambdaCaptureByReference()
|
||||||
|
{
|
||||||
|
const QByteArray src = "\n"
|
||||||
|
"void f() {\n"
|
||||||
|
" int test;\n"
|
||||||
|
" [&test] { ++test; };\n"
|
||||||
|
"}\n";
|
||||||
|
Document::Ptr doc = Document::create("lambdaCaptureByReference");
|
||||||
doc->setUtf8Source(src);
|
doc->setUtf8Source(src);
|
||||||
doc->parse();
|
doc->parse();
|
||||||
doc->check();
|
doc->check();
|
||||||
@@ -156,7 +188,6 @@ void tst_FindUsages::lambdaArg()
|
|||||||
findUsages(d);
|
findUsages(d);
|
||||||
QCOMPARE(findUsages.usages().size(), 3);
|
QCOMPARE(findUsages.usages().size(), 3);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@interface Clazz {} +(void)method:(int)arg; @end
|
@interface Clazz {} +(void)method:(int)arg; @end
|
||||||
|
|||||||
@@ -1645,6 +1645,9 @@ virtual bool visit(LambdaCaptureAST *ast)
|
|||||||
|
|
||||||
virtual bool visit(CaptureAST *ast)
|
virtual bool visit(CaptureAST *ast)
|
||||||
{
|
{
|
||||||
|
if (ast->amper_token)
|
||||||
|
terminal(ast->amper_token, ast);
|
||||||
|
nonterminal(ast->identifier);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user