diff options
author | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2015-07-28 11:26:29 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@theqtcompany.com> | 2015-07-28 12:50:58 +0000 |
commit | 495f82585322365c681d2af65954f09af1dbb29a (patch) | |
tree | 29791e286fb5f564fdebf29a9dfdf6e93b67f210 | |
parent | b9bead2be7feab7db1a1d352ebe890db79703436 (diff) |
Decouple ItemReader and ItemReaderASTVisitor.
Change-Id: I67191f686a3fdbc27186422c3ba3bd9f1f1b9c0c
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r-- | src/lib/corelib/corelib.qbs | 2 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreader.cpp | 129 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreader.h | 29 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreaderastvisitor.cpp | 53 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreaderastvisitor.h | 21 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreadervisitorstate.cpp | 168 | ||||
-rw-r--r-- | src/lib/corelib/language/itemreadervisitorstate.h | 70 | ||||
-rw-r--r-- | src/lib/corelib/language/language.pri | 2 |
8 files changed, 293 insertions, 181 deletions
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs index d0b42354b..ead8c5f5a 100644 --- a/src/lib/corelib/corelib.qbs +++ b/src/lib/corelib/corelib.qbs @@ -230,6 +230,8 @@ QbsLibrary { "itemreader.h", "itemreaderastvisitor.cpp", "itemreaderastvisitor.h", + "itemreadervisitorstate.cpp", + "itemreadervisitorstate.h", "jsimports.h", "language.cpp", "language.h", diff --git a/src/lib/corelib/language/itemreader.cpp b/src/lib/corelib/language/itemreader.cpp index 4b1f970cc..de3e78eca 100644 --- a/src/lib/corelib/language/itemreader.cpp +++ b/src/lib/corelib/language/itemreader.cpp @@ -29,80 +29,19 @@ ****************************************************************************/ #include "itemreader.h" -#include "asttools.h" -#include "itemreaderastvisitor.h" -#include <logging/translator.h> -#include <parser/qmljsengine_p.h> -#include <parser/qmljslexer_p.h> -#include <parser/qmljsparser_p.h> -#include <tools/error.h> -#include <QExplicitlySharedDataPointer> -#include <QFile> -#include <QFileInfo> -#include <QSharedData> -#include <QTextStream> + +#include "itemreadervisitorstate.h" namespace qbs { namespace Internal { -class ASTCacheValueData : public QSharedData -{ - Q_DISABLE_COPY(ASTCacheValueData) -public: - ASTCacheValueData() - : ast(0) - , processing(false) - { - } - - QString code; - QbsQmlJS::Engine engine; - QbsQmlJS::AST::UiProgram *ast; - bool processing; -}; - -class ASTCacheValue -{ -public: - ASTCacheValue() - : d(new ASTCacheValueData) - { - } - - ASTCacheValue(const ASTCacheValue &other) - : d(other.d) - { - } - - void setProcessingFlag(bool b) { d->processing = b; } - bool isProcessing() const { return d->processing; } - - void setCode(const QString &code) { d->code = code; } - QString code() const { return d->code; } - - QbsQmlJS::Engine *engine() const { return &d->engine; } - - void setAst(QbsQmlJS::AST::UiProgram *ast) { d->ast = ast; } - QbsQmlJS::AST::UiProgram *ast() const { return d->ast; } - bool isValid() const { return d->ast; } - -private: - QExplicitlySharedDataPointer<ASTCacheValueData> d; -}; - -class ItemReader::ASTCache : public QHash<QString, ASTCacheValue> {}; - - -ItemReader::ItemReader(const Logger &logger) - : m_pool(0) - , m_logger(logger) - , m_astCache(new ASTCache) +ItemReader::ItemReader(const Logger &logger) : m_visitorState(new ItemReaderVisitorState(logger)) { } ItemReader::~ItemReader() { - delete m_astCache; + delete m_visitorState; } void ItemReader::setSearchPaths(const QStringList &searchPaths) @@ -134,70 +73,14 @@ QStringList ItemReader::searchPaths() const return paths; } -void ItemReader::cacheDirectoryEntries(const QString &dirPath, const QStringList &entries) -{ - m_directoryEntries.insert(dirPath, entries); -} - -bool ItemReader::findDirectoryEntries(const QString &dirPath, QStringList *entries) const -{ - const QHash<QString, QStringList>::ConstIterator it = m_directoryEntries.constFind(dirPath); - if (it == m_directoryEntries.constEnd()) - return false; - *entries = it.value(); - return true; -} - Item *ItemReader::readFile(const QString &filePath) { - return internalReadFile(filePath).rootItem; + return m_visitorState->readFile(filePath, searchPaths(), m_pool); } QSet<QString> ItemReader::filesRead() const { - return m_filesRead; -} - -ItemReaderResult ItemReader::internalReadFile(const QString &filePath) -{ - ASTCacheValue &cacheValue = (*m_astCache)[filePath]; - if (cacheValue.isValid()) { - if (Q_UNLIKELY(cacheValue.isProcessing())) - throw ErrorInfo(Tr::tr("Loop detected when importing '%1'.").arg(filePath)); - } else { - QFile file(filePath); - if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) - throw ErrorInfo(Tr::tr("Cannot open '%1'.").arg(filePath)); - - m_filesRead.insert(filePath); - const QString code = QTextStream(&file).readAll(); - QbsQmlJS::Lexer lexer(cacheValue.engine()); - lexer.setCode(code, 1); - QbsQmlJS::Parser parser(cacheValue.engine()); - - file.close(); - if (!parser.parse()) { - QList<QbsQmlJS::DiagnosticMessage> parserMessages = parser.diagnosticMessages(); - if (Q_UNLIKELY(!parserMessages.isEmpty())) { - ErrorInfo err; - foreach (const QbsQmlJS::DiagnosticMessage &msg, parserMessages) - err.append(msg.message, toCodeLocation(filePath, msg.loc)); - throw err; - } - } - - cacheValue.setCode(code); - cacheValue.setAst(parser.ast()); - } - - ItemReaderResult result; - ItemReaderASTVisitor itemReader(this, &result); - itemReader.setFilePath(QFileInfo(filePath).absoluteFilePath()); - itemReader.setSourceCode(cacheValue.code()); - cacheValue.setProcessingFlag(true); - cacheValue.ast()->accept(&itemReader); - cacheValue.setProcessingFlag(false); - return result; + return m_visitorState->filesRead(); } } // namespace Internal diff --git a/src/lib/corelib/language/itemreader.h b/src/lib/corelib/language/itemreader.h index 31963ee8b..b77c16b82 100644 --- a/src/lib/corelib/language/itemreader.h +++ b/src/lib/corelib/language/itemreader.h @@ -34,7 +34,6 @@ #include "forward_decls.h" #include <logging/logger.h> -#include <QHash> #include <QSet> #include <QStack> #include <QStringList> @@ -44,15 +43,7 @@ namespace Internal { class Item; class ItemPool; - -struct ItemReaderResult -{ - ItemReaderResult() - : rootItem(0) - {} - - Item *rootItem; -}; +class ItemReaderVisitorState; /* * Reads a qbs file and creates a tree of Item objects. @@ -65,13 +56,10 @@ struct ItemReaderResult */ class ItemReader { - friend class ItemReaderASTVisitor; public: ItemReader(const Logger &logger); ~ItemReader(); - Logger logger() const { return m_logger; } - void setPool(ItemPool *pool) { m_pool = pool; } void setSearchPaths(const QStringList &searchPaths); void pushExtraSearchPaths(const QStringList &extraSearchPaths); @@ -86,21 +74,10 @@ public: QSet<QString> filesRead() const; private: - ItemReaderResult internalReadFile(const QString &filePath); - - void cacheDirectoryEntries(const QString &dirPath, const QStringList &entries); - bool findDirectoryEntries(const QString &dirPath, QStringList *entries) const; - - ItemPool *m_pool; - Logger m_logger; + ItemPool *m_pool = nullptr; QStringList m_searchPaths; QStack<QStringList> m_extraSearchPaths; - QHash<const Item *, QSet<JSSourceValuePtr> > m_conditionalValuesPerScopeItem; - - class ASTCache; - ASTCache *m_astCache; - QSet<QString> m_filesRead; - QHash<QString, QStringList> m_directoryEntries; + ItemReaderVisitorState * const m_visitorState; }; } // namespace Internal diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index b949bde1e..cf4686578 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -29,10 +29,12 @@ ****************************************************************************/ #include "itemreaderastvisitor.h" + #include "asttools.h" #include "builtindeclarations.h" #include "identifiersearch.h" -#include "itemreader.h" +#include "itemreadervisitorstate.h" + #include <jsextensions/jsextensions.h> #include <parser/qmljsast_p.h> #include <tools/error.h> @@ -43,19 +45,19 @@ #include <QDirIterator> #include <QFileInfo> -#include <QStringList> using namespace QbsQmlJS; namespace qbs { namespace Internal { -ItemReaderASTVisitor::ItemReaderASTVisitor(ItemReader *reader, ItemReaderResult *result) - : m_reader(reader) - , m_readerResult(result) +ItemReaderASTVisitor::ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, + ItemPool *itemPool, Logger logger, const QStringList &searchPaths) + : m_visitorState(visitorState) , m_file(FileContext::create()) - , m_item(0) - , m_sourceValue(0) + , m_itemPool(itemPool) + , m_logger(logger) + , m_searchPaths(searchPaths) { } @@ -77,7 +79,7 @@ bool ItemReaderASTVisitor::visit(AST::UiProgram *ast) { Q_UNUSED(ast); m_sourceValue.clear(); - m_file->m_searchPaths = m_reader->searchPaths(); + m_file->m_searchPaths = m_searchPaths; if (Q_UNLIKELY(!ast->members->member)) throw ErrorInfo(Tr::tr("No root item found in %1.").arg(m_file->filePath())); @@ -108,7 +110,7 @@ bool ItemReaderASTVisitor::addPrototype(const QString &fileName, const QString & void ItemReaderASTVisitor::collectPrototypes(const QString &path, const QString &as) { QStringList fileNames; // Yes, file *names*. - if (m_reader->findDirectoryEntries(path, &fileNames)) { + if (m_visitorState.findDirectoryEntries(path, &fileNames)) { foreach (const QString &fileName, fileNames) addPrototype(fileName, path + QLatin1Char('/') + fileName, as, false); return; @@ -121,12 +123,12 @@ void ItemReaderASTVisitor::collectPrototypes(const QString &path, const QString if (addPrototype(fileName, filePath, as, true)) fileNames << fileName; } - m_reader->cacheDirectoryEntries(path, fileNames); + m_visitorState.cacheDirectoryEntries(path, fileNames); } bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) { - foreach (const QString &searchPath, m_reader->searchPaths()) + foreach (const QString &searchPath, m_searchPaths) collectPrototypes(searchPath + QLatin1String("/imports"), QString()); const QString path = FileInfo::path(m_file->filePath()); @@ -150,8 +152,8 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) if (isBase) checkImportVersion(import->versionToken); else if (import->versionToken.length) - m_reader->logger().printWarning(ErrorInfo(Tr::tr("Superfluous version specification."), - toCodeLocation(import->versionToken))); + m_logger.printWarning(ErrorInfo(Tr::tr("Superfluous version specification."), + toCodeLocation(import->versionToken))); } QString as; @@ -169,8 +171,8 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) "must not have 'as' specifier.").arg(extensionName)); } if (Q_UNLIKELY(m_file->m_jsExtensions.contains(extensionName))) { - m_reader->logger().printWarning(Tr::tr("Built-in extension '%1' already " - "imported.").arg(extensionName)); + m_logger.printWarning(Tr::tr("Built-in extension '%1' already " + "imported.").arg(extensionName)); } else { m_file->m_jsExtensions << extensionName; } @@ -233,7 +235,7 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) ? QLatin1String("qbs/base") : importUri.join(QDir::separator()); bool found = m_typeNameToFile.contains(importUri); if (!found) { - foreach (const QString &searchPath, m_reader->searchPaths()) { + foreach (const QString &searchPath, m_searchPaths) { const QFileInfo fi(FileInfo::resolvePath( FileInfo::resolvePath(searchPath, QLatin1String("imports")), @@ -279,7 +281,7 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast) { const QString typeName = ast->qualifiedTypeNameId->name.toString(); - Item *item = Item::create(m_reader->m_pool); + Item *item = Item::create(m_itemPool); item->m_file = m_file; item->m_parent = m_item; item->m_typeName = typeName; @@ -292,7 +294,7 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast) } else { // This is the root item. m_item = item; - m_readerResult->rootItem = item; + m_rootItem = item; } if (ast->initializer) { @@ -301,7 +303,7 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast) qSwap(m_item, item); } - BuiltinDeclarations::instance().setupItemForBuiltinType(item, m_reader->logger()); + BuiltinDeclarations::instance().setupItemForBuiltinType(item, m_logger); if (item->typeName() != QLatin1String("Properties") && item->typeName() != QLatin1String("SubProject")) { @@ -312,14 +314,15 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast) const QStringList fullTypeName = toStringList(ast->qualifiedTypeNameId); const QString baseTypeFileName = m_typeNameToFile.value(fullTypeName); if (!baseTypeFileName.isEmpty()) { - const ItemReaderResult baseFile = m_reader->internalReadFile(baseTypeFileName); + const Item * const rootItem + = m_visitorState.readFile(baseTypeFileName, m_searchPaths, m_itemPool); - inheritItem(item, baseFile.rootItem); - if (baseFile.rootItem->m_file->m_idScope) { + inheritItem(item, rootItem); + if (rootItem->m_file->m_idScope) { // Make ids from the derived file visible in the base file. // ### Do we want to turn off this feature? It's QMLish but kind of strange. ensureIdScope(item->m_file); - baseFile.rootItem->m_file->m_idScope->setPrototype(item->m_file->m_idScope); + rootItem->m_file->m_idScope->setPrototype(item->m_file->m_idScope); } } @@ -475,7 +478,7 @@ Item *ItemReaderASTVisitor::targetItemForBinding(Item *item, for (int i = 0; i < c; ++i) { ValuePtr v = targetItem->m_properties.value(bindingName.at(i)); if (!v) { - Item *newItem = Item::create(m_reader->m_pool); + Item *newItem = Item::create(m_itemPool); v = ItemValue::create(newItem); targetItem->m_properties.insert(bindingName.at(i), v); } @@ -556,7 +559,7 @@ void ItemReaderASTVisitor::inheritItem(Item *dst, const Item *src) void ItemReaderASTVisitor::ensureIdScope(const FileContextPtr &file) { if (!file->m_idScope) { - file->m_idScope = Item::create(m_reader->m_pool); + file->m_idScope = Item::create(m_itemPool); file->m_idScope->m_typeName = QLatin1String("IdScope"); } } diff --git a/src/lib/corelib/language/itemreaderastvisitor.h b/src/lib/corelib/language/itemreaderastvisitor.h index 60b1fdd94..643c9a1e1 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.h +++ b/src/lib/corelib/language/itemreaderastvisitor.h @@ -34,21 +34,23 @@ #include "item.h" #include "filecontext.h" +#include <logging/logger.h> #include <parser/qmljsastvisitor_p.h> #include <QHash> +#include <QStringList> namespace qbs { namespace Internal { -class ItemReader; -struct ItemReaderResult; +class ItemReaderVisitorState; class Version; class ItemReaderASTVisitor : public QbsQmlJS::AST::Visitor { public: - ItemReaderASTVisitor(ItemReader *reader, ItemReaderResult *result); + ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, + ItemPool *itemPool, Logger logger, const QStringList &searchPaths); ~ItemReaderASTVisitor(); void setFilePath(const QString &filePath); @@ -61,6 +63,8 @@ public: bool visit(QbsQmlJS::AST::UiScriptBinding *ast); bool visit(QbsQmlJS::AST::FunctionDeclaration *ast); + Item *rootItem() const { return m_rootItem; } + private: static Version readImportVersion(const QString &str, const CodeLocation &location = CodeLocation()); @@ -80,11 +84,14 @@ private: bool addPrototype(const QString &fileName, const QString &filePath, const QString &as, bool needsCheck); - ItemReader *m_reader; - ItemReaderResult *m_readerResult; - FileContextPtr m_file; + ItemReaderVisitorState &m_visitorState; + const FileContextPtr m_file; + ItemPool * const m_itemPool; + Logger m_logger; + const QStringList m_searchPaths; QHash<QStringList, QString> m_typeNameToFile; - Item *m_item; + Item *m_item = nullptr; + Item *m_rootItem = nullptr; JSSourceValuePtr m_sourceValue; }; diff --git a/src/lib/corelib/language/itemreadervisitorstate.cpp b/src/lib/corelib/language/itemreadervisitorstate.cpp new file mode 100644 index 000000000..4eeb7df38 --- /dev/null +++ b/src/lib/corelib/language/itemreadervisitorstate.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#include "itemreadervisitorstate.h" + +#include "asttools.h" +#include "itemreaderastvisitor.h" + +#include <logging/translator.h> +#include <parser/qmljsengine_p.h> +#include <parser/qmljslexer_p.h> +#include <parser/qmljsparser_p.h> +#include <tools/error.h> + +#include <QExplicitlySharedDataPointer> +#include <QFile> +#include <QFileInfo> +#include <QSharedData> +#include <QTextStream> + +namespace qbs { +namespace Internal { + +class ASTCacheValueData : public QSharedData +{ + Q_DISABLE_COPY(ASTCacheValueData) +public: + ASTCacheValueData() + : ast(0) + , processing(false) + { + } + + QString code; + QbsQmlJS::Engine engine; + QbsQmlJS::AST::UiProgram *ast; + bool processing; +}; + +class ASTCacheValue +{ +public: + ASTCacheValue() + : d(new ASTCacheValueData) + { + } + + ASTCacheValue(const ASTCacheValue &other) + : d(other.d) + { + } + + void setProcessingFlag(bool b) { d->processing = b; } + bool isProcessing() const { return d->processing; } + + void setCode(const QString &code) { d->code = code; } + QString code() const { return d->code; } + + QbsQmlJS::Engine *engine() const { return &d->engine; } + + void setAst(QbsQmlJS::AST::UiProgram *ast) { d->ast = ast; } + QbsQmlJS::AST::UiProgram *ast() const { return d->ast; } + bool isValid() const { return d->ast; } + +private: + QExplicitlySharedDataPointer<ASTCacheValueData> d; +}; + +class ItemReaderVisitorState::ASTCache : public QHash<QString, ASTCacheValue> {}; + + +ItemReaderVisitorState::ItemReaderVisitorState(Logger logger) + : m_logger(logger) + , m_astCache(new ASTCache) +{ + +} + +ItemReaderVisitorState::~ItemReaderVisitorState() +{ + delete m_astCache; +} + +Item *ItemReaderVisitorState::readFile(const QString &filePath, const QStringList &searchPaths, + ItemPool *itemPool) +{ + ASTCacheValue &cacheValue = (*m_astCache)[filePath]; + if (cacheValue.isValid()) { + if (Q_UNLIKELY(cacheValue.isProcessing())) + throw ErrorInfo(Tr::tr("Loop detected when importing '%1'.").arg(filePath)); + } else { + QFile file(filePath); + if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) + throw ErrorInfo(Tr::tr("Cannot open '%1'.").arg(filePath)); + + m_filesRead.insert(filePath); + const QString code = QTextStream(&file).readAll(); + QbsQmlJS::Lexer lexer(cacheValue.engine()); + lexer.setCode(code, 1); + QbsQmlJS::Parser parser(cacheValue.engine()); + + file.close(); + if (!parser.parse()) { + QList<QbsQmlJS::DiagnosticMessage> parserMessages = parser.diagnosticMessages(); + if (Q_UNLIKELY(!parserMessages.isEmpty())) { + ErrorInfo err; + foreach (const QbsQmlJS::DiagnosticMessage &msg, parserMessages) + err.append(msg.message, toCodeLocation(filePath, msg.loc)); + throw err; + } + } + + cacheValue.setCode(code); + cacheValue.setAst(parser.ast()); + } + + ItemReaderASTVisitor astVisitor(*this, itemPool, m_logger, searchPaths); + astVisitor.setFilePath(QFileInfo(filePath).absoluteFilePath()); + astVisitor.setSourceCode(cacheValue.code()); + cacheValue.setProcessingFlag(true); + cacheValue.ast()->accept(&astVisitor); + cacheValue.setProcessingFlag(false); + return astVisitor.rootItem(); +} + +void ItemReaderVisitorState::cacheDirectoryEntries(const QString &dirPath, const QStringList &entries) +{ + m_directoryEntries.insert(dirPath, entries); +} + +bool ItemReaderVisitorState::findDirectoryEntries(const QString &dirPath, QStringList *entries) const +{ + const auto it = m_directoryEntries.constFind(dirPath); + if (it == m_directoryEntries.constEnd()) + return false; + *entries = it.value(); + return true; +} + + +} // namespace Internal +} // namespace qbs diff --git a/src/lib/corelib/language/itemreadervisitorstate.h b/src/lib/corelib/language/itemreadervisitorstate.h new file mode 100644 index 000000000..40c13c835 --- /dev/null +++ b/src/lib/corelib/language/itemreadervisitorstate.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ +#ifndef QBS_ITEMREADERVISITORSTATE_H +#define QBS_ITEMREADERVISITORSTATE_H + +#include <logging/logger.h> + +#include <QSet> +#include <QStack> +#include <QStringList> + +namespace qbs { +namespace Internal { +class BuiltinDeclarations; +class Item; +class ItemPool; + +class ItemReaderVisitorState +{ +public: + ItemReaderVisitorState(Logger logger); + ~ItemReaderVisitorState(); + + QSet<QString> filesRead() const { return m_filesRead; } + + Item *readFile(const QString &filePath, const QStringList &searchPaths, ItemPool *itemPool); + + void cacheDirectoryEntries(const QString &dirPath, const QStringList &entries); + bool findDirectoryEntries(const QString &dirPath, QStringList *entries) const; + +private: + Logger m_logger; + QSet<QString> m_filesRead; + QHash<QString, QStringList> m_directoryEntries; + + class ASTCache; + ASTCache * const m_astCache; +}; + +} // namespace Internal +} // namespace qbs + +#endif // Include guard. diff --git a/src/lib/corelib/language/language.pri b/src/lib/corelib/language/language.pri index 7c984176f..68c8139d7 100644 --- a/src/lib/corelib/language/language.pri +++ b/src/lib/corelib/language/language.pri @@ -21,6 +21,7 @@ HEADERS += \ $$PWD/itempool.h \ $$PWD/itemreader.h \ $$PWD/itemreaderastvisitor.h \ + $$PWD/itemreadervisitorstate.h \ $$PWD/jsimports.h \ $$PWD/language.h \ $$PWD/loader.h \ @@ -53,6 +54,7 @@ SOURCES += \ $$PWD/itempool.cpp \ $$PWD/itemreader.cpp \ $$PWD/itemreaderastvisitor.cpp \ + $$PWD/itemreadervisitorstate.cpp \ $$PWD/language.cpp \ $$PWD/loader.cpp \ $$PWD/moduleloader.cpp \ |