Also support partly specified versions in JS .imports

Task-number: QTBUG-71278
Change-Id: Ie3167d44780a192b5010052eea5192eee8c21c32
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Ulf Hermann 2020-02-20 16:54:35 +01:00
parent 36fb7cf832
commit c5b48c735e
4 changed files with 26 additions and 38 deletions

View File

@ -1052,7 +1052,7 @@ QTypeRevision IRBuilder::extractVersion(const QStringRef &string)
const int dot = string.indexOf(QLatin1Char('.'));
return (dot < 0)
? QTypeRevision::fromVersion(string.toInt(), 0)
? QTypeRevision::fromMajorVersion(string.toInt())
: QTypeRevision::fromVersion(string.left(dot).toInt(), string.mid(dot + 1).toInt());
}

View File

@ -1538,9 +1538,10 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
setError(QCoreApplication::translate("QQmlParser","Imported file must be a script"));
return false;
}
lex();
} else if (_tokenKind == T_IDENTIFIER) {
// .import T_IDENTIFIER (. T_IDENTIFIER)* T_VERSION_NUMBER . T_VERSION_NUMBER as T_IDENTIFIER
// .import T_IDENTIFIER (. T_IDENTIFIER)* (T_VERSION_NUMBER (. T_VERSION_NUMBER)?)? as T_IDENTIFIER
while (true) {
if (!isUriToken(_tokenKind)) {
setError(QCoreApplication::translate("QQmlParser","Invalid module URI"));
@ -1566,31 +1567,27 @@ bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
}
}
if (_tokenKind != T_VERSION_NUMBER) {
setError(QCoreApplication::translate("QQmlParser","Module import requires a version"));
return false; // expected the module version number
if (_tokenKind == T_VERSION_NUMBER) {
version = tokenText();
lex();
if (_tokenKind == T_DOT) {
version += QLatin1Char('.');
lex();
if (_tokenKind != T_VERSION_NUMBER) {
setError(QCoreApplication::translate(
"QQmlParser", "Incomplete version number (dot but no minor)"));
return false; // expected the module version number
}
version += tokenText();
lex();
}
}
version = tokenText();
lex();
if (_tokenKind != T_DOT) {
setError(QCoreApplication::translate( "QQmlParser", "Module import requires a minor version (missing dot)"));
return false; // expected the module version number
}
version += QLatin1Char('.');
lex();
if (_tokenKind != T_VERSION_NUMBER) {
setError(QCoreApplication::translate( "QQmlParser", "Module import requires a minor version (missing number)"));
return false; // expected the module version number
}
version += tokenText();
}
//
// recognize the mandatory `as' followed by the module name
//
if (! (lex() == T_AS && tokenStartLine() == lineNumber)) {
if (! (_tokenKind == T_AS && tokenStartLine() == lineNumber)) {
if (fileImport)
setError(QCoreApplication::translate("QQmlParser", "File import requires a qualifier"));
else

View File

@ -4514,9 +4514,9 @@ void tst_qqmlecmascript::importScripts_data()
QTest::newRow("missing module version")
<< testFileUrl("jsimportfail/missingModuleVersion.qml")
<< false /* compilation should succeed */
<< true /* compilation should succeed */
<< QString()
<< (QStringList() << testFileUrl("jsimportfail/missingModuleVersion.js").toString() + QLatin1String(":1:17: Module import requires a version"))
<< QStringList()
<< QStringList()
<< QVariantList();
@ -4524,7 +4524,7 @@ void tst_qqmlecmascript::importScripts_data()
<< testFileUrl("jsimportfail/malformedModuleVersion.qml")
<< false /* compilation should succeed */
<< QString()
<< (QStringList() << testFileUrl("jsimportfail/malformedModuleVersion.js").toString() + QLatin1String(":1:17: Module import requires a version"))
<< (QStringList() << testFileUrl("jsimportfail/malformedModuleVersion.js").toString() + QLatin1String(":1:17: Module import requires a qualifier"))
<< QStringList()
<< QVariantList();

View File

@ -59,7 +59,7 @@ private slots:
void templateLiteral();
void leadingSemicolonInClass();
void templatedReadonlyProperty();
void qmlImportInJSRequiresFullVersion();
void qmlImportInJS();
void typeAnnotations_data();
void typeAnnotations();
void disallowedTypeAnnotations_data();
@ -361,37 +361,28 @@ void tst_qqmlparser::templatedReadonlyProperty()
QVERIFY(parser.parse());
}
void tst_qqmlparser::qmlImportInJSRequiresFullVersion()
void tst_qqmlparser::qmlImportInJS()
{
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
lexer.setCode(QLatin1String(".import Test 1.0 as T"), 0, false);
QQmlJS::Parser parser(&engine);
bool b = parser.parseProgram();
qDebug() << parser.errorMessage();
QVERIFY(b);
QVERIFY(parser.parseProgram());
}
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
lexer.setCode(QLatin1String(".import Test 1 as T"), 0, false);
QQmlJS::Parser parser(&engine);
QVERIFY(!parser.parseProgram());
}
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
lexer.setCode(QLatin1String(".import Test 1 as T"), 0, false);
QQmlJS::Parser parser(&engine);
QVERIFY(!parser.parseProgram());
QVERIFY(parser.parseProgram());
}
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
lexer.setCode(QLatin1String(".import Test as T"), 0, false);
QQmlJS::Parser parser(&engine);
QVERIFY(!parser.parseProgram());
QVERIFY(parser.parseProgram());
}
}