diff --git a/src/plugins/autotest/quick/quicktestvisitors.cpp b/src/plugins/autotest/quick/quicktestvisitors.cpp index 39e0a5befc5..9e4752821be 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.cpp +++ b/src/plugins/autotest/quick/quicktestvisitors.cpp @@ -84,7 +84,9 @@ static bool isDerivedFromTestCase(QmlJS::AST::UiQualifiedId *id, const QmlJS::Do bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) { const QStringRef name = ast->qualifiedTypeNameId->name; + m_objectStack.push(name.toString()); if (name != "TestCase") { + m_insideTestCase = false; if (!isDerivedFromTestCase(ast->qualifiedTypeNameId, m_currentDoc, m_snapshot)) return true; } else if (!documentImportsQtTest(m_currentDoc.data())) { @@ -92,6 +94,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) } m_typeIsTestCase = true; + m_insideTestCase = true; m_currentTestCaseName.clear(); const auto sourceLocation = ast->firstSourceLocation(); m_testCaseLocation.m_name = m_currentDoc->fileName(); @@ -101,6 +104,11 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast) return true; } +void TestQmlVisitor::endVisit(QmlJS::AST::UiObjectDefinition *) +{ + m_insideTestCase = m_objectStack.pop() == "TestCase"; +} + bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast) { const QmlJS::AST::ExpressionNode *expr = ast->expression; @@ -109,8 +117,15 @@ bool TestQmlVisitor::visit(QmlJS::AST::ExpressionStatement *ast) bool TestQmlVisitor::visit(QmlJS::AST::UiScriptBinding *ast) { - const QStringRef name = ast->qualifiedId->name; - return name == "name"; + if (m_insideTestCase) + m_expectTestCaseName = ast->qualifiedId->name == "name"; + return m_expectTestCaseName; +} + +void TestQmlVisitor::endVisit(QmlJS::AST::UiScriptBinding *) +{ + if (m_expectTestCaseName) + m_expectTestCaseName = false; } bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast) @@ -139,8 +154,10 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast) bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast) { - if (m_typeIsTestCase) + if (m_expectTestCaseName && m_currentTestCaseName.isEmpty()) { m_currentTestCaseName = ast->value.toString(); + m_expectTestCaseName = false; + } return false; } diff --git a/src/plugins/autotest/quick/quicktestvisitors.h b/src/plugins/autotest/quick/quicktestvisitors.h index 927b3322b0e..f131339475d 100644 --- a/src/plugins/autotest/quick/quicktestvisitors.h +++ b/src/plugins/autotest/quick/quicktestvisitors.h @@ -30,6 +30,8 @@ #include #include +#include + namespace Autotest { namespace Internal { @@ -38,11 +40,13 @@ class TestQmlVisitor : public QmlJS::AST::Visitor public: explicit TestQmlVisitor(QmlJS::Document::Ptr doc, const QmlJS::Snapshot &snapshot); - bool visit(QmlJS::AST::UiObjectDefinition *ast); - bool visit(QmlJS::AST::ExpressionStatement *ast); - bool visit(QmlJS::AST::UiScriptBinding *ast); - bool visit(QmlJS::AST::FunctionDeclaration *ast); - bool visit(QmlJS::AST::StringLiteral *ast); + bool visit(QmlJS::AST::UiObjectDefinition *ast) override; + void endVisit(QmlJS::AST::UiObjectDefinition *ast) override; + bool visit(QmlJS::AST::ExpressionStatement *ast) override; + bool visit(QmlJS::AST::UiScriptBinding *ast) override; + void endVisit(QmlJS::AST::UiScriptBinding *ast) override; + bool visit(QmlJS::AST::FunctionDeclaration *ast) override; + bool visit(QmlJS::AST::StringLiteral *ast) override; QString testCaseName() const { return m_currentTestCaseName; } TestCodeLocationAndType testCaseLocation() const { return m_testCaseLocation; } @@ -55,7 +59,10 @@ private: QString m_currentTestCaseName; TestCodeLocationAndType m_testCaseLocation; QMap m_testFunctions; + QStack m_objectStack; bool m_typeIsTestCase = false; + bool m_insideTestCase = false; + bool m_expectTestCaseName = false; }; } // namespace Internal