diff options
author | Christiaan Janssen <christiaan.janssen@qt.io> | 2021-09-27 15:28:36 +0200 |
---|---|---|
committer | Christiaan Janssen <christiaan.janssen@qt.io> | 2021-09-30 06:19:46 +0000 |
commit | 525039daebe783560d2ba7f12db573f25d745852 (patch) | |
tree | e858c756fcff37f00905cf6a38d8080049edde43 | |
parent | 3ad9c6497798adeac883495014f7afd83ec2aa04 (diff) |
QmlProject: port changes from QtForMcus
Task-number: QTCREATORBUG-26041
Change-Id: I5068381fb2c4c901d8621e0b8358db77d2cb0b21
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
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() |