Add ui.qml support to code mode and editor

Change-Id: I6d818ddad1e7467578c63161c278455ef6ac743e
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
This commit is contained in:
Fawzi Mohamed
2014-10-13 16:46:30 +02:00
parent 65aef999ce
commit 419d4e4411
11 changed files with 74 additions and 17 deletions

View File

@@ -1390,12 +1390,20 @@ void Check::warnAboutUnnecessarySuppressions()
bool Check::isQtQuick2() const bool Check::isQtQuick2() const
{ {
foreach (const Import &import, _imports->all()) { if (_doc->language() == Dialect::Qml) {
if (import.info.name() == QLatin1String("QtQuick") foreach (const Import &import, _imports->all()) {
&& import.info.version().majorVersion() == 2) if (import.info.name() == QLatin1String("QtQuick")
return true; && import.info.version().majorVersion() == 2)
return true;
}
return false;
} }
return false; return _doc->language() == Dialect::QmlQtQuick2 || _doc->language() == Dialect::QmlQtQuick2Ui;
}
bool Check::isQtQuick2Ui() const
{
return _doc->language() == Dialect::QmlQtQuick2Ui;
} }
bool Check::visit(NewExpression *ast) bool Check::visit(NewExpression *ast)

View File

@@ -118,6 +118,7 @@ private:
void warnAboutUnnecessarySuppressions(); void warnAboutUnnecessarySuppressions();
bool isQtQuick2() const; bool isQtQuick2() const;
bool isQtQuick2Ui() const;
AST::Node *parent(int distance = 0); AST::Node *parent(int distance = 0);

View File

@@ -38,6 +38,7 @@ bool Dialect::isQmlLikeLanguage() const
case Dialect::Qml: case Dialect::Qml:
case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick1:
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
case Dialect::QmlQbs: case Dialect::QmlQbs:
case Dialect::QmlProject: case Dialect::QmlProject:
case Dialect::QmlTypeInfo: case Dialect::QmlTypeInfo:
@@ -56,6 +57,7 @@ bool Dialect::isFullySupportedLanguage() const
case Dialect::Qml: case Dialect::Qml:
case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick1:
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
return true; return true;
case Dialect::NoLanguage: case Dialect::NoLanguage:
case Dialect::AnyLanguage: case Dialect::AnyLanguage:
@@ -73,6 +75,7 @@ bool Dialect::isQmlLikeOrJsLanguage() const
case Dialect::Qml: case Dialect::Qml:
case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick1:
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
case Dialect::QmlQbs: case Dialect::QmlQbs:
case Dialect::QmlProject: case Dialect::QmlProject:
case Dialect::QmlTypeInfo: case Dialect::QmlTypeInfo:
@@ -97,6 +100,8 @@ QString Dialect::toString() const
return QLatin1String("QmlQtQuick1"); return QLatin1String("QmlQtQuick1");
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
return QLatin1String("QmlQtQuick2"); return QLatin1String("QmlQtQuick2");
case Dialect::QmlQtQuick2Ui:
return QLatin1String("QmlQtQuick2Ui");
case Dialect::NoLanguage: case Dialect::NoLanguage:
return QLatin1String("NoLanguage"); return QLatin1String("NoLanguage");
case Dialect::AnyLanguage: case Dialect::AnyLanguage:
@@ -178,6 +183,9 @@ bool Dialect::restrictLanguage(const Dialect &l2)
} }
if (i2 && !i1) if (i2 && !i1)
return true; return true;
qDebug() << toString() << "restrictTo" << l2.toString() << "failed";
qDebug() << ll1 << ll2;
qDebug() << i1 << i2;
QList<Dialect> qmlLangs = Dialect(Qml).companionLanguages(); QList<Dialect> qmlLangs = Dialect(Qml).companionLanguages();
if (qmlLangs.contains(*this) && qmlLangs.contains(l2)) if (qmlLangs.contains(*this) && qmlLangs.contains(l2))
*this = Dialect::Qml; *this = Dialect::Qml;
@@ -199,16 +207,22 @@ QList<Dialect> Dialect::companionLanguages() const
langs << Dialect::JavaScript; langs << Dialect::JavaScript;
break; break;
case Dialect::Qml: case Dialect::Qml:
langs << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 << Dialect::JavaScript; langs << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 << Dialect::QmlQtQuick2Ui
<< Dialect::JavaScript;
break; break;
case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick1:
case Dialect::QmlQtQuick2:
langs << Dialect::Qml << Dialect::JavaScript; langs << Dialect::Qml << Dialect::JavaScript;
break; break;
case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
langs.clear();
langs << Dialect::QmlQtQuick2 << Dialect::QmlQtQuick2Ui << Dialect::Qml
<< Dialect::JavaScript;
break;
case Dialect::AnyLanguage: case Dialect::AnyLanguage:
langs << Dialect::JavaScript << Dialect::Json << Dialect::QmlProject << Dialect:: QmlQbs langs << Dialect::JavaScript << Dialect::Json << Dialect::QmlProject << Dialect:: QmlQbs
<< Dialect::QmlTypeInfo << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2 << Dialect::QmlTypeInfo << Dialect::QmlQtQuick1 << Dialect::QmlQtQuick2
<< Dialect::Qml; << Dialect::QmlQtQuick2Ui << Dialect::Qml;
break; break;
case Dialect::NoLanguage: case Dialect::NoLanguage:
return QList<Dialect>(); // return at least itself? return QList<Dialect>(); // return at least itself?

View File

@@ -51,7 +51,8 @@ public:
QmlQbs = 6, QmlQbs = 6,
QmlProject = 7, QmlProject = 7,
QmlTypeInfo = 8, QmlTypeInfo = 8,
AnyLanguage = 9, QmlQtQuick2Ui = 9,
AnyLanguage = 10,
}; };
Dialect(Enum dialect = NoLanguage) Dialect(Enum dialect = NoLanguage)
: m_dialect(dialect) : m_dialect(dialect)

View File

@@ -78,6 +78,8 @@ QMLJS_EXPORT Q_LOGGING_CATEGORY(qmljsLog, "qtc.qmljs.common")
static ModelManagerInterface *g_instance = 0; static ModelManagerInterface *g_instance = 0;
const char qtQuickUISuffix[] = "ui.qml";
static QStringList environmentImportPaths() static QStringList environmentImportPaths()
{ {
QStringList paths; QStringList paths;
@@ -148,6 +150,7 @@ static QHash<QString, Dialect> defaultLanguageMapping()
res[QLatin1String("qmlproject")] = Dialect::QmlProject; res[QLatin1String("qmlproject")] = Dialect::QmlProject;
res[QLatin1String("json")] = Dialect::Json; res[QLatin1String("json")] = Dialect::Json;
res[QLatin1String("qbs")] = Dialect::QmlQbs; res[QLatin1String("qbs")] = Dialect::QmlQbs;
res[QLatin1String(qtQuickUISuffix)] = Dialect::QmlQtQuick2Ui;
return res; return res;
} }
@@ -159,7 +162,16 @@ Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName)
else else
lMapping = defaultLanguageMapping(); lMapping = defaultLanguageMapping();
const QFileInfo info(fileName); const QFileInfo info(fileName);
const QString fileSuffix = info.suffix(); QString fileSuffix = info.suffix();
/*
* I was reluctant to use complete suffix in all cases, because it is a huge
* change in behaivour. But in case of .qml this should be safe.
*/
if (fileSuffix == QLatin1String("qml"))
fileSuffix = info.completeSuffix();
return lMapping.value(fileSuffix, Dialect::NoLanguage); return lMapping.value(fileSuffix, Dialect::NoLanguage);
} }
@@ -856,6 +868,8 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
if (language == Dialect::Qml if (language == Dialect::Qml
&& (mainLanguage == Dialect::QmlQtQuick1 || mainLanguage == Dialect::QmlQtQuick2)) && (mainLanguage == Dialect::QmlQtQuick1 || mainLanguage == Dialect::QmlQtQuick2))
language = mainLanguage; language = mainLanguage;
if (language == Dialect::Qml && mainLanguage == Dialect::QmlQtQuick2Ui)
language = Dialect::QmlQtQuick2;
QString contents; QString contents;
int documentRevision = 0; int documentRevision = 0;
@@ -1314,7 +1328,8 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
&& ((vCtx.language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage) && ((vCtx.language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage)
|| (vCtx.language == Dialect::Qml || (vCtx.language == Dialect::Qml
&& (doc->language() == Dialect::QmlQtQuick1 && (doc->language() == Dialect::QmlQtQuick1
|| doc->language() == Dialect::QmlQtQuick2)))) || doc->language() == Dialect::QmlQtQuick2
|| doc->language() == Dialect::QmlQtQuick2Ui))))
res.language = doc->language(); res.language = doc->language();
ProjectInfo info; ProjectInfo info;
if (!doc.isNull()) if (!doc.isNull())
@@ -1344,8 +1359,9 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
res.maybeAddPath(info.qtImportsPath); res.maybeAddPath(info.qtImportsPath);
// fallthrough // fallthrough
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui:
{ {
if (res.language == Dialect::QmlQtQuick2) if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui)
res.maybeAddPath(info.qtQmlPath); res.maybeAddPath(info.qtQmlPath);
QList<ProjectInfo> allProjects; QList<ProjectInfo> allProjects;
{ {
@@ -1382,13 +1398,14 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
foreach (const QString &path, defaultVCtx.paths) foreach (const QString &path, defaultVCtx.paths)
res.maybeAddPath(path); res.maybeAddPath(path);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml
|| res.language == Dialect::QmlQtQuick2) || res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui)
res.maybeAddPath(info.qtImportsPath); res.maybeAddPath(info.qtImportsPath);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml
|| res.language == Dialect::QmlQtQuick1) || res.language == Dialect::QmlQtQuick1)
res.maybeAddPath(info.qtQmlPath); res.maybeAddPath(info.qtQmlPath);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml
|| res.language == Dialect::QmlQtQuick1 || res.language == Dialect::QmlQtQuick2) { || res.language == Dialect::QmlQtQuick1 || res.language == Dialect::QmlQtQuick2
|| res.language == Dialect::QmlQtQuick2Ui) {
foreach (const QString &path, environmentImportPaths()) foreach (const QString &path, environmentImportPaths())
res.maybeAddPath(path); res.maybeAddPath(path);
} }
@@ -1406,7 +1423,8 @@ ViewerContext ModelManagerInterface::defaultVContext(Dialect language,
if (language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage) if (language == Dialect::AnyLanguage && doc->language() != Dialect::NoLanguage)
language = doc->language(); language = doc->language();
else if (language == Dialect::Qml && else if (language == Dialect::Qml &&
(doc->language() == Dialect::QmlQtQuick1 || doc->language() == Dialect::QmlQtQuick2)) (doc->language() == Dialect::QmlQtQuick1 || doc->language() == Dialect::QmlQtQuick2
|| doc->language() == Dialect::QmlQtQuick2Ui))
language = doc->language(); language = doc->language();
} }
ViewerContext defaultCtx; ViewerContext defaultCtx;

View File

@@ -71,7 +71,9 @@ bool ViewerContext::languageIsCompatible(Dialect l) const
case Dialect::QmlQtQuick1: case Dialect::QmlQtQuick1:
return l == Dialect::Qml || l == Dialect::QmlQtQuick1 || l == Dialect::JavaScript; return l == Dialect::Qml || l == Dialect::QmlQtQuick1 || l == Dialect::JavaScript;
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::JavaScript; case Dialect::QmlQtQuick2Ui:
return l == Dialect::Qml || l == Dialect::QmlQtQuick2 || l == Dialect::QmlQtQuick2Ui
|| l == Dialect::JavaScript;
case Dialect::AnyLanguage: case Dialect::AnyLanguage:
return true; return true;
case Dialect::NoLanguage: case Dialect::NoLanguage:

View File

@@ -366,6 +366,7 @@ static bool checkIfEditorIsQtQuick(Core::IEditor *editor)
if (!document.isNull()) if (!document.isNull())
return document->language() == QmlJS::Dialect::QmlQtQuick1 return document->language() == QmlJS::Dialect::QmlQtQuick1
|| document->language() == QmlJS::Dialect::QmlQtQuick2 || document->language() == QmlJS::Dialect::QmlQtQuick2
|| document->language() == QmlJS::Dialect::QmlQtQuick2Ui
|| document->language() == QmlJS::Dialect::Qml; || document->language() == QmlJS::Dialect::Qml;
} }

View File

@@ -4,7 +4,7 @@
<alias type="text/x-qml"/> <alias type="text/x-qml"/>
<sub-class-of type="text/plain"/> <sub-class-of type="text/plain"/>
<comment>QML file</comment> <comment>QML file</comment>
<glob pattern="*.qml"/> <glob weight="50" pattern="*.qml"/>
</mime-type> </mime-type>
<mime-type type="application/x-qt.qbs+qml"> <mime-type type="application/x-qt.qbs+qml">
<alias type="text/x-qt.qbs+qml"/> <alias type="text/x-qt.qbs+qml"/>
@@ -12,6 +12,12 @@
<comment>Qt Build Suite file</comment> <comment>Qt Build Suite file</comment>
<glob pattern="*.qbs"/> <glob pattern="*.qbs"/>
</mime-type> </mime-type>
<mime-type type="application/x-qt.ui+qml">
<alias type="text/x-qt.ui+qml"/>
<sub-class-of type="application/x-qml"/>
<comment>QtQuick Designer ui file</comment>
<glob weight="100" pattern="*.ui.qml"/>
</mime-type>
<mime-type type="application/x-qmlproject"> <mime-type type="application/x-qmlproject">
<alias type="text/x-qmlproject"/> <alias type="text/x-qmlproject"/>
<sub-class-of type="application/x-qml"/> <sub-class-of type="application/x-qml"/>

View File

@@ -127,6 +127,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit
QmlBundle b2(defaultQt5QtQuick2Bundle()); QmlBundle b2(defaultQt5QtQuick2Bundle());
bundles.mergeBundleForLanguage(Dialect::Qml, b2); bundles.mergeBundleForLanguage(Dialect::Qml, b2);
bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, b2); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, b2);
bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2Ui, b2);
return; return;
} }
QString qtImportsPath = qtVersion->qmakeProperty("QT_INSTALL_IMPORTS"); QString qtImportsPath = qtVersion->qmakeProperty("QT_INSTALL_IMPORTS");
@@ -181,6 +182,7 @@ void BasicBundleProvider::mergeBundlesForKit(ProjectExplorer::Kit *kit
qtQuick2Bundle.replaceVars(myReplacements); qtQuick2Bundle.replaceVars(myReplacements);
bundles.mergeBundleForLanguage(Dialect::Qml, qtQuick2Bundle); bundles.mergeBundleForLanguage(Dialect::Qml, qtQuick2Bundle);
bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, qtQuick2Bundle); bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2, qtQuick2Bundle);
bundles.mergeBundleForLanguage(Dialect::QmlQtQuick2Ui, qtQuick2Bundle);
} }
} }

View File

@@ -189,6 +189,9 @@ QHash<QString,QmlJS::Dialect> ModelManager::languageForSuffix() const
MimeType qmlProjectSourceTy = MimeDatabase::findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE)); MimeType qmlProjectSourceTy = MimeDatabase::findByType(QLatin1String(Constants::QMLPROJECT_MIMETYPE));
foreach (const QString &suffix, qmlProjectSourceTy.suffixes()) foreach (const QString &suffix, qmlProjectSourceTy.suffixes())
res[suffix] = Dialect::QmlProject; res[suffix] = Dialect::QmlProject;
MimeType qmlUiSourceTy = MimeDatabase::findByType(QLatin1String(Constants::QMLUI_MIMETYPE));
foreach (const QString &suffix, qmlUiSourceTy.suffixes())
res[suffix] = Dialect::QmlQtQuick2Ui;
MimeType jsonSourceTy = MimeDatabase::findByType(QLatin1String(Constants::JSON_MIMETYPE)); MimeType jsonSourceTy = MimeDatabase::findByType(QLatin1String(Constants::JSON_MIMETYPE));
foreach (const QString &suffix, jsonSourceTy.suffixes()) foreach (const QString &suffix, jsonSourceTy.suffixes())
res[suffix] = Dialect::Json; res[suffix] = Dialect::Json;

View File

@@ -39,6 +39,7 @@ const char QML_MIMETYPE[] = "application/x-qml"; // separate def also in project
const char QBS_MIMETYPE[] = "application/x-qt.qbs+qml"; const char QBS_MIMETYPE[] = "application/x-qt.qbs+qml";
const char QMLPROJECT_MIMETYPE[] = "application/x-qmlproject"; const char QMLPROJECT_MIMETYPE[] = "application/x-qmlproject";
const char QMLTYPES_MIMETYPE[] = "application/x-qt.meta-info+qml"; const char QMLTYPES_MIMETYPE[] = "application/x-qt.meta-info+qml";
const char QMLUI_MIMETYPE[] = "application/x-qt.ui+qml";
const char JS_MIMETYPE[] = "application/javascript"; const char JS_MIMETYPE[] = "application/javascript";
const char JSON_MIMETYPE[] = "application/json"; const char JSON_MIMETYPE[] = "application/json";