From 903c6b60cdd6c67b4fa5935d25213625e5f22724 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Fri, 9 Sep 2011 10:55:11 +0200 Subject: QmlJS: Use mime types to distinguish qml and js files. This allows adding patterns to the qml mime type in the options dialog. Previously they were always parsed as js. Change-Id: Ifa344fb6ab8cbcda02becef991cf6807615a1caa Reviewed-on: http://codereview.qt-project.org/4515 Reviewed-by: Leandro T. C. Melo --- src/libs/qmljs/qmljsdocument.cpp | 29 +++++---- src/libs/qmljs/qmljsdocument.h | 21 +++++-- .../filemanager/astobjecttextextractor.cpp | 2 +- .../filemanager/firstdefinitionfinder.cpp | 2 +- .../filemanager/objectlengthcalculator.cpp | 2 +- .../designercore/filemanager/qmlrefactoring.cpp | 2 +- .../designercore/model/modeltotextmerger.cpp | 2 +- .../designercore/model/texttomodelmerger.cpp | 2 +- .../qmljseditor/qmlexpressionundercursor.cpp | 2 +- src/plugins/qmljseditor/qmljsfindreferences.cpp | 13 +++- .../qmljseditor/qmljssemanticinfoupdater.cpp | 8 ++- src/plugins/qmljstools/qmljsmodelmanager.cpp | 73 ++++++++++++++-------- src/plugins/qmljstools/qmljsmodelmanager.h | 4 ++ src/plugins/qmljstools/qmljsrefactoringchanges.cpp | 9 ++- 14 files changed, 114 insertions(+), 57 deletions(-) diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index 831e9fb160..7fb13796ed 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -83,23 +83,20 @@ using namespace QmlJS::AST; */ -Document::Document(const QString &fileName) +Document::Document(const QString &fileName, Language language) : _engine(0) , _pool(0) , _ast(0) , _bind(0) - , _isQmlDocument(false) + , _fileName(QDir::cleanPath(fileName)) , _editorRevision(0) + , _language(language) , _parsedCorrectly(false) - , _fileName(QDir::cleanPath(fileName)) { QFileInfo fileInfo(fileName); _path = QDir::cleanPath(fileInfo.absolutePath()); - // ### Should use mime type - if (fileInfo.suffix() == QLatin1String("qml") - || fileInfo.suffix() == QLatin1String("qmlproject")) { - _isQmlDocument = true; + if (language == QmlLanguage) { _componentName = fileInfo.baseName(); if (! _componentName.isEmpty()) { @@ -123,9 +120,9 @@ Document::~Document() delete _pool; } -Document::Ptr Document::create(const QString &fileName) +Document::Ptr Document::create(const QString &fileName, Language language) { - Document::Ptr doc(new Document(fileName)); + Document::Ptr doc(new Document(fileName, language)); doc->_ptr = doc; return doc; } @@ -137,12 +134,17 @@ Document::Ptr Document::ptr() const bool Document::isQmlDocument() const { - return _isQmlDocument; + return _language == QmlLanguage; } bool Document::isJSDocument() const { - return ! _isQmlDocument; + return _language == JavaScriptLanguage; +} + +Document::Language Document::language() const +{ + return _language; } AST::UiProgram *Document::qmlProgram() const @@ -422,9 +424,10 @@ void Snapshot::remove(const QString &fileName) } Document::Ptr Snapshot::documentFromSource(const QString &code, - const QString &fileName) const + const QString &fileName, + Document::Language language) const { - Document::Ptr newDoc = Document::create(fileName); + Document::Ptr newDoc = Document::create(fileName, language); if (Document::Ptr thisDocument = document(fileName)) { newDoc->_editorRevision = thisDocument->_editorRevision; diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h index b2f824cecb..95a941640c 100644 --- a/src/libs/qmljs/qmljsdocument.h +++ b/src/libs/qmljs/qmljsdocument.h @@ -56,18 +56,26 @@ class QMLJS_EXPORT Document public: typedef QSharedPointer Ptr; + enum Language + { + QmlLanguage = 0, + JavaScriptLanguage = 1, + UnknownLanguage = 2 + }; + protected: - Document(const QString &fileName); + Document(const QString &fileName, Language language); public: ~Document(); - static Document::Ptr create(const QString &fileName); + static Document::Ptr create(const QString &fileName, Language language); Document::Ptr ptr() const; bool isQmlDocument() const; bool isJSDocument() const; + Language language() const; AST::UiProgram *qmlProgram() const; AST::Program *jsProgram() const; @@ -107,15 +115,15 @@ private: NodePool *_pool; AST::Node *_ast; Bind *_bind; - bool _isQmlDocument; - int _editorRevision; - bool _parsedCorrectly; QList _diagnosticMessages; QString _fileName; QString _path; QString _componentName; QString _source; QWeakPointer _ptr; + int _editorRevision; + Language _language : 2; + bool _parsedCorrectly : 1; // for documentFromSource friend class Snapshot; @@ -211,7 +219,8 @@ public: LibraryInfo libraryInfo(const QString &path) const; Document::Ptr documentFromSource(const QString &code, - const QString &fileName) const; + const QString &fileName, + Document::Language language) const; }; } // namespace QmlJS diff --git a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp b/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp index f835dc09d5..14f90ece61 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp @@ -39,7 +39,7 @@ using namespace QmlDesigner; using namespace QmlJS::AST; ASTObjectTextExtractor::ASTObjectTextExtractor(const QString &text): - m_document(Document::create("")) + m_document(Document::create("", Document::QmlLanguage)) { m_document->setSource(text); m_document->parseQml(); diff --git a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp b/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp index 68461eb9f1..fe5a5eedea 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp @@ -41,7 +41,7 @@ using namespace QmlDesigner; using namespace QmlJS::AST; FirstDefinitionFinder::FirstDefinitionFinder(const QString &text): - m_doc(Document::create("")) + m_doc(Document::create("", Document::QmlLanguage)) { m_doc->setSource(text); bool ok = m_doc->parseQml(); diff --git a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp b/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp index df22fa683b..446334547a 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp @@ -39,7 +39,7 @@ using namespace QmlDesigner; using namespace QmlJS::AST; ObjectLengthCalculator::ObjectLengthCalculator(): - m_doc(Document::create("")) + m_doc(Document::create("", Document::QmlLanguage)) { } diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp index eede5d1b17..e3da259382 100644 --- a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp +++ b/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp @@ -61,7 +61,7 @@ bool QmlRefactoring::reparseDocument() // qDebug() << "QmlRefactoring::reparseDocument() new QML source:" << newSource; - Document::Ptr tmpDocument(Document::create("")); + Document::Ptr tmpDocument(Document::create("", Document::QmlLanguage)); tmpDocument->setSource(newSource); if (tmpDocument->parseQml()) { diff --git a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp index 975544868d..4bf2d49cfe 100644 --- a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp @@ -229,7 +229,7 @@ void ModelToTextMerger::applyChanges() if (m_rewriteActions.isEmpty()) return; - Document::Ptr tmpDocument(Document::create(QLatin1String(""))); + Document::Ptr tmpDocument(Document::create(QLatin1String(""), Document::QmlLanguage)); tmpDocument->setSource(m_rewriterView->textModifier()->text()); if (!tmpDocument->parseQml()) { qDebug() << "*** Possible problem: QML file wasn't parsed correctly."; diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 55ba5123f6..fa77d1f855 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -750,7 +750,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH try { Snapshot snapshot = m_rewriterView->textModifier()->getSnapshot(); const QString fileName = url.toLocalFile(); - Document::Ptr doc = Document::create(fileName.isEmpty() ? QLatin1String("") : fileName); + Document::Ptr doc = Document::create(fileName.isEmpty() ? QLatin1String("") : fileName, Document::QmlLanguage); doc->setSource(data); doc->parseQml(); diff --git a/src/plugins/qmljseditor/qmlexpressionundercursor.cpp b/src/plugins/qmljseditor/qmlexpressionundercursor.cpp index 8b9a8a66a4..60e90b60de 100644 --- a/src/plugins/qmljseditor/qmlexpressionundercursor.cpp +++ b/src/plugins/qmljseditor/qmlexpressionundercursor.cpp @@ -136,7 +136,7 @@ QmlJS::AST::ExpressionNode *QmlExpressionUnderCursor::operator()(const QTextCurs ExpressionUnderCursor expressionUnderCursor; _text = expressionUnderCursor(cursor); - exprDoc = Document::create(QLatin1String("")); + exprDoc = Document::create(QLatin1String(""), Document::JavaScriptLanguage); exprDoc->setSource(_text); exprDoc->parseExpression(); diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index d8afb967fc..8581255843 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include "qmljseditorconstants.h" @@ -799,11 +800,19 @@ static void find_helper(QFutureInterface &future, QHashIterator< QString, QPair > it(workingCopy.all()); while (it.hasNext()) { it.next(); - Document::Ptr oldDoc = snapshot.document(it.key()); + const QString fileName = it.key(); + Document::Ptr oldDoc = snapshot.document(fileName); if (oldDoc && oldDoc->editorRevision() == it.value().second) continue; - Document::Ptr newDoc = snapshot.documentFromSource(it.key(), it.value().first); + Document::Language language; + if (oldDoc) + language = oldDoc->language(); + else + language = QmlJSTools::languageOfFile(fileName); + + Document::Ptr newDoc = snapshot.documentFromSource(it.value().first, fileName, + language); newDoc->parse(); snapshot.insert(newDoc); } diff --git a/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp b/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp index 6ba69bd424..8bc7c47a58 100644 --- a/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp +++ b/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp @@ -37,6 +37,7 @@ #include #include #include +#include namespace QmlJSEditor { namespace Internal { @@ -122,7 +123,12 @@ SemanticInfo SemanticInfoUpdater::semanticInfo(const SemanticInfoUpdaterSource & if (! doc) { snapshot = source.snapshot; - doc = snapshot.documentFromSource(source.code, source.fileName); + QmlJS::Document::Language language; + if (m_lastSemanticInfo.document) + language = m_lastSemanticInfo.document->language(); + else + language = QmlJSTools::languageOfFile(source.fileName); + doc = snapshot.documentFromSource(source.code, source.fileName, language); doc->setEditorRevision(source.revision); doc->parse(); snapshot.insert(doc); diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index 054776c184..aff7cd4cb3 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -71,6 +71,47 @@ using namespace QmlJSTools::Internal; static QStringList environmentImportPaths(); +QmlJS::Document::Language QmlJSTools::languageOfFile(const QString &fileName) +{ + QStringList jsSuffixes("js"); + QStringList qmlSuffixes("qml"); + + if (Core::ICore::instance()) { + Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase(); + Core::MimeType jsSourceTy = db->findByType(Constants::JS_MIMETYPE); + jsSuffixes = jsSourceTy.suffixes(); + Core::MimeType qmlSourceTy = db->findByType(Constants::QML_MIMETYPE); + qmlSuffixes = qmlSourceTy.suffixes(); + } + + const QFileInfo info(fileName); + const QString fileSuffix = info.suffix(); + if (jsSuffixes.contains(fileSuffix)) + return QmlJS::Document::JavaScriptLanguage; + if (qmlSuffixes.contains(fileSuffix)) + return QmlJS::Document::QmlLanguage; + return QmlJS::Document::UnknownLanguage; +} + +QStringList QmlJSTools::qmlAndJsGlobPatterns() +{ + QStringList pattern; + if (Core::ICore::instance()) { + Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase(); + Core::MimeType jsSourceTy = db->findByType(Constants::JS_MIMETYPE); + Core::MimeType qmlSourceTy = db->findByType(Constants::QML_MIMETYPE); + + QStringList pattern; + foreach (const Core::MimeGlobPattern &glob, jsSourceTy.globPatterns()) + pattern << glob.regExp().pattern(); + foreach (const Core::MimeGlobPattern &glob, qmlSourceTy.globPatterns()) + pattern << glob.regExp().pattern(); + } else { + pattern << "*.qml" << "*.js"; + } + return pattern; +} + ModelManager::ModelManager(QObject *parent): ModelManagerInterface(parent), m_core(Core::ICore::instance()), @@ -349,22 +390,7 @@ void ModelManager::updateLibraryInfo(const QString &path, const LibraryInfo &inf static QStringList qmlFilesInDirectory(const QString &path) { - QStringList pattern; - if (Core::ICore::instance()) { - // ### It would suffice to build pattern once. This function needs to be thread-safe. - Core::MimeDatabase *db = Core::ICore::instance()->mimeDatabase(); - Core::MimeType jsSourceTy = db->findByType(Constants::JS_MIMETYPE); - Core::MimeType qmlSourceTy = db->findByType(Constants::QML_MIMETYPE); - - QStringList pattern; - foreach (const Core::MimeGlobPattern &glob, jsSourceTy.globPatterns()) - pattern << glob.regExp().pattern(); - foreach (const Core::MimeGlobPattern &glob, qmlSourceTy.globPatterns()) - pattern << glob.regExp().pattern(); - } else { - pattern << "*.qml" << "*.js"; - } - + const QStringList pattern = qmlAndJsGlobPatterns(); QStringList files; const QDir dir(path); @@ -527,15 +553,6 @@ void ModelManager::parse(QFutureInterface &future, ModelManager *modelManager, bool emitDocChangedOnDisk) { - Core::MimeDatabase *db = 0; - Core::MimeType jsSourceTy; - Core::MimeType qmlSourceTy; - if (Core::ICore::instance()) { - db = Core::ICore::instance()->mimeDatabase(); - jsSourceTy = db->findByType(QLatin1String("application/javascript")); - qmlSourceTy = db->findByType(QLatin1String("application/x-qml")); - } - int progressRange = files.size(); future.setProgressRange(0, progressRange); @@ -549,6 +566,10 @@ void ModelManager::parse(QFutureInterface &future, const QString fileName = files.at(i); + Document::Language language = languageOfFile(fileName); + if (language == Document::UnknownLanguage) + continue; + QString contents; int documentRevision = 0; @@ -566,7 +587,7 @@ void ModelManager::parse(QFutureInterface &future, } } - Document::Ptr doc = Document::create(fileName); + Document::Ptr doc = Document::create(fileName, language); doc->setEditorRevision(documentRevision); doc->setSource(contents); doc->parse(); diff --git a/src/plugins/qmljstools/qmljsmodelmanager.h b/src/plugins/qmljstools/qmljsmodelmanager.h index 4fd79063b9..e95c65be2a 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.h +++ b/src/plugins/qmljstools/qmljsmodelmanager.h @@ -55,6 +55,10 @@ class CppModelManagerInterface; } namespace QmlJSTools { + +QMLJSTOOLS_EXPORT QmlJS::Document::Language languageOfFile(const QString &fileName); +QMLJSTOOLS_EXPORT QStringList qmlAndJsGlobPatterns(); + namespace Internal { class PluginDumper; diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 0c01f0cea7..56b9d8486b 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -33,6 +33,7 @@ #include "qmljsrefactoringchanges.h" #include "qmljsqtstylecodeformatter.h" #include "qmljstoolsconstants.h" +#include "qmljsmodelmanager.h" #include #include @@ -112,7 +113,11 @@ QmlJSRefactoringChangesData *QmlJSRefactoringChanges::data() const QmlJSRefactoringFile::QmlJSRefactoringFile(const QString &fileName, const QSharedPointer &data) : RefactoringFile(fileName, data) -{ } +{ + // the RefactoringFile is invalid if its not for a file with qml or js code + if (languageOfFile(fileName) == Document::UnknownLanguage) + m_fileName.clear(); +} QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document) : RefactoringFile(editor) @@ -128,7 +133,7 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const const QString name = fileName(); const Snapshot &snapshot = data()->m_snapshot; - m_qmljsDocument = snapshot.documentFromSource(source, name); + m_qmljsDocument = snapshot.documentFromSource(source, name, languageOfFile(name)); m_qmljsDocument->parse(); } -- cgit v1.2.1