qmljs: correctly handle js string templates

In most cases we do want to visit the expressions in a function
template. Changing its accept0 would force those not wanting to visit
it to iterate on the templates (currently a linked list), so we add a
visit method explicitly visiting the expression in all the needed
places.

Fixes: QTCREATORBUG-21869
Change-Id: I47733544bfd32eec357810b97242608b8f7de572
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
Fawzi Mohamed
2021-12-06 09:44:24 +01:00
parent 9d1fe1df14
commit 6b270b8dc9
19 changed files with 99 additions and 0 deletions

View File

@@ -84,6 +84,12 @@ void JsonCheck::postVisit(Node *)
analysis()->m_ranking += previous.m_ranking; analysis()->m_ranking += previous.m_ranking;
} }
bool JsonCheck::visit(AST::TemplateLiteral *ast)
{
Node::accept(ast->expression, this);
return true;
}
bool JsonCheck::visit(ObjectPattern *ast) bool JsonCheck::visit(ObjectPattern *ast)
{ {
if (!proceedCheck(JsonValue::Object, ast->lbraceToken)) if (!proceedCheck(JsonValue::Object, ast->lbraceToken))

View File

@@ -51,6 +51,7 @@ private:
bool preVisit(AST::Node *) override; bool preVisit(AST::Node *) override;
void postVisit(AST::Node *) override; void postVisit(AST::Node *) override;
bool visit(AST::TemplateLiteral *ast) override;
bool visit(AST::ObjectPattern *ast) override; bool visit(AST::ObjectPattern *ast) override;
bool visit(AST::ArrayPattern *ast) override; bool visit(AST::ArrayPattern *ast) override;
bool visit(AST::NullExpression *ast) override; bool visit(AST::NullExpression *ast) override;

View File

@@ -350,6 +350,12 @@ bool Bind::visit(UiInlineComponent *ast)
return true; return true;
} }
bool Bind::visit(AST::TemplateLiteral *ast)
{
Node::accept(ast->expression, this);
return true;
}
bool Bind::visit(PatternElement *ast) bool Bind::visit(PatternElement *ast)
{ {
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration()) if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())

View File

@@ -82,6 +82,7 @@ protected:
bool visit(AST::UiInlineComponent *ast) override; bool visit(AST::UiInlineComponent *ast) override;
// QML/JS // QML/JS
bool visit(AST::TemplateLiteral *ast) override;
bool visit(AST::FunctionDeclaration *ast) override; bool visit(AST::FunctionDeclaration *ast) override;
bool visit(AST::FunctionExpression *ast) override; bool visit(AST::FunctionExpression *ast) override;
bool visit(AST::PatternElement *ast) override; bool visit(AST::PatternElement *ast) override;

View File

@@ -808,6 +808,12 @@ bool Check::visit(UiObjectInitializer *)
return true; return true;
} }
bool Check::visit(AST::TemplateLiteral *ast)
{
Node::accept(ast->expression, this);
return true;
}
void Check::endVisit(UiObjectInitializer *uiObjectInitializer) void Check::endVisit(UiObjectInitializer *uiObjectInitializer)
{ {
Q_UNUSED(uiObjectInitializer) Q_UNUSED(uiObjectInitializer)

View File

@@ -77,6 +77,7 @@ protected:
bool visit(AST::FunctionExpression *ast) override; bool visit(AST::FunctionExpression *ast) override;
bool visit(AST::UiObjectInitializer *) override; bool visit(AST::UiObjectInitializer *) override;
bool visit(AST::TemplateLiteral *ast) override;
bool visit(AST::BinaryExpression *ast) override; bool visit(AST::BinaryExpression *ast) override;
bool visit(AST::Block *ast) override; bool visit(AST::Block *ast) override;
bool visit(AST::WithStatement *ast) override; bool visit(AST::WithStatement *ast) override;

View File

@@ -211,6 +211,12 @@ bool Evaluate::visit(AST::UiQualifiedId *ast)
return false; return false;
} }
bool Evaluate::visit(AST::TemplateLiteral *ast)
{
_result = _valueOwner->stringValue();
return false;
}
bool Evaluate::visit(AST::ThisExpression *) bool Evaluate::visit(AST::ThisExpression *)
{ {
return false; return false;

View File

@@ -75,6 +75,7 @@ protected:
bool visit(AST::UiQualifiedId *ast) override; bool visit(AST::UiQualifiedId *ast) override;
// QmlJS // QmlJS
bool visit(AST::TemplateLiteral *ast) override;
bool visit(AST::ThisExpression *ast) override; bool visit(AST::ThisExpression *ast) override;
bool visit(AST::IdentifierExpression *ast) override; bool visit(AST::IdentifierExpression *ast) override;
bool visit(AST::NullExpression *ast) override; bool visit(AST::NullExpression *ast) override;

View File

@@ -61,6 +61,12 @@ bool ScopeAstPath::preVisit(Node *node)
return true; return true;
} }
bool ScopeAstPath::visit(AST::TemplateLiteral *node)
{
Node::accept(node->expression, this);
return true;
}
bool ScopeAstPath::visit(UiPublicMember *node) bool ScopeAstPath::visit(UiPublicMember *node)
{ {
if (node && node->statement && node->statement->kind == node->Kind_Block if (node && node->statement && node->statement->kind == node->Kind_Block

View File

@@ -44,6 +44,7 @@ protected:
using Visitor::visit; using Visitor::visit;
bool preVisit(AST::Node *node) override; bool preVisit(AST::Node *node) override;
bool visit(AST::TemplateLiteral *node) override;
bool visit(AST::UiPublicMember *node) override; bool visit(AST::UiPublicMember *node) override;
bool visit(AST::UiScriptBinding *node) override; bool visit(AST::UiScriptBinding *node) override;
bool visit(AST::UiObjectDefinition *node) override; bool visit(AST::UiObjectDefinition *node) override;

View File

@@ -158,6 +158,11 @@ public:
return true; return true;
} }
bool visit(TemplateLiteral *ast) override
{
Node::accept(ast->expression, this);
return true;
}
bool visit(VariableStatement *ast) override { test(ast); return true; } bool visit(VariableStatement *ast) override { test(ast); return true; }
bool visit(VariableDeclarationList *ast) override { test(ast); return true; } bool visit(VariableDeclarationList *ast) override { test(ast); return true; }
bool visit(ExpressionStatement *ast) override { test(ast); return true; } bool visit(ExpressionStatement *ast) override { test(ast); return true; }

View File

@@ -31,6 +31,14 @@ ConnectionVisitor::ConnectionVisitor()
{ {
} }
bool ConnectionVisitor::visit(QmlJS::AST::TemplateLiteral *ast)
{
m_expression.append(
qMakePair(QmlJS::AST::Node::Kind::Kind_StringLiteral, ast->value.toString()));
QmlJS::AST::Node::accept(ast->expression, this);
return true;
}
bool ConnectionVisitor::visit(QmlJS::AST::StringLiteral *ast) bool ConnectionVisitor::visit(QmlJS::AST::StringLiteral *ast)
{ {
m_expression.append(qMakePair(QmlJS::AST::Node::Kind::Kind_StringLiteral, m_expression.append(qMakePair(QmlJS::AST::Node::Kind::Kind_StringLiteral,

View File

@@ -37,6 +37,7 @@ class ConnectionVisitor : public QmlJS::AST::Visitor
public: public:
explicit ConnectionVisitor(); explicit ConnectionVisitor();
bool visit(QmlJS::AST::TemplateLiteral *ast) override;
bool visit(QmlJS::AST::StringLiteral *ast) override; bool visit(QmlJS::AST::StringLiteral *ast) override;
bool visit(QmlJS::AST::NumericLiteral *ast) override; bool visit(QmlJS::AST::NumericLiteral *ast) override;
bool visit(QmlJS::AST::TrueLiteral *ast) override; bool visit(QmlJS::AST::TrueLiteral *ast) override;

View File

@@ -148,6 +148,12 @@ protected:
return true; return true;
} }
bool visit(AST::TemplateLiteral *node) override
{
AST::Node::accept(node->expression, this);
return true;
}
bool visit(AST::IdentifierExpression *node) override bool visit(AST::IdentifierExpression *node) override
{ {
if (node->name != m_typeName) if (node->name != m_typeName)

View File

@@ -99,6 +99,12 @@ bool FirstDefinitionFinder::visit(QmlJS::AST::UiObjectDefinition *ast)
return true; return true;
} }
bool FirstDefinitionFinder::visit(QmlJS::AST::TemplateLiteral *ast)
{
QmlJS::AST::Node::accept(ast->expression, this);
return true;
}
void FirstDefinitionFinder::throwRecursionDepthError() void FirstDefinitionFinder::throwRecursionDepthError()
{ {
qWarning("Warning: Hit maximum recursion depth while visiting the AST in FirstDefinitionFinder"); qWarning("Warning: Hit maximum recursion depth while visiting the AST in FirstDefinitionFinder");

View File

@@ -42,6 +42,7 @@ protected:
bool visit(QmlJS::AST::UiObjectBinding *ast) override; bool visit(QmlJS::AST::UiObjectBinding *ast) override;
bool visit(QmlJS::AST::UiObjectDefinition *ast) override; bool visit(QmlJS::AST::UiObjectDefinition *ast) override;
bool visit(QmlJS::AST::TemplateLiteral *ast) override;
void throwRecursionDepthError() override; void throwRecursionDepthError() override;

View File

@@ -279,6 +279,13 @@ protected:
--_depth; --_depth;
} }
bool visit(AST::TemplateLiteral *ast) override
{
// avoid? finds function declarations in templates
AST::Node::accept(ast->expression, this);
return true;
}
bool visit(AST::FunctionExpression *) override bool visit(AST::FunctionExpression *) override
{ {
return false; return false;
@@ -398,6 +405,12 @@ protected:
return true; return true;
} }
bool visit(AST::TemplateLiteral *ast) override
{
AST::Node::accept(ast->expression, this);
return true;
}
bool visit(AST::FunctionDeclaration *ast) override bool visit(AST::FunctionDeclaration *ast) override
{ {
_ranges.append(createRange(ast)); _ranges.append(createRange(ast));

View File

@@ -118,6 +118,12 @@ protected:
return false; return false;
} }
bool visit(AST::TemplateLiteral *el) override
{
Node::accept(el->expression, this);
return true;
}
bool visit(AST::UiObjectBinding *node) override bool visit(AST::UiObjectBinding *node) override
{ {
if (node->qualifiedId if (node->qualifiedId
@@ -398,6 +404,12 @@ protected:
return true; return true;
} }
bool visit(AST::TemplateLiteral *el) override
{
Node::accept(el->expression, this);
return true;
}
bool visit(AST::FunctionDeclaration *node) override bool visit(AST::FunctionDeclaration *node) override
{ {
return visit(static_cast<FunctionExpression *>(node)); return visit(static_cast<FunctionExpression *>(node));
@@ -557,6 +569,12 @@ protected:
return true; return true;
} }
bool visit(AST::TemplateLiteral *el) override
{
Node::accept(el->expression, this);
return true;
}
bool visit(UiScriptBinding *node) override bool visit(UiScriptBinding *node) override
{ {
return !checkBindingName(node->qualifiedId); return !checkBindingName(node->qualifiedId);

View File

@@ -127,6 +127,12 @@ protected:
return handleLocationAst(ast); return handleLocationAst(ast);
} }
bool visit(AST::TemplateLiteral *ast) override
{
AST::Node::accept(ast->expression, this);
return true;
}
void throwRecursionDepthError() override void throwRecursionDepthError() override
{ {
qWarning("Warning: Hit maximum recursion depth when visiting the AST in AstPath"); qWarning("Warning: Hit maximum recursion depth when visiting the AST in AstPath");