diff --git a/src/imports/tooling/Member.qml b/src/imports/tooling/Member.qml index 9df4fa76a2..872083e099 100644 --- a/src/imports/tooling/Member.qml +++ b/src/imports/tooling/Member.qml @@ -5,4 +5,5 @@ import QML QtObject { required property string name + property int lineNumber: 0 } diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 0690167fdf..9abd049f30 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -254,12 +254,13 @@ void QQmlJSTypeDescriptionReader::readComponent(UiObjectDefinition *ast) scope->setIsJavaScriptBuiltin(true); } else { addWarning(script->firstSourceLocation(), - tr("Expected only name, prototype, defaultProperty, attachedType, " + tr("Expected only lineNumber, name, prototype, defaultProperty, " + "attachedType, " "valueType, exports, interfaces, isSingleton, isCreatable, " "isStructured, isComposite, hasCustomParser, enforcesScopedEnums, " "aliases, exportMetaObjectRevisions, deferredNames, and " "immediateNames in script bindings, not \"%1\".") - .arg(name)); + .arg(name)); } } else { addWarning(member->firstSourceLocation(), @@ -303,6 +304,8 @@ void QQmlJSTypeDescriptionReader::readSignalOrMethod( QString name = toString(script->qualifiedId); if (name == QLatin1String("name")) { metaMethod.setMethodName(readStringBinding(script)); + } else if (name == QLatin1String("lineNumber")) { + // only used in 6.11 } else if (name == QLatin1String("type")) { metaMethod.setReturnTypeName(readStringBinding(script)); } else if (name == QLatin1String("revision")) { @@ -343,7 +346,8 @@ void QQmlJSTypeDescriptionReader::readSignalOrMethod( metaMethod.setIsConst(readBoolBinding(script)); } else { addWarning(script->firstSourceLocation(), - tr("Expected only name, type, revision, isPointer, isTypeConstant, " + tr("Expected only name, lineNumber, type, revision, isPointer, " + "isTypeConstant, " "isList, isCloned, isConstructor, isMethodConstant, and " "isJavaScriptFunction in script bindings.")); } @@ -388,6 +392,8 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ QString id = toString(script->qualifiedId); if (id == QLatin1String("name")) { property.setPropertyName(readStringBinding(script)); + } else if (id == QLatin1String("lineNumber")) { + // only used in 6.11 } else if (id == QLatin1String("type")) { property.setTypeName(readStringBinding(script)); } else if (id == QLatin1String("isPointer")) { @@ -425,8 +431,10 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ property.setPrivateClass(readStringBinding(script)); } else { addWarning(script->firstSourceLocation(), - tr("Expected only type, name, revision, isPointer, isTypeConstant, isReadonly, isRequired, " - "isFinal, isList, bindable, read, write, isPropertyConstant, reset, notify, index, and " + tr("Expected only type, name, lineNumber, revision, isPointer, " + "isTypeConstant, isReadonly, isRequired, " + "isFinal, isList, bindable, read, write, isPropertyConstant, reset, " + "notify, index, and " "privateClass and script bindings.")); } } @@ -467,9 +475,12 @@ void QQmlJSTypeDescriptionReader::readEnum(UiObjectDefinition *ast, const QQmlJS metaEnum.setIsScoped(readBoolBinding(script)); } else if (name == QLatin1String("type")) { metaEnum.setTypeName(readStringBinding(script)); + } else if (name == QLatin1String("lineNumber")) { + // only used in 6.11 } else { addWarning(script->firstSourceLocation(), - tr("Expected only name, alias, isFlag, values, isScoped, or type.")); + tr("Expected only name, alias, isFlag, values, isScoped, type, or " + "lineNumber.")); } } diff --git a/src/qmltyperegistrar/qmetatypesjsonprocessor.cpp b/src/qmltyperegistrar/qmetatypesjsonprocessor.cpp index 3bfd8b4978..30f344d705 100644 --- a/src/qmltyperegistrar/qmetatypesjsonprocessor.cpp +++ b/src/qmltyperegistrar/qmetatypesjsonprocessor.cpp @@ -757,6 +757,7 @@ Property::Property(const QCborMap &cbor) , bindable(cbor[S_BINDABLE].toStringView()) , privateClass(cbor[S_PRIVATE_CLASS].toStringView()) , index(cbor[S_INDEX].toInteger(-1)) + , lineNumber(cbor[S_LINENUMBER].toInteger(0)) , revision(getRevision(cbor)) , isFinal(cbor[S_FINAL].toBool()) , isConstant(cbor[S_CONSTANT].toBool()) @@ -774,6 +775,7 @@ Method::Method(const QCborMap &cbor, bool isConstructor) : name(cbor[S_NAME].toStringView()) , returnType(cbor[S_RETURN_TYPE].toStringView()) , index(cbor[S_INDEX].toInteger(InvalidIndex)) + , lineNumber(cbor[S_LINENUMBER].toInteger(0)) , revision(getRevision(cbor)) , access(getAccess(cbor)) , isCloned(cbor[S_IS_CLONED].toBool()) @@ -798,6 +800,7 @@ Enum::Enum(const QCborMap &cbor) : name(cbor[S_NAME].toStringView()) , alias(cbor[S_ALIAS].toStringView()) , type(cbor[S_TYPE].toStringView()) + , lineNumber(cbor[S_LINENUMBER].toInteger(0)) , isFlag(cbor[S_IS_FLAG].toBool()) , isClass(cbor[S_IS_CLASS].toBool()) { diff --git a/src/qmltyperegistrar/qmetatypesjsonprocessor_p.h b/src/qmltyperegistrar/qmetatypesjsonprocessor_p.h index 827e4c1e60..2bab7d522b 100644 --- a/src/qmltyperegistrar/qmetatypesjsonprocessor_p.h +++ b/src/qmltyperegistrar/qmetatypesjsonprocessor_p.h @@ -84,6 +84,7 @@ struct Property QAnyStringView privateClass; int index = -1; + int lineNumber = 0; QTypeRevision revision; @@ -117,6 +118,7 @@ struct Method QAnyStringView returnType; int index = InvalidIndex; + int lineNumber = 0; QTypeRevision revision; @@ -141,6 +143,7 @@ struct Enum QList values; + int lineNumber = 0; bool isFlag = false; bool isClass = false; }; diff --git a/src/qmltyperegistrar/qqmltypescreator.cpp b/src/qmltyperegistrar/qqmltypescreator.cpp index 93be96d69e..14d6e2c1a3 100644 --- a/src/qmltyperegistrar/qqmltypescreator.cpp +++ b/src/qmltyperegistrar/qqmltypescreator.cpp @@ -216,6 +216,10 @@ void QmlTypesCreator::writeProperties(const Property::Container &properties) if (index != -1) { m_qml.writeNumberBinding(S_INDEX, index); } + const auto lineNumber = obj.lineNumber; + if (lineNumber != 0) + m_qml.writeNumberBinding(S_LINE_NUMBER, obj.lineNumber); + const auto privateClass = obj.privateClass; if (!privateClass.isEmpty()) { m_qml.writeStringBinding( @@ -260,6 +264,9 @@ void QmlTypesCreator::writeMethods(const Method::Container &methods, QLatin1Stri m_qml.writeBooleanBinding(S_IS_JAVASCRIPT_FUNCTION, true); if (obj.isConst) m_qml.writeBooleanBinding(S_IS_METHOD_CONSTANT, true); + const auto lineNumber = obj.lineNumber; + if (lineNumber != 0) + m_qml.writeNumberBinding(S_LINE_NUMBER, obj.lineNumber); const Argument::Container &arguments = obj.arguments; for (qsizetype i = 0, end = arguments.size(); i != end; ++i) { @@ -287,6 +294,9 @@ void QmlTypesCreator::writeEnums(const Enum::Container &enums) if (obj.isClass) m_qml.writeBooleanBinding(S_IS_SCOPED, true); writeType(obj.type); + const auto lineNumber = obj.lineNumber; + if (lineNumber != 0) + m_qml.writeNumberBinding(S_LINE_NUMBER, obj.lineNumber); m_qml.writeStringListBinding(S_VALUES, obj.values); m_qml.writeEndObject(); } diff --git a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp index a45cd1ba9c..70b6898747 100644 --- a/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp +++ b/tests/auto/qml/qmltyperegistrar/tst_qmltyperegistrar.cpp @@ -104,9 +104,26 @@ void tst_qmltyperegistrar::superAndForeignTypes() QVERIFY(qmltypesData.contains("values: [\"Pixel\", \"Centimeter\", \"Inch\", \"Point\"]")); QVERIFY(qmltypesData.contains("name: \"SizeGadget\"")); QVERIFY(qmltypesData.contains("prototype: \"SizeEnums\"")); - QVERIFY(qmltypesData.contains("Property { name: \"height\"; type: \"int\"; read: \"height\"; write: \"setHeight\"; index: 0; isFinal: true }")); - QVERIFY(qmltypesData.contains("Property { name: \"width\"; type: \"int\"; read: \"width\"; write: \"setWidth\"; index: 0; isFinal: true }")); - QVERIFY(qmltypesData.contains("Method { name: \"sizeToString\"; type: \"QString\"; isMethodConstant: true }")); + QVERIFY(qmltypesData.contains(R"(Property { + name: "height" + type: "int" + read: "height" + write: "setHeight" + index: 0 + lineNumber: 31 + isFinal: true + })")); + QVERIFY(qmltypesData.contains(R"(Property { + name: "width" + type: "int" + read: "width" + write: "setWidth" + index: 0 + lineNumber: 94 + isFinal: true + })")); + QVERIFY(qmltypesData.contains("Method { name: \"sizeToString\"; type: \"QString\"; " + "isMethodConstant: true; lineNumber: 100 }")); QCOMPARE(qmltypesData.count("extension: \"SizeValueType\""), 1); } @@ -118,7 +135,13 @@ void tst_qmltyperegistrar::accessSemantics() void tst_qmltyperegistrar::isBindable() { - QVERIFY(qmltypesData.contains(R"(Property { name: "someProperty"; type: "int"; bindable: "bindableSomeProperty"; index: 0 })")); + QVERIFY(qmltypesData.contains(R"(Property { + name: "someProperty" + type: "int" + bindable: "bindableSomeProperty" + index: 0 + lineNumber: 162 + })")); } void tst_qmltyperegistrar::doNotRestrictToImportVersion() @@ -250,7 +273,7 @@ void tst_qmltyperegistrar::finalProperty() { QCOMPARE(qmltypesData.count("name: \"FinalProperty\""), 1); QCOMPARE(qmltypesData.count( - "Property { name: \"fff\"; type: \"int\"; index: 0; isFinal: true }"), + "Property { name: \"fff\"; type: \"int\"; index: 0; lineNumber: 244; isFinal: true }"), 1); } @@ -574,16 +597,18 @@ void tst_qmltyperegistrar::clonedSignal() { QVERIFY(qmltypesData.contains(R"(Signal { name: "clonedSignal" + lineNumber: 548 Parameter { name: "i"; type: "int" } })")); - QVERIFY(qmltypesData.contains(R"(Signal { name: "clonedSignal"; isCloned: true })")); + QVERIFY(qmltypesData.contains(R"(Signal { name: "clonedSignal"; isCloned: true; lineNumber: 548 })")); } void tst_qmltyperegistrar::hasIsConstantInParameters() { QVERIFY(qmltypesData.contains(R"( Signal { name: "mySignal" + lineNumber: 17 Parameter { name: "myObject"; type: "QObject"; isPointer: true } Parameter { name: "myConstObject"; type: "QObject"; isPointer: true; isTypeConstant: true } Parameter { name: "myConstObject2"; type: "QObject"; isPointer: true; isTypeConstant: true } @@ -594,6 +619,7 @@ void tst_qmltyperegistrar::hasIsConstantInParameters() QVERIFY(qmltypesData.contains(R"(Signal { name: "myVolatileSignal" + lineNumber: 19 Parameter { name: "a"; type: "volatile QObject"; isPointer: true; isTypeConstant: true } Parameter { name: "b"; type: "volatile QObject"; isPointer: true; isTypeConstant: true } Parameter { name: "nonConst"; type: "volatile QObject"; isPointer: true } @@ -783,9 +809,10 @@ void tst_qmltyperegistrar::constructibleValueType() Method { name: "Constructible" isConstructor: true + lineNumber: 564 Parameter { name: "i"; type: "int" } } - Method { name: "Constructible"; isCloned: true; isConstructor: true } + Method { name: "Constructible"; isCloned: true; isConstructor: true; lineNumber: 564 } })")); } @@ -800,7 +827,7 @@ void tst_qmltyperegistrar::structuredValueType() exports: ["QmlTypeRegistrarTest/structured 1.0"] isStructured: true exportMetaObjectRevisions: [256] - Property { name: "i"; type: "int"; index: 0; isFinal: true } + Property { name: "i"; type: "int"; index: 0; lineNumber: 575; isFinal: true } })")); } @@ -842,56 +869,67 @@ void tst_qmltyperegistrar::typedEnum() Enum { name: "UChar" type: "quint8" + lineNumber: 604 values: ["V0"] } Enum { name: "Int8_T" type: "qint8" + lineNumber: 606 values: ["V1"] } Enum { name: "UInt8_T" type: "quint8" + lineNumber: 608 values: ["V2"] } Enum { name: "Int16_T" type: "short" + lineNumber: 610 values: ["V3"] } Enum { name: "UInt16_T" type: "ushort" + lineNumber: 612 values: ["V4"] } Enum { name: "Int32_T" type: "int" + lineNumber: 614 values: ["V5"] } Enum { name: "UInt32_T" type: "uint" + lineNumber: 616 values: ["V6"] } Enum { name: "S" type: "short" + lineNumber: 622 values: ["A", "B", "C"] } Enum { name: "T" type: "ushort" + lineNumber: 627 values: ["D", "E", "F"] } Enum { name: "U" type: "qint8" + lineNumber: 632 values: ["G", "H", "I"] } Enum { name: "V" type: "quint8" + lineNumber: 637 values: ["J", "K", "L"] } })")); @@ -908,6 +946,7 @@ void tst_qmltyperegistrar::listSignal() prototype: "QObject" Signal { name: "objectListHappened" + lineNumber: 649 Parameter { type: "QObjectList" } } })")); @@ -926,6 +965,7 @@ void tst_qmltyperegistrar::withNamespace() type: "int" read: "bar" index: 0 + lineNumber: 655 isReadonly: true isPropertyConstant: true } @@ -944,6 +984,7 @@ void tst_qmltyperegistrar::withNamespace() type: "int" read: "bar" index: 0 + lineNumber: 676 isReadonly: true isPropertyConstant: true } @@ -960,6 +1001,7 @@ void tst_qmltyperegistrar::withNamespace() type: "int" read: "foo" index: 0 + lineNumber: 666 isReadonly: true isPropertyConstant: true } @@ -1003,7 +1045,15 @@ void tst_qmltyperegistrar::valueTypeSelfReference() lineNumber: 708 name: "QPersistentModelIndexValueType" accessSemantics: "value" - Property { name: "row"; type: "int"; read: "row"; index: 0; isReadonly: true; isFinal: true } + Property { + name: "row" + type: "int" + read: "row" + index: 0 + lineNumber: 711 + isReadonly: true + isFinal: true + } })")); } @@ -1115,10 +1165,10 @@ void tst_qmltyperegistrar::longNumberTypes() prototype: "QObject" exports: ["QmlTypeRegistrarTest/LongNumberTypes 1.0"] exportMetaObjectRevisions: [256] - Property { name: "a"; type: "qlonglong"; index: 0 } - Property { name: "b"; type: "qlonglong"; index: 1 } - Property { name: "c"; type: "qulonglong"; index: 2 } - Property { name: "d"; type: "qulonglong"; index: 3 } + Property { name: "a"; type: "qlonglong"; index: 0; lineNumber: 772 } + Property { name: "b"; type: "qlonglong"; index: 1; lineNumber: 773 } + Property { name: "c"; type: "qulonglong"; index: 2; lineNumber: 774 } + Property { name: "d"; type: "qulonglong"; index: 3; lineNumber: 775 } })")); } @@ -1142,7 +1192,13 @@ void tst_qmltyperegistrar::constReturnType() prototype: "QObject" exports: ["QmlTypeRegistrarTest/ConstInvokable 1.0"] exportMetaObjectRevisions: [256] - Method { name: "getObject"; type: "QObject"; isPointer: true; isTypeConstant: true } + Method { + name: "getObject" + type: "QObject" + isPointer: true + isTypeConstant: true + lineNumber: 796 + } })")); } @@ -1156,7 +1212,15 @@ void tst_qmltyperegistrar::usingDeclaration() prototype: "QObject" exports: ["QmlTypeRegistrarTest/WithMyInt 1.0"] exportMetaObjectRevisions: [256] - Property { name: "a"; type: "int"; read: "a"; index: 0; isReadonly: true; isPropertyConstant: true } + Property { + name: "a" + type: "int" + read: "a" + index: 0 + lineNumber: 812 + isReadonly: true + isPropertyConstant: true + } })")); } @@ -1205,9 +1269,9 @@ void tst_qmltyperegistrar::slotsBeforeInvokables() name: "SlotsBeforeInvokables" accessSemantics: "reference" prototype: "QObject" - Method { name: "bar" } - Method { name: "foo" } - Method { name: "baz" } + Method { name: "bar"; lineNumber: 833 } + Method { name: "foo"; lineNumber: 831 } + Method { name: "baz"; lineNumber: 835 } })")); } @@ -1221,7 +1285,7 @@ void tst_qmltyperegistrar::omitQQmlV4FunctionPtrArg() prototype: "QObject" exports: ["QmlTypeRegistrarTest/JavaScriptFunction 1.0"] exportMetaObjectRevisions: [256] - Method { name: "jsfunc"; isJavaScriptFunction: true } + Method { name: "jsfunc"; isJavaScriptFunction: true; lineNumber: 844 } })")); } @@ -1241,6 +1305,7 @@ void tst_qmltyperegistrar::preserveVoidStarPropTypes() isPointer: true read: "void1" index: 0 + lineNumber: 858 isReadonly: true isPropertyConstant: true } @@ -1250,6 +1315,7 @@ void tst_qmltyperegistrar::preserveVoidStarPropTypes() isPointer: true read: "void2" index: 1 + lineNumber: 859 isReadonly: true isPropertyConstant: true } @@ -1271,7 +1337,7 @@ void tst_qmltyperegistrar::inaccessibleBase() name: "InaccessibleBase" accessSemantics: "reference" prototype: "QObject" - Property { name: "a"; type: "int"; index: 0; isPropertyConstant: true } + Property { name: "a"; type: "int"; index: 0; lineNumber: 12; isPropertyConstant: true } })")); QVERIFY(!qmltypesData.contains(R"(name: "InaccessibleProperty")")); @@ -1289,6 +1355,7 @@ void tst_qmltyperegistrar::inaccessibleBase() type: "InaccessibleProperty" isPointer: true index: 0 + lineNumber: 872 isPropertyConstant: true } })")); @@ -1333,7 +1400,15 @@ void tst_qmltyperegistrar::derivedFromInvisible() prototype: "InvisibleBase" exports: ["QmlTypeRegistrarTest/DerivedFromInvisible 1.0"] exportMetaObjectRevisions: [256] - Property { name: "b"; type: "int"; read: "b"; index: 0; isReadonly: true; isPropertyConstant: true } + Property { + name: "b" + type: "int" + read: "b" + index: 0 + lineNumber: 890 + isReadonly: true + isPropertyConstant: true + } })")); } @@ -1351,6 +1426,7 @@ void tst_qmltyperegistrar::foreignNamespacedWithEnum() Enum { name: "Enum" isScoped: true + lineNumber: 903 values: ["ValueA", "ValueB"] } })"));