Dom : simplify ScriptExpression a bit

this commit removes dead code. Some of the things were there, but never
used. For example, wrapping script expression into object defitinion,
however there is no reason/usages for that. Most of the complexity in
ScriptExpression::setCode was coming from it.

Change-Id: I1e1653a3f052fb138e4ab31cf3c9b375e90842bb
Task-number: QTBUG-121933
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
Dmitrii Akshintsev 2025-08-27 23:31:58 +02:00
parent 663ff3cb00
commit 288e03a84d
2 changed files with 37 additions and 106 deletions

View File

@ -1619,9 +1619,8 @@ void BindingValue::clearValue()
ScriptExpression::ScriptExpression(QStringView code, const std::shared_ptr<QQmlJS::Engine> &engine,
AST::Node *ast, const std::shared_ptr<AstComments> &comments,
ExpressionType expressionType, SourceLocation localOffset,
int derivedFrom)
: OwningItem(derivedFrom),
ExpressionType expressionType, SourceLocation localOffset)
: OwningItem(),
m_expressionType(expressionType),
m_code(code),
m_engine(engine),
@ -1651,16 +1650,6 @@ ScriptExpression::ScriptExpression(const ScriptExpression &e) : OwningItem(e)
m_astComments = e.m_astComments;
}
// TODO can be deleted atm used only in MutableItem setCode (which is unused atm)
std::shared_ptr<ScriptExpression> ScriptExpression::copyWithUpdatedCode(
const DomItem &self, const QString &code) const
{
std::shared_ptr<ScriptExpression> copy = makeCopy(self);
DomItem container = self.containingObject();
copy->setCode(code);
return copy;
}
bool ScriptExpression::iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
{
bool cont = OwningItem::iterateDirectSubpaths(self, visitor);
@ -1713,35 +1702,23 @@ AST::Node *firstNodeInRange(AST::Node *n, qsizetype minStart = 0, qsizetype maxE
void ScriptExpression::setCode(const QString &code)
{
// TODO QTBUG-121933
m_codeStr = code;
QString resolvedPreCode, resolvedPostCode;
if (m_expressionType == ExpressionType::BindingExpression) {
resolvedPreCode = Binding::preCodeForName(u"binding");
resolvedPostCode = Binding::postCodeForName(u"binding");
if (code.isEmpty()) {
return;
}
if (!resolvedPreCode.isEmpty() || !resolvedPostCode.isEmpty())
m_codeStr = resolvedPreCode + code + resolvedPostCode;
m_code = QStringView(m_codeStr).mid(resolvedPreCode.size(), code.size());
auto preCode = QStringView(m_codeStr).mid(0, resolvedPreCode.size());
m_codeStr = code;
m_code = QStringView(m_codeStr);
m_engine = nullptr;
m_ast = nullptr;
m_localOffset = SourceLocation();
if (!m_code.isEmpty()) {
IndentInfo preChange(preCode, 4);
m_localOffset.offset = preCode.size();
m_localOffset.length = m_code.size();
m_localOffset.startColumn = preChange.trailingString.size();
m_localOffset.startLine = preChange.nNewlines;
m_engine = std::make_shared<QQmlJS::Engine>();
m_astComments = std::make_shared<AstComments>(m_engine);
m_ast = parse(resolveParseMode());
m_ast = parse();
if (AST::Program *programPtr = AST::cast<AST::Program *>(m_ast)) {
m_ast = programPtr->statements;
}
if (!preCode.isEmpty())
m_ast = firstNodeInRange(m_ast, preCode.size(), preCode.size() + m_code.size());
if (auto *sList = AST::cast<AST::FormalParameterList *>(m_ast)) {
m_ast = sList->element;
}
@ -1757,26 +1734,15 @@ void ScriptExpression::setCode(const QString &code)
CommentCollector collector;
collector.collectComments(m_engine, m_ast, m_astComments);
}
}
AST::Node *ScriptExpression::parse(const ParseMode mode)
AST::Node *ScriptExpression::parse()
{
QQmlJS::Lexer lexer(m_engine.get());
lexer.setCode(m_codeStr, /*lineno = */ 1, /*qmlMode=*/mode == ParseMode::QML);
lexer.setCode(m_codeStr, /*lineno = */ 1, /*qmlMode=*/false /* it's EcmaScript */);
QQmlJS::Parser parser(m_engine.get());
const bool parserSucceeded = [mode, &parser]() {
switch (mode) {
case ParseMode::QML:
return parser.parse();
case ParseMode::JS:
return parser.parseScript();
case ParseMode::ESM:
return parser.parseModule();
default:
Q_UNREACHABLE_RETURN(false);
}
}();
const bool parserSucceeded = m_expressionType == ExpressionType::ESMCode ? parser.parseModule()
: parser.parseScript();
if (!parserSucceeded) {
addErrorLocal(domParsingErrors().error(tr("Parsing of code failed")));
}

View File

@ -407,18 +407,17 @@ public:
explicit ScriptExpression(QStringView code, const std::shared_ptr<QQmlJS::Engine> &engine,
AST::Node *ast, const std::shared_ptr<AstComments> &comments,
ExpressionType expressionType,
SourceLocation localOffset = SourceLocation(), int derivedFrom = 0);
SourceLocation localOffset = SourceLocation());
ScriptExpression()
: ScriptExpression(QStringView(), std::shared_ptr<QQmlJS::Engine>(), nullptr,
std::shared_ptr<AstComments>(), ExpressionType::BindingExpression,
SourceLocation(), 0)
SourceLocation())
{
}
explicit ScriptExpression(const QString &code, ExpressionType expressionType,
int derivedFrom = 0)
: OwningItem(derivedFrom), m_expressionType(expressionType)
explicit ScriptExpression(const QString &code, ExpressionType expressionType)
: OwningItem(), m_expressionType(expressionType)
{
setCode(code);
}
@ -430,10 +429,6 @@ public:
return std::static_pointer_cast<ScriptExpression>(doCopy(self));
}
// TODO can be deleted atm used only in MutableItem setCode (which is unused atm)
std::shared_ptr<ScriptExpression> copyWithUpdatedCode(const DomItem &self,
const QString &code) const;
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override;
Path canonicalPath(const DomItem &self) const override { return self.m_ownerPath; }
@ -481,18 +476,6 @@ protected:
return std::make_shared<ScriptExpression>(*this);
}
std::function<SourceLocation(SourceLocation)> locationToGlobalF(const DomItem &self) const
{
SourceLocation loc = globalLocation(self);
return [loc, this](SourceLocation x) {
return SourceLocation(x.offset - m_localOffset.offset + loc.offset, x.length,
x.startLine - m_localOffset.startLine + loc.startLine,
((x.startLine == m_localOffset.startLine) ? x.startColumn
- m_localOffset.startColumn + loc.startColumn
: x.startColumn));
};
}
SourceLocation locationToLocal(SourceLocation x) const
{
return SourceLocation(
@ -502,11 +485,6 @@ protected:
: x.startColumn)); // are line and column 1 based? then we should + 1
}
std::function<SourceLocation(SourceLocation)> locationToLocalF(const DomItem &) const
{
return [this](SourceLocation x) { return locationToLocal(x); };
}
private:
enum class ParseMode {
QML,
@ -514,21 +492,8 @@ private:
ESM, // ECMAScript module
};
inline ParseMode resolveParseMode()
{
switch (m_expressionType) {
case ExpressionType::BindingExpression:
// unfortunately there are no documentation explaining this resolution
// this was just moved from the original implementation
return ParseMode::QML;
case ExpressionType::ESMCode:
return ParseMode::ESM;
default:
return ParseMode::JS;
}
}
void setCode(const QString &code);
[[nodiscard]] AST::Node *parse(ParseMode mode);
[[nodiscard]] AST::Node *parse();
ExpressionType m_expressionType;
QString m_codeStr;