/**************************************************************************** ** ** Copyright (C) 2019 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QQMLJSIMPORTEDMEMBERSVISITOR_P_H #define QQMLJSIMPORTEDMEMBERSVISITOR_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. #include "qqmljsscope_p.h" #include "qqmljsannotation_p.h" #include "qqmljslogger_p.h" #include #include #include QT_BEGIN_NAMESPACE struct QQmlJSResourceFileMapper; class QQmlJSImportVisitor : public QQmlJS::AST::Visitor { public: QQmlJSImportVisitor(QQmlJSImporter *importer, const QString &implicitImportDirectory, const QStringList &qmltypesFiles = QStringList(), const QString &fileName = QString(), const QString &code = QString(), bool silent = true); ~QQmlJSImportVisitor(); QQmlJSScope::Ptr result() const; // TODO: Should be superseded by accessing the logger instead QList errors() const { return m_logger.warnings() + m_logger.errors(); } QQmlJSLogger &logger() { return m_logger; } QHash imports() const { return m_rootScopeImports; } QHash addressableScopes() const { return m_scopesById; } QHash signalHandlers() const { return m_signalHandlers; } static QString implicitImportDirectory( const QString &localFile, QQmlJSResourceFileMapper *mapper); protected: // Linter warnings, we might want to move this at some point bool visit(QQmlJS::AST::StringLiteral *) override; bool visit(QQmlJS::AST::ExpressionStatement *ast) override; void endVisit(QQmlJS::AST::ExpressionStatement *ast) override; bool visit(QQmlJS::AST::UiProgram *) override; void endVisit(QQmlJS::AST::UiProgram *) override; bool visit(QQmlJS::AST::UiObjectDefinition *) override; void endVisit(QQmlJS::AST::UiObjectDefinition *) override; bool visit(QQmlJS::AST::UiInlineComponent *) override; void endVisit(QQmlJS::AST::UiInlineComponent *) override; bool visit(QQmlJS::AST::UiPublicMember *) override; bool visit(QQmlJS::AST::UiRequired *required) override; bool visit(QQmlJS::AST::UiScriptBinding *) override; void endVisit(QQmlJS::AST::UiScriptBinding *) override; bool visit(QQmlJS::AST::UiArrayBinding *) override; void endVisit(QQmlJS::AST::UiArrayBinding *) override; bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override; bool visit(QQmlJS::AST::FunctionExpression *fexpr) override; void endVisit(QQmlJS::AST::FunctionExpression *) override; bool visit(QQmlJS::AST::UiSourceElement *) override; bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override; void endVisit(QQmlJS::AST::FunctionDeclaration *) override; bool visit(QQmlJS::AST::ClassExpression *ast) override; void endVisit(QQmlJS::AST::ClassExpression *) override; bool visit(QQmlJS::AST::UiImport *import) override; bool visit(QQmlJS::AST::ClassDeclaration *ast) override; void endVisit(QQmlJS::AST::ClassDeclaration *ast) override; bool visit(QQmlJS::AST::ForStatement *ast) override; void endVisit(QQmlJS::AST::ForStatement *ast) override; bool visit(QQmlJS::AST::ForEachStatement *ast) override; void endVisit(QQmlJS::AST::ForEachStatement *ast) override; bool visit(QQmlJS::AST::Block *ast) override; void endVisit(QQmlJS::AST::Block *ast) override; bool visit(QQmlJS::AST::CaseBlock *ast) override; void endVisit(QQmlJS::AST::CaseBlock *ast) override; bool visit(QQmlJS::AST::Catch *ast) override; void endVisit(QQmlJS::AST::Catch *ast) override; bool visit(QQmlJS::AST::WithStatement *withStatement) override; void endVisit(QQmlJS::AST::WithStatement *ast) override; bool visit(QQmlJS::AST::VariableDeclarationList *vdl) override; bool visit(QQmlJS::AST::FormalParameterList *fpl) override; bool visit(QQmlJS::AST::UiObjectBinding *uiob) override; void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override; bool visit(QQmlJS::AST::ExportDeclaration *exp) override; void endVisit(QQmlJS::AST::ExportDeclaration *exp) override; bool visit(QQmlJS::AST::ESModule *module) override; void endVisit(QQmlJS::AST::ESModule *module) override; bool visit(QQmlJS::AST::Program *program) override; void endVisit(QQmlJS::AST::Program *program) override; void throwRecursionDepthError() override; QString m_implicitImportDirectory; QString m_code; QString m_filePath; QString m_rootId; QStringView m_inlineComponentName; bool m_nextIsInlineComponent = false; QStringList m_qmltypesFiles; QQmlJSScope::Ptr m_currentScope; QQmlJSScope::Ptr m_exportedRootScope; QQmlJSScope::ConstPtr m_globalScope; QHash m_scopesById; QHash m_rootScopeImports; // Maps all qmlNames to the source location of their import QMultiHash m_importTypeLocationMap; // Contains all import source locations (could be extracted from above but that is expensive) QSet m_importLocations; // A set of all types that have been used during type resolution QSet m_usedTypes; QQmlJSImporter *m_importer; void enterEnvironment(QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location); // Finds an existing scope before attempting to create a new one. Returns \c // true if the scope already exists and \c false if the new scope is created bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location); void leaveEnvironment(); QVector parseAnnotations(QQmlJS::AST::UiAnnotationList *list); void addDefaultProperties(); void processDefaultProperties(); void processPropertyBindings(); void checkRequiredProperties(); void processPropertyTypes(); void processPropertyBindingObjects(); void checkSignals(); void flushPendingSignalParameters(); void checkInheritanceCycle(QQmlJSScope::ConstPtr scope); void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope); QQmlJSLogger m_logger; // Used to temporarily store annotations for functions and generators wrapped in UiSourceElements QVector m_pendingMethodAnnotations; struct PendingPropertyType { QQmlJSScope::Ptr scope; QString name; QQmlJS::SourceLocation location; }; struct PendingPropertyObjectBinding { QQmlJSScope::Ptr scope; QQmlJSScope::ConstPtr childScope; QString name; QQmlJS::SourceLocation location; bool onToken; }; struct RequiredProperty { QQmlJSScope::Ptr scope; QString name; QQmlJS::SourceLocation location; }; QHash> m_pendingDefaultProperties; QVector m_pendingPropertyTypes; QVector m_pendingPropertyObjectBindings; QVector m_requiredProperties; QVector m_objectBindingScopes; QVector m_objectDefinitionScopes; QHash> m_propertyBindings; QHash>> m_signals; QHash m_signalHandlers; QQmlJS::SourceLocation m_pendingSignalHandler; struct OutstandingConnection { QString targetName; QQmlJSScope::Ptr scope; QQmlJS::AST::UiObjectDefinition *uiod; }; QVarLengthArray m_outstandingConnections; // Connections whose target we have not encountered private: void importBaseModules(); void resolveAliases(); void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr); void processImportWarnings(const QString &what, const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation()); void addImportWithLocation(const QString &name, const QQmlJS::SourceLocation &loc); }; QT_END_NAMESPACE #endif // QQMLJSIMPORTEDMEMBERSVISITOR_P_H