aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristiaan Janssen <christiaan.janssen@qt.io>2021-09-27 15:28:36 +0200
committerChristiaan Janssen <christiaan.janssen@qt.io>2021-09-30 06:19:46 +0000
commit525039daebe783560d2ba7f12db573f25d745852 (patch)
treee858c756fcff37f00905cf6a38d8080049edde43
parent3ad9c6497798adeac883495014f7afd83ec2aa04 (diff)
QmlProject: port changes from QtForMcus
Task-number: QTCREATORBUG-26041 Change-Id: I5068381fb2c4c901d8621e0b8358db77d2cb0b21 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/libs/qmljs/qmljssimplereader.cpp495
-rw-r--r--src/libs/qmljs/qmljssimplereader.h63
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp10
-rw-r--r--src/plugins/qmldesigner/designercore/include/metainforeader.h7
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp7
-rw-r--r--src/plugins/qmldesigner/designercore/model/rewriterview.cpp4
-rw-r--r--src/plugins/qmldesigner/designermcumanager.cpp41
-rw-r--r--src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp60
-rw-r--r--tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp4
-rw-r--r--tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp16
10 files changed, 394 insertions, 313 deletions
diff --git a/src/libs/qmljs/qmljssimplereader.cpp b/src/libs/qmljs/qmljssimplereader.cpp
index d0d43b4098..92d0761656 100644
--- a/src/libs/qmljs/qmljssimplereader.cpp
+++ b/src/libs/qmljs/qmljssimplereader.cpp
@@ -25,9 +25,15 @@
#include "qmljssimplereader.h"
-#include "parser/qmljsparser_p.h"
-#include "parser/qmljslexer_p.h"
+#ifdef QT_CREATOR
#include "parser/qmljsengine_p.h"
+#include "parser/qmljslexer_p.h"
+#include "parser/qmljsparser_p.h"
+#else
+#include "parser/qqmljsengine_p.h"
+#include "parser/qqmljslexer_p.h"
+#include "qqmljsparser_p.h"
+#endif
#include "qmljsutils.h"
@@ -37,308 +43,331 @@
static Q_LOGGING_CATEGORY(simpleReaderLog, "qtc.qmljs.simpleReader", QtWarningMsg)
-namespace QmlJS{
-
-QVariant SimpleReaderNode::property(const QString &name) const
+ namespace QmlJS
{
- return m_properties.value(name);
-}
+#ifdef QT_CREATOR
+ using UiQualifiedId = QmlJS::AST::UiQualifiedId;
+#else
+ using UiQualifiedId = QQmlJS::AST::UiQualifiedId;
+#endif
-QStringList SimpleReaderNode::propertyNames() const
-{
- return m_properties.keys();
-}
+ static SourceLocation toSourceLocation(SourceLocation first, SourceLocation last)
+ {
+ first.length = last.end() - first.begin();
+ return first;
+ }
-SimpleReaderNode::PropertyHash SimpleReaderNode::properties() const
-{
- return m_properties;
-}
+ static SourceLocation toSourceLocation(UiQualifiedId * qualifiedId)
+ {
+ SourceLocation first = qualifiedId->firstSourceLocation();
+ SourceLocation last;
+ for (UiQualifiedId *iter = qualifiedId; iter; iter = iter->next) {
+ if (iter->lastSourceLocation().isValid())
+ last = iter->lastSourceLocation();
+ }
+ return toSourceLocation(first, last);
+ }
-bool SimpleReaderNode::isRoot() const
-{
- return m_parentNode.isNull();
-}
+ SimpleReaderNode::Property SimpleReaderNode::property(const QString &name) const
+ {
+ return m_properties.value(name);
+ }
-bool SimpleReaderNode::isValid() const
-{
- return !m_name.isEmpty();
-}
+ QStringList SimpleReaderNode::propertyNames() const { return m_properties.keys(); }
-SimpleReaderNode::Ptr SimpleReaderNode::invalidNode()
-{
- return Ptr(new SimpleReaderNode);
-}
+ SimpleReaderNode::PropertyHash SimpleReaderNode::properties() const { return m_properties; }
-SimpleReaderNode::WeakPtr SimpleReaderNode::parent() const
-{
- return m_parentNode;
-}
+ bool SimpleReaderNode::isRoot() const { return m_parentNode.isNull(); }
-QString SimpleReaderNode::name() const
-{
- return m_name;
-}
+ bool SimpleReaderNode::isValid() const { return !m_name.isEmpty(); }
-SimpleReaderNode::SimpleReaderNode()
-{
-}
+ SimpleReaderNode::Ptr SimpleReaderNode::invalidNode() { return Ptr(new SimpleReaderNode); }
-SimpleReaderNode::SimpleReaderNode(const QString &name, WeakPtr parent)
- : m_name(name), m_parentNode(parent)
-{
-}
+ SimpleReaderNode::WeakPtr SimpleReaderNode::parent() const { return m_parentNode; }
-SimpleReaderNode::Ptr SimpleReaderNode::create(const QString &name, WeakPtr parent)
-{
- Ptr newNode(new SimpleReaderNode(name, parent));
- newNode->m_weakThis = newNode;
- if (parent)
- parent.toStrongRef().data()->m_children.append(newNode);
- return newNode;
-}
-
-const SimpleReaderNode::List SimpleReaderNode::children() const
-{
- return m_children;
-}
+ QString SimpleReaderNode::name() const { return m_name; }
-void SimpleReaderNode::setProperty(const QString &name, const QVariant &value)
-{
- m_properties.insert(name, value);
-}
+ SourceLocation SimpleReaderNode::nameLocation() const { return m_nameLocation; }
-SimpleAbstractStreamReader::SimpleAbstractStreamReader()
-{
-}
+ SimpleReaderNode::SimpleReaderNode() {}
-bool SimpleAbstractStreamReader::readFile(const QString &fileName)
-{
- QFile file(fileName);
- if (file.open(QIODevice::ReadOnly)) {
- QByteArray source = file.readAll();
- file.close();
- return readFromSource(QString::fromLocal8Bit(source));
+ SimpleReaderNode::SimpleReaderNode(const QString &name,
+ const SourceLocation &nameLocation,
+ WeakPtr parent)
+ : m_name(name)
+ , m_nameLocation(nameLocation)
+ , m_parentNode(parent)
+ {}
+
+ SimpleReaderNode::Ptr SimpleReaderNode::create(const QString &name,
+ const SourceLocation &nameLocation,
+ WeakPtr parent)
+ {
+ Ptr newNode(new SimpleReaderNode(name, nameLocation, parent));
+ newNode->m_weakThis = newNode;
+ if (parent)
+ parent.toStrongRef().data()->m_children.append(newNode);
+ return newNode;
}
- addError(tr("Cannot find file %1.").arg(fileName));
- return false;
-}
-bool SimpleAbstractStreamReader::readFromSource(const QString &source)
-{
- m_errors.clear();
- m_currentSourceLocation = SourceLocation();
+ const SimpleReaderNode::List SimpleReaderNode::children() const { return m_children; }
- m_source = source;
+ void SimpleReaderNode::setProperty(const QString &name,
+ const SourceLocation &nameLocation,
+ const QVariant &value,
+ const SourceLocation &valueLocation)
+ {
+ m_properties.insert(name, {value, nameLocation, valueLocation});
+ }
- Engine engine;
- Lexer lexer(&engine);
- Parser parser(&engine);
+ SimpleAbstractStreamReader::SimpleAbstractStreamReader() {}
- lexer.setCode(source, /*line = */ 1, /*qmlMode = */true);
+ SimpleAbstractStreamReader::~SimpleAbstractStreamReader() {}
- if (!parser.parse()) {
- QString errorMessage = QString::fromLatin1("%1:%2: %3").arg(
- QString::number(parser.errorLineNumber()),
- QString::number(parser.errorColumnNumber()),
- parser.errorMessage());
- addError(errorMessage);
+ bool SimpleAbstractStreamReader::readFile(const QString &fileName)
+ {
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ QByteArray source = file.readAll();
+ file.close();
+ return readFromSource(QString::fromLocal8Bit(source));
+ }
+ addError(tr("Cannot find file %1.").arg(fileName));
return false;
}
- return readDocument(parser.ast());
-}
-QStringList SimpleAbstractStreamReader::errors() const
-{
- return m_errors;
-}
+ bool SimpleAbstractStreamReader::readFromSource(const QString &source)
+ {
+ m_errors.clear();
+ m_currentSourceLocation = SourceLocation();
-void SimpleAbstractStreamReader::addError(const QString &error, const SourceLocation &sourceLocation)
-{
- m_errors << QString::fromLatin1("%1:%2: %3\n").arg(
- QString::number(sourceLocation.startLine),
- QString::number(sourceLocation.startColumn),
- error);
-}
+ m_source = source;
-SourceLocation SimpleAbstractStreamReader::currentSourceLocation() const
-{
- return m_currentSourceLocation;
-}
+ Engine engine;
+ Lexer lexer(&engine);
+ Parser parser(&engine);
-bool SimpleAbstractStreamReader::readDocument(AST::UiProgram *ast)
-{
- if (!ast) {
- addError(tr("Could not parse document."));
- return false;
- }
+ lexer.setCode(source, /*line = */ 1, /*qmlMode = */ true);
- AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(ast->members->member);
- if (!uiObjectDefinition) {
- addError(tr("Expected document to contain a single object definition."));
- return false;
+ if (!parser.parse()) {
+ QString errorMessage = QString::fromLatin1("%1:%2: %3")
+ .arg(QString::number(parser.errorLineNumber()),
+ QString::number(parser.errorColumnNumber()),
+ parser.errorMessage());
+ addError(errorMessage);
+ return false;
+ }
+ return readDocument(parser.ast());
}
- readChild(uiObjectDefinition);
- m_source.clear();
+ QStringList SimpleAbstractStreamReader::errors() const { return m_errors; }
- return errors().isEmpty();
-}
-
-void SimpleAbstractStreamReader::readChildren(AST::UiObjectDefinition *uiObjectDefinition)
-{
- Q_ASSERT(uiObjectDefinition);
-
- for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it; it = it->next) {
- AST::UiObjectMember *member = it->member;
- AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(member);
- if (uiObjectDefinition)
- readChild(uiObjectDefinition);
+ void SimpleAbstractStreamReader::addError(const QString &error,
+ const SourceLocation &sourceLocation)
+ {
+ m_errors << QString::fromLatin1("%1:%2: %3\n")
+ .arg(QString::number(sourceLocation.startLine),
+ QString::number(sourceLocation.startColumn),
+ error);
}
-}
-
-void SimpleAbstractStreamReader::readChild(AST::UiObjectDefinition *uiObjectDefinition)
-{
- Q_ASSERT(uiObjectDefinition);
- setSourceLocation(uiObjectDefinition->firstSourceLocation());
+ SourceLocation SimpleAbstractStreamReader::currentSourceLocation() const
+ {
+ return m_currentSourceLocation;
+ }
- elementStart(toString(uiObjectDefinition->qualifiedTypeNameId));
+ bool SimpleAbstractStreamReader::readDocument(AST::UiProgram * ast)
+ {
+ if (!ast) {
+ addError(tr("Could not parse document."));
+ return false;
+ }
- readProperties(uiObjectDefinition);
- readChildren(uiObjectDefinition);
+ AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(
+ ast->members->member);
+ if (!uiObjectDefinition) {
+ addError(tr("Expected document to contain a single object definition."));
+ return false;
+ }
+ readChild(uiObjectDefinition);
- elementEnd();
-}
+ m_source.clear();
-void SimpleAbstractStreamReader::readProperties(AST::UiObjectDefinition *uiObjectDefinition)
-{
- Q_ASSERT(uiObjectDefinition);
+ return errors().isEmpty();
+ }
- for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it; it = it->next) {
- AST::UiObjectMember *member = it->member;
- AST::UiScriptBinding *scriptBinding = AST::cast<AST::UiScriptBinding *>(member);
- if (scriptBinding)
- readProperty(scriptBinding);
+ void SimpleAbstractStreamReader::readChildren(AST::UiObjectDefinition * uiObjectDefinition)
+ {
+ Q_ASSERT(uiObjectDefinition);
+
+ for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it;
+ it = it->next) {
+ AST::UiObjectMember *member = it->member;
+ AST::UiObjectDefinition *uiObjectDefinition = AST::cast<AST::UiObjectDefinition *>(
+ member);
+ if (uiObjectDefinition)
+ readChild(uiObjectDefinition);
+ }
}
-}
-void SimpleAbstractStreamReader::readProperty(AST::UiScriptBinding *uiScriptBinding)
-{
- Q_ASSERT(uiScriptBinding);
+ void SimpleAbstractStreamReader::readChild(AST::UiObjectDefinition * uiObjectDefinition)
+ {
+ Q_ASSERT(uiObjectDefinition);
- setSourceLocation(uiScriptBinding->firstSourceLocation());
+ setSourceLocation(uiObjectDefinition->firstSourceLocation());
- const QString name = toString(uiScriptBinding->qualifiedId);
- const QVariant value = parsePropertyScriptBinding(uiScriptBinding);
+ elementStart(toString(uiObjectDefinition->qualifiedTypeNameId),
+ toSourceLocation(uiObjectDefinition->qualifiedTypeNameId));
- propertyDefinition(name, value);
-}
+ readProperties(uiObjectDefinition);
+ readChildren(uiObjectDefinition);
-QVariant SimpleAbstractStreamReader::parsePropertyScriptBinding(AST::UiScriptBinding *uiScriptBinding)
-{
- Q_ASSERT(uiScriptBinding);
+ elementEnd();
+ }
- AST::ExpressionStatement *expStmt = AST::cast<AST::ExpressionStatement *>(uiScriptBinding->statement);
- if (!expStmt) {
- addError(tr("Expected expression statement after colon."), uiScriptBinding->statement->firstSourceLocation());
- return QVariant();
+ void SimpleAbstractStreamReader::readProperties(AST::UiObjectDefinition * uiObjectDefinition)
+ {
+ Q_ASSERT(uiObjectDefinition);
+
+ for (AST::UiObjectMemberList *it = uiObjectDefinition->initializer->members; it;
+ it = it->next) {
+ AST::UiObjectMember *member = it->member;
+ AST::UiScriptBinding *scriptBinding = AST::cast<AST::UiScriptBinding *>(member);
+ if (scriptBinding)
+ readProperty(scriptBinding);
+ }
}
- return parsePropertyExpression(expStmt->expression);
-}
+ void SimpleAbstractStreamReader::readProperty(AST::UiScriptBinding * uiScriptBinding)
+ {
+ Q_ASSERT(uiScriptBinding);
-QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode *expressionNode)
-{
- Q_ASSERT(expressionNode);
+ setSourceLocation(uiScriptBinding->firstSourceLocation());
- AST::ArrayPattern *arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
+ const QString name = toString(uiScriptBinding->qualifiedId);
+ auto nameLoc = toSourceLocation(uiScriptBinding->qualifiedId);
+ auto value = parsePropertyScriptBinding(uiScriptBinding);
- if (arrayLiteral) {
- QList<QVariant> variantList;
- for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
- variantList << parsePropertyExpression(it->element->initializer);
- return variantList;
+ propertyDefinition(name, nameLoc, value.first, value.second);
}
- AST::StringLiteral *stringLiteral = AST::cast<AST::StringLiteral *>(expressionNode);
- if (stringLiteral)
- return stringLiteral->value.toString();
+ std::pair<QVariant, SourceLocation> SimpleAbstractStreamReader::parsePropertyScriptBinding(
+ AST::UiScriptBinding * uiScriptBinding)
+ {
+ Q_ASSERT(uiScriptBinding);
+
+ AST::ExpressionStatement *expStmt = AST::cast<AST::ExpressionStatement *>(
+ uiScriptBinding->statement);
+ if (!expStmt) {
+ addError(tr("Expected expression statement after colon."),
+ uiScriptBinding->statement->firstSourceLocation());
+ return std::make_pair(QVariant(), SourceLocation());
+ }
+
+ return std::make_pair(parsePropertyExpression(expStmt->expression),
+ toSourceLocation(expStmt->firstSourceLocation(),
+ expStmt->lastSourceLocation()));
+ }
- AST::TrueLiteral *trueLiteral = AST::cast<AST::TrueLiteral *>(expressionNode);
- if (trueLiteral)
- return true;
+ QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode
+ * expressionNode)
+ {
+ Q_ASSERT(expressionNode);
- AST::FalseLiteral *falseLiteral = AST::cast<AST::FalseLiteral *>(expressionNode);
- if (falseLiteral)
- return false;
+ AST::ArrayPattern *arrayLiteral = AST::cast<AST::ArrayPattern *>(expressionNode);
- AST::NumericLiteral *numericLiteral = AST::cast<AST::NumericLiteral *>(expressionNode);
- if (numericLiteral)
- return numericLiteral->value;
+ if (arrayLiteral) {
+ QList<QVariant> variantList;
+ for (AST::PatternElementList *it = arrayLiteral->elements; it; it = it->next)
+ variantList << parsePropertyExpression(it->element->initializer);
+ return variantList;
+ }
- return textAt(expressionNode->firstSourceLocation(), expressionNode->lastSourceLocation());
-}
+ AST::StringLiteral *stringLiteral = AST::cast<AST::StringLiteral *>(expressionNode);
+ if (stringLiteral)
+ return stringLiteral->value.toString();
-void SimpleAbstractStreamReader::setSourceLocation(const SourceLocation &sourceLocation)
-{
- m_currentSourceLocation = sourceLocation;
-}
+ AST::TrueLiteral *trueLiteral = AST::cast<AST::TrueLiteral *>(expressionNode);
+ if (trueLiteral)
+ return true;
-QString SimpleAbstractStreamReader::textAt(const SourceLocation &from,
- const SourceLocation &to)
-{
- return m_source.mid(from.offset, to.end() - from.begin());
-}
+ AST::FalseLiteral *falseLiteral = AST::cast<AST::FalseLiteral *>(expressionNode);
+ if (falseLiteral)
+ return false;
-SimpleReader::SimpleReader()
-{
-}
+ AST::NumericLiteral *numericLiteral = AST::cast<AST::NumericLiteral *>(expressionNode);
+ if (numericLiteral)
+ return numericLiteral->value;
-SimpleReaderNode::Ptr SimpleReader::readFile(const QString &fileName)
-{
- SimpleAbstractStreamReader::readFile(fileName);
- return m_rootNode;
-}
+ return textAt(expressionNode->firstSourceLocation(), expressionNode->lastSourceLocation());
+ }
-SimpleReaderNode::Ptr SimpleReader::readFromSource(const QString &source)
-{
- SimpleAbstractStreamReader::readFromSource(source);
- return m_rootNode;
-}
+ void SimpleAbstractStreamReader::setSourceLocation(const SourceLocation &sourceLocation)
+ {
+ m_currentSourceLocation = sourceLocation;
+ }
-void SimpleReader::elementStart(const QString &name)
-{
- qCDebug(simpleReaderLog) << "elementStart()" << name;
+ QString SimpleAbstractStreamReader::textAt(const SourceLocation &from, const SourceLocation &to)
+ {
+ return m_source.mid(from.offset, to.end() - from.begin());
+ }
- SimpleReaderNode::Ptr newNode = SimpleReaderNode::create(name, m_currentNode);
+ SimpleReader::SimpleReader() {}
- if (newNode->isRoot())
- m_rootNode = newNode;
+ SimpleReaderNode::Ptr SimpleReader::readFile(const QString &fileName)
+ {
+ SimpleAbstractStreamReader::readFile(fileName);
+ return m_rootNode;
+ }
- Q_ASSERT(newNode->isValid());
+ SimpleReaderNode::Ptr SimpleReader::readFromSource(const QString &source)
+ {
+ SimpleAbstractStreamReader::readFromSource(source);
+ return m_rootNode;
+ }
- m_currentNode = newNode;
-}
+ void SimpleReader::elementStart(const QString &name, const SourceLocation &nameLocation)
+ {
+ qCDebug(simpleReaderLog) << "elementStart()" << name;
-void SimpleReader::elementEnd()
-{
- Q_ASSERT(m_currentNode);
+ SimpleReaderNode::Ptr newNode = SimpleReaderNode::create(name, nameLocation, m_currentNode);
- qCDebug(simpleReaderLog) << "elementEnd()" << m_currentNode.toStrongRef().data()->name();
+ if (newNode->isRoot())
+ m_rootNode = newNode;
- m_currentNode = m_currentNode.toStrongRef().data()->parent();
-}
+ Q_ASSERT(newNode->isValid());
-void SimpleReader::propertyDefinition(const QString &name, const QVariant &value)
-{
- Q_ASSERT(m_currentNode);
+ m_currentNode = newNode;
+ }
- qCDebug(simpleReaderLog) << "propertyDefinition()" << m_currentNode.toStrongRef().data()->name() << name << value;
+ void SimpleReader::elementEnd()
+ {
+ Q_ASSERT(m_currentNode);
- if (m_currentNode.toStrongRef().data()->propertyNames().contains(name))
- addError(tr("Property is defined twice."), currentSourceLocation());
+ qCDebug(simpleReaderLog) << "elementEnd()" << m_currentNode.toStrongRef().data()->name();
- m_currentNode.toStrongRef().data()->setProperty(name, value);
-}
+ m_currentNode = m_currentNode.toStrongRef().data()->parent();
+ }
+
+ void SimpleReader::propertyDefinition(const QString &name,
+ const SourceLocation &nameLocation,
+ const QVariant &value,
+ const SourceLocation &valueLocation)
+ {
+ Q_ASSERT(m_currentNode);
+
+ qCDebug(simpleReaderLog) << "propertyDefinition()"
+ << m_currentNode.toStrongRef().data()->name() << name << value;
+
+ if (m_currentNode.toStrongRef().data()->propertyNames().contains(name)) {
+ auto previousSourceLoc = m_currentNode.toStrongRef().data()->property(name).nameLocation;
+ addError(tr("Property is defined twice, previous definition at %1:%2")
+ .arg(QString::number(previousSourceLoc.startLine),
+ QString::number(previousSourceLoc.startColumn)),
+ currentSourceLocation());
+ }
+
+ m_currentNode.toStrongRef().data()->setProperty(name, nameLocation, value, valueLocation);
+ }
} // namespace QmlJS
diff --git a/src/libs/qmljs/qmljssimplereader.h b/src/libs/qmljs/qmljssimplereader.h
index 2d5bad3e09..4713c1b67a 100644
--- a/src/libs/qmljs/qmljssimplereader.h
+++ b/src/libs/qmljs/qmljssimplereader.h
@@ -26,13 +26,18 @@
#pragma once
#include <qmljs/qmljs_global.h>
-#include <qmljs/parser/qmljsastfwd_p.h>
+#ifdef QT_CREATOR
+#include <qmljs/parser/qmljsastfwd_p.h>
+#else
+#include <parser/qqmljsastfwd_p.h>
+#endif
#include <QHash>
#include <QList>
-#include <QStringList>
#include <QSharedPointer>
+#include <QStringList>
+#include <QVariant>
#include <QWeakPointer>
// for Q_DECLARE_TR_FUNCTIONS
@@ -40,15 +45,31 @@
namespace QmlJS {
+#ifndef QT_CREATOR
+using SourceLocation = QQmlJS::SourceLocation;
+#endif
+
class QMLJS_EXPORT SimpleReaderNode
{
public:
+ struct Property
+ {
+ QVariant value;
+ SourceLocation nameLocation;
+ SourceLocation valueLocation;
+
+ bool isValid() const { return !value.isNull() && value.isValid(); }
+ bool isDefaultValue() const
+ {
+ return !value.isNull() && !nameLocation.isValid() && !valueLocation.isValid();
+ }
+ };
typedef QSharedPointer<SimpleReaderNode> Ptr;
typedef QWeakPointer<SimpleReaderNode> WeakPtr;
- typedef QHash<QString, QVariant> PropertyHash;
+ typedef QHash<QString, Property> PropertyHash;
typedef QList<Ptr> List;
- QVariant property(const QString &name) const;
+ Property property(const QString &name) const;
QStringList propertyNames() const;
PropertyHash properties() const;
bool isRoot() const;
@@ -56,16 +77,21 @@ public:
static Ptr invalidNode();
WeakPtr parent() const;
QString name() const;
+ SourceLocation nameLocation() const;
const List children() const;
protected:
SimpleReaderNode();
- SimpleReaderNode(const QString &name, WeakPtr parent);
- static Ptr create(const QString &name, WeakPtr parent);
- void setProperty(const QString &name, const QVariant &value);
+ SimpleReaderNode(const QString &name, const SourceLocation &nameLocation, WeakPtr parent);
+ static Ptr create(const QString &name, const SourceLocation &nameLocation, WeakPtr parent);
+ void setProperty(const QString &name,
+ const SourceLocation &nameLocation,
+ const QVariant &value,
+ const SourceLocation &valueLocation);
private:
const QString m_name;
+ const SourceLocation m_nameLocation;
PropertyHash m_properties;
const WeakPtr m_parentNode;
List m_children;
@@ -74,12 +100,17 @@ private:
friend class SimpleReader;
};
+#ifndef QT_CREATOR
+using namespace QQmlJS;
+#endif
+
class QMLJS_EXPORT SimpleAbstractStreamReader
{
Q_DECLARE_TR_FUNCTIONS(QmlJS::SimpleAbstractStreamReader)
public:
SimpleAbstractStreamReader();
+ virtual ~SimpleAbstractStreamReader();
bool readFile(const QString &fileName);
bool readFromSource(const QString &source);
QStringList errors() const;
@@ -88,9 +119,13 @@ protected:
void addError(const QString &error, const SourceLocation &sourceLocation = SourceLocation());
SourceLocation currentSourceLocation() const;
- virtual void elementStart(const QString &name) = 0;
+ virtual void elementStart(const QString &name, const SourceLocation &nameLocation) = 0;
virtual void elementEnd() = 0;
- virtual void propertyDefinition(const QString &name, const QVariant &value) = 0;
+ virtual void propertyDefinition(const QString &name,
+ const SourceLocation &nameLocation,
+ const QVariant &value,
+ const SourceLocation &valueLocation)
+ = 0;
private:
bool readDocument(AST::UiProgram *ast);
@@ -98,7 +133,8 @@ private:
void readChild(AST::UiObjectDefinition *uiObjectDefinition);
void readProperties(AST::UiObjectDefinition *ast);
void readProperty(AST::UiScriptBinding *uiScriptBinding);
- QVariant parsePropertyScriptBinding(AST::UiScriptBinding *ExpressionNode);
+ std::pair<QVariant, SourceLocation> parsePropertyScriptBinding(
+ AST::UiScriptBinding *ExpressionNode);
QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode);
void setSourceLocation(const SourceLocation &sourceLocation);
QString textAt(const SourceLocation &from, const SourceLocation &to);
@@ -118,9 +154,12 @@ public:
SimpleReaderNode::Ptr readFromSource(const QString &source);
protected:
- void elementStart(const QString &name) override;
+ void elementStart(const QString &name, const SourceLocation &nameLocation) override;
void elementEnd() override;
- void propertyDefinition(const QString &name, const QVariant &value) override;
+ void propertyDefinition(const QString &name,
+ const SourceLocation &nameLocation,
+ const QVariant &value,
+ const SourceLocation &valueLocation) override;
private:
SimpleReaderNode::Ptr m_rootNode;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index 5adce7e932..b9c2ce6768 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -595,9 +595,9 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) {
if (node->propertyNames().contains("separateSection"))
- separateSectionTypes.append(variantToStringList(node->property("typeNames")));
+ separateSectionTypes.append(variantToStringList(node->property("typeNames").value));
- allTypes.append(variantToStringList(node->property("typeNames")));
+ allTypes.append(variantToStringList(node->property("typeNames").value));
}
const QList<PropertyName> allProperties = type.propertyNames();
@@ -666,8 +666,8 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
QString filledTemplate;
for (const QmlJS::SimpleReaderNode::Ptr &n : nodes) {
// Check if we have a template for the type
- if (variantToStringList(n->property(QStringLiteral("typeNames"))).contains(QString::fromLatin1(typeName))) {
- const QString fileName = propertyTemplatesPath() + n->property(QStringLiteral("sourceFile")).toString();
+ if (variantToStringList(n->property(QStringLiteral("typeNames")).value).contains(QString::fromLatin1(typeName))) {
+ const QString fileName = propertyTemplatesPath() + n->property(QStringLiteral("sourceFile")).value.toString();
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
QString source = QString::fromUtf8(file.readAll());
@@ -682,7 +682,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
};
// QML specfics preparation
- QStringList imports = variantToStringList(templateConfiguration()->property(QStringLiteral("imports")));
+ QStringList imports = variantToStringList(templateConfiguration()->property(QStringLiteral("imports")).value);
QString qmlTemplate = imports.join(QLatin1Char('\n')) + QLatin1Char('\n');
bool emptyTemplate = true;
diff --git a/src/plugins/qmldesigner/designercore/include/metainforeader.h b/src/plugins/qmldesigner/designercore/include/metainforeader.h
index f14336b4a1..64047444f3 100644
--- a/src/plugins/qmldesigner/designercore/include/metainforeader.h
+++ b/src/plugins/qmldesigner/designercore/include/metainforeader.h
@@ -54,9 +54,12 @@ public:
void setQualifcation(const TypeName &qualification);
protected:
- void elementStart(const QString &name) override;
+ void elementStart(const QString &name, const QmlJS::SourceLocation &nameLocation) override;
void elementEnd() override;
- void propertyDefinition(const QString &name, const QVariant &value) override;
+ void propertyDefinition(const QString &name,
+ const QmlJS::SourceLocation &nameLocation,
+ const QVariant &value,
+ const QmlJS::SourceLocation &valueLocation) override;
private:
enum ParserSate { Error,
diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
index 5baf856dce..28d8e02826 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp
@@ -87,7 +87,7 @@ void MetaInfoReader::setQualifcation(const TypeName &qualification)
m_qualication = qualification;
}
-void MetaInfoReader::elementStart(const QString &name)
+void MetaInfoReader::elementStart(const QString &name, const QmlJS::SourceLocation &nameLocation)
{
switch (parserState()) {
case ParsingDocument: setParserState(readDocument(name)); break;
@@ -128,7 +128,10 @@ void MetaInfoReader::elementEnd()
}
}
-void MetaInfoReader::propertyDefinition(const QString &name, const QVariant &value)
+void MetaInfoReader::propertyDefinition(const QString &name,
+ const QmlJS::SourceLocation &nameLocation,
+ const QVariant &value,
+ const QmlJS::SourceLocation &valueLocation)
{
switch (parserState()) {
case ParsingType: readTypeProperty(name, value); break;
diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
index a110750453..56a54a0071 100644
--- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
@@ -1161,7 +1161,7 @@ void checkNode(const QmlJS::SimpleReaderNode::Ptr &node, RewriterView *view)
if (!node->propertyNames().contains("i"))
return;
- const int index = node->property("i").toInt();
+ const int index = node->property("i").value.toInt();
const ModelNode modelNode = view->getNodeForCanonicalIndex(index);
@@ -1174,7 +1174,7 @@ void checkNode(const QmlJS::SimpleReaderNode::Ptr &node, RewriterView *view)
if (i.key() != "i") {
const PropertyName name = fixUpIllegalChars(i.key()).toUtf8();
if (!modelNode.hasAuxiliaryData(name))
- modelNode.setAuxiliaryData(name, i.value());
+ modelNode.setAuxiliaryData(name, i.value().value);
}
}
diff --git a/src/plugins/qmldesigner/designermcumanager.cpp b/src/plugins/qmldesigner/designermcumanager.cpp
index b7b9ef2fad..369d4f1dad 100644
--- a/src/plugins/qmldesigner/designermcumanager.cpp
+++ b/src/plugins/qmldesigner/designermcumanager.cpp
@@ -37,20 +37,20 @@ namespace QmlDesigner {
static QString readProperty(const QString property, const QmlJS::SimpleReaderNode::Ptr &node)
{
- const QVariant propertyVar = node->property(property);
+ const auto propertyVar = node->property(property);
- if (!propertyVar.isNull() && propertyVar.isValid())
- return propertyVar.value<QString>();
+ if (propertyVar.isValid())
+ return propertyVar.value.value<QString>();
return {};
}
static QStringList readPropertyList(const QString &property, const QmlJS::SimpleReaderNode::Ptr &node)
{
- const QVariant propertyVar = node->property(property);
+ const auto propertyVar = node->property(property);
- if (!propertyVar.isNull() && propertyVar.isValid())
- return propertyVar.value<QStringList>();
+ if (propertyVar.isValid())
+ return propertyVar.value.value<QStringList>();
return {};
}
@@ -99,30 +99,31 @@ void DesignerMcuManager::readMetadata()
return;
}
- const QVariant defaultVersion = metadata->property("defaultVersion");
- if (!defaultVersion.isNull() && defaultVersion.isValid()) {
+ const QmlJS::SimpleReaderNode::Property defaultVersion = metadata->property("defaultVersion");
+
+ if (defaultVersion.isValid()) {
for (const auto& version : versions) {
Version newVersion;
- const QVariant vId = version->property("id");
- if (vId.isNull() || !vId.isValid())
+ const auto vId = version->property("id");
+ if (!vId.isValid())
continue;
- const QVariant vName = version->property("name");
- if (!vName.isNull() && vName.isValid())
- newVersion.name = vName.value<QString>();
+ const auto vName = version->property("name");
+ if (vName.isValid())
+ newVersion.name = vName.value.value<QString>();
else
continue;
- const QVariant vPath = version->property("path");
- if (!vPath.isNull() && vPath.isValid())
- newVersion.fileName = vPath.value<QString>();
+ const auto vPath = version->property("path");
+ if (vPath.isValid())
+ newVersion.fileName = vPath.value.value<QString>();
else
continue;
m_versionsList.push_back(newVersion);
- if (vId == defaultVersion)
+ if (vId.value == defaultVersion.value)
m_defaultVersion = newVersion;
}
}
@@ -172,10 +173,10 @@ void DesignerMcuManager::readVersionData(const DesignerMcuManager::Version &vers
if (child->propertyNames().contains("allowedProperties")) {
ItemProperties allowedProperties;
- const QVariant childrenPropertyVar = child->property("allowChildren");
+ const auto childrenPropertyVar = child->property("allowChildren");
- if (!childrenPropertyVar.isNull() && childrenPropertyVar.isValid())
- allowedProperties.allowChildren = childrenPropertyVar.toBool();
+ if (childrenPropertyVar.isValid())
+ allowedProperties.allowChildren = childrenPropertyVar.value.toBool();
allowedProperties.properties = readPropertyList("allowedProperties", child);
diff --git a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
index 546e912000..53c76263a2 100644
--- a/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
+++ b/src/plugins/qmlprojectmanager/fileformat/qmlprojectfileformat.cpp
@@ -39,24 +39,30 @@ namespace {
QmlProjectManager::FileFilterBaseItem *setupFileFilterItem(QmlProjectManager::FileFilterBaseItem *fileFilterItem, const QmlJS::SimpleReaderNode::Ptr &node)
{
- const QVariant directoryProperty = node->property(QLatin1String("directory"));
+ const auto directoryProperty = node->property(QLatin1String("directory"));
if (directoryProperty.isValid())
- fileFilterItem->setDirectory(directoryProperty.toString());
+ fileFilterItem->setDirectory(directoryProperty.value.toString());
- const QVariant recursiveProperty = node->property(QLatin1String("recursive"));
+ const auto recursiveProperty = node->property(QLatin1String("recursive"));
if (recursiveProperty.isValid())
- fileFilterItem->setRecursive(recursiveProperty.toBool());
+ fileFilterItem->setRecursive(recursiveProperty.value.toBool());
- const QVariant pathsProperty = node->property(QLatin1String("paths"));
+ const auto pathsProperty = node->property(QLatin1String("paths"));
if (pathsProperty.isValid())
- fileFilterItem->setPathsProperty(pathsProperty.toStringList());
+ fileFilterItem->setPathsProperty(pathsProperty.value.toStringList());
- const QVariant filterProperty = node->property(QLatin1String("filter"));
+ // "paths" and "files" have the same functionality
+ const auto filesProperty = node->property(QLatin1String("files"));
+ if (filesProperty.isValid())
+ fileFilterItem->setPathsProperty(filesProperty.value.toStringList());
+
+ const auto filterProperty = node->property(QLatin1String("filter"));
if (filterProperty.isValid())
- fileFilterItem->setFilter(filterProperty.toString());
+ fileFilterItem->setFilter(filterProperty.value.toString());
if (debug)
- qDebug() << "directory:" << directoryProperty << "recursive" << recursiveProperty << "paths" << pathsProperty;
+ qDebug() << "directory:" << directoryProperty.value << "recursive" << recursiveProperty.value
+ << "paths" << pathsProperty.value << "files" << filesProperty.value;
return fileFilterItem;
}
@@ -81,36 +87,36 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
if (rootNode->name() == QLatin1String("Project")) {
auto projectItem = new QmlProjectItem;
- const QVariant mainFileProperty = rootNode->property(QLatin1String("mainFile"));
+ const auto mainFileProperty = rootNode->property(QLatin1String("mainFile"));
if (mainFileProperty.isValid())
- projectItem->setMainFile(mainFileProperty.toString());
+ projectItem->setMainFile(mainFileProperty.value.toString());
- const QVariant importPathsProperty = rootNode->property(QLatin1String("importPaths"));
+ const auto importPathsProperty = rootNode->property(QLatin1String("importPaths"));
if (importPathsProperty.isValid())
- projectItem->setImportPaths(importPathsProperty.toStringList());
+ projectItem->setImportPaths(importPathsProperty.value.toStringList());
- const QVariant fileSelectorsProperty = rootNode->property(QLatin1String("fileSelectors"));
+ const auto fileSelectorsProperty = rootNode->property(QLatin1String("fileSelectors"));
if (fileSelectorsProperty.isValid())
- projectItem->setFileSelectors(fileSelectorsProperty.toStringList());
+ projectItem->setFileSelectors(fileSelectorsProperty.value.toStringList());
- const QVariant forceFreeTypeProperty = rootNode->property("forceFreeType");
+ const auto forceFreeTypeProperty = rootNode->property("forceFreeType");
if (forceFreeTypeProperty.isValid())
- projectItem->setForceFreeType(forceFreeTypeProperty.toBool());
+ projectItem->setForceFreeType(forceFreeTypeProperty.value.toBool());
- const QVariant targetDirectoryPropery = rootNode->property("targetDirectory");
+ const auto targetDirectoryPropery = rootNode->property("targetDirectory");
if (targetDirectoryPropery.isValid())
- projectItem->setTargetDirectory(targetDirectoryPropery.toString());
+ projectItem->setTargetDirectory(targetDirectoryPropery.value.toString());
- const QVariant qtForMCUProperty = rootNode->property("qtForMCUs");
- if (qtForMCUProperty.isValid() && qtForMCUProperty.toBool())
- projectItem->setQtForMCUs(qtForMCUProperty.toBool());
+ const auto qtForMCUProperty = rootNode->property("qtForMCUs");
+ if (qtForMCUProperty.isValid() && qtForMCUProperty.value.toBool())
+ projectItem->setQtForMCUs(qtForMCUProperty.value.toBool());
- const QVariant qt6ProjectProperty = rootNode->property("qt6Project");
- if (qt6ProjectProperty.isValid() && qt6ProjectProperty.toBool())
- projectItem->setQt6Project(qt6ProjectProperty.toBool());
+ const auto qt6ProjectProperty = rootNode->property("qt6Project");
+ if (qt6ProjectProperty.isValid() && qt6ProjectProperty.value.toBool())
+ projectItem->setQt6Project(qt6ProjectProperty.value.toBool());
if (debug)
- qDebug() << "importPath:" << importPathsProperty << "mainFile:" << mainFileProperty;
+ qDebug() << "importPath:" << importPathsProperty.value << "mainFile:" << mainFileProperty.value;
foreach (const QmlJS::SimpleReaderNode::Ptr &childNode, rootNode->children()) {
if (debug)
@@ -132,7 +138,7 @@ QmlProjectItem *QmlProjectFileFormat::parseProjectFile(const Utils::FilePath &fi
const auto properties = childNode->properties();
auto i = properties.constBegin();
while (i != properties.constEnd()) {
- projectItem->addToEnviroment(i.key(), i.value().toString());
+ projectItem->addToEnviroment(i.key(), i.value().value.toString());
++i;
}
} else {
diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp
index 084a750258..c8c8145319 100644
--- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp
+++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp
@@ -8546,14 +8546,14 @@ static void checkNode(QmlJS::SimpleReaderNode::Ptr node, TestRewriterView *view)
{
QVERIFY(node);
QVERIFY(node->propertyNames().contains("i"));
- const int internalId = node->property("i").toInt();
+ const int internalId = node->property("i").value.toInt();
const ModelNode modelNode = view->modelNodeForInternalId(internalId);
QVERIFY(modelNode.isValid());
auto properties = node->properties();
for (auto i = properties.begin(); i != properties.end(); ++i) {
if (i.key() != "i")
- QCOMPARE(i.value(), modelNode.auxiliaryData(i.key().toUtf8()));
+ QCOMPARE(i.value().value, modelNode.auxiliaryData(i.key().toUtf8()));
}
checkChildNodes(node, view);
diff --git a/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
index a17ef2d993..128bc14c6b 100644
--- a/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
+++ b/tests/auto/qml/qmljssimplereader/tst_qmljssimplereader.cpp
@@ -77,13 +77,13 @@ void tst_SimpleReader::testWellFormed()
QCOMPARE(rootNode->properties().count(), 1);
QVERIFY(rootNode->properties().contains("propertyBlah"));
- QCOMPARE(rootNode->property("property01").toBool(), false);
+ QCOMPARE(rootNode->property("property01").value.toBool(), false);
QVERIFY(rootNode->children().first()->isValid());
QVERIFY(!rootNode->children().first()->isRoot());
QVERIFY(rootNode->children().first()->properties().contains("property01"));
- QCOMPARE(rootNode->children().first()->property("property01").toInt(), 10);
+ QCOMPARE(rootNode->children().first()->property("property01").value.toInt(), 10);
SimpleReaderNode::Ptr secondChild = rootNode->children().at(1);
@@ -93,7 +93,7 @@ void tst_SimpleReader::testWellFormed()
QCOMPARE(secondChild->name(), QLatin1String("ChildNode"));
QVERIFY(secondChild->properties().contains("propertyString"));
- QCOMPARE(secondChild->property("propertyString").toString(), QLatin1String("str"));
+ QCOMPARE(secondChild->property("propertyString").value.toString(), QLatin1String("str"));
QCOMPARE(secondChild->children().count(), 1);
@@ -105,7 +105,7 @@ void tst_SimpleReader::testWellFormed()
QCOMPARE(innerChild->name(), QLatin1String("InnerChild"));
QVERIFY(innerChild->properties().contains("test"));
- QCOMPARE(innerChild->property("test").toString(), QLatin1String("test"));
+ QCOMPARE(innerChild->property("test").value.toString(), QLatin1String("test"));
weak01 = rootNode;
weak02 = secondChild;
@@ -170,7 +170,7 @@ void tst_SimpleReader::testIllFormed02()
QCOMPARE(firstChild->properties().count(), 1);
QVERIFY(firstChild->properties().contains("property01"));
- QCOMPARE(firstChild->property("property01").toString(), QLatin1String("20"));
+ QCOMPARE(firstChild->property("property01").value.toString(), QLatin1String("20"));
}
void tst_SimpleReader::testArrays()
@@ -194,7 +194,7 @@ void tst_SimpleReader::testArrays()
QVERIFY(rootNode->isValid());
QVERIFY(rootNode->isRoot());
- QCOMPARE(rootNode->property("propertyArray"), variant);
+ QCOMPARE(rootNode->property("propertyArray").value, variant);
SimpleReaderNode::Ptr firstChild = rootNode->children().at(0);
@@ -202,13 +202,13 @@ void tst_SimpleReader::testArrays()
QVERIFY(firstChild);
QVERIFY(firstChild->isValid());
QVERIFY(!firstChild->isRoot());
- QCOMPARE(firstChild->property("propertyArray"), variant);
+ QCOMPARE(firstChild->property("propertyArray").value, variant);
QList<QVariant> variantList2;
variantList2 << QVariant(QLatin1String("string03")) << variant;
const QVariant variant2 = variantList2;
- QCOMPARE(firstChild->property("propertyArrayMixed"), variant2);
+ QCOMPARE(firstChild->property("propertyArrayMixed").value, variant2);
}
void tst_SimpleReader::testBug01()