aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qmldirparser/qqmldirparser_p.h
blob: deef8f2dcf5260f1abbbeb2877d72ce7c8aab41a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only

#ifndef QQMLDIRPARSER_P_H
#define QQMLDIRPARSER_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 <QtCore/QUrl>
#include <QtCore/QHash>
#include <QtCore/QDebug>
#include <QtCore/QTypeRevision>
#include <private/qtqmlcompilerglobal_p.h>
#include <private/qqmljsdiagnosticmessage_p.h>

QT_BEGIN_NAMESPACE

class QQmlEngine;
class Q_QML_COMPILER_EXPORT QQmlDirParser
{
public:
    void clear();
    bool parse(const QString &source);
    void disambiguateFileSelectors();

    bool hasError() const { return !_errors.isEmpty(); }
    void setError(const QQmlJS::DiagnosticMessage &);
    QList<QQmlJS::DiagnosticMessage> errors(const QString &uri) const;

    QString typeNamespace() const { return _typeNamespace; }
    void setTypeNamespace(const QString &s) { _typeNamespace = s; }

    static void checkNonRelative(const char *item, const QString &typeName, const QString &fileName)
    {
        if (fileName.startsWith(QLatin1Char('/'))) {
            qWarning() << item << typeName
                       << "is specified with non-relative URL" << fileName << "in a qmldir file."
                       << "URLs in qmldir files should be relative to the qmldir file's directory.";
        }
    }

    struct Plugin
    {
        Plugin() = default;

        Plugin(const QString &name, const QString &path, bool optional)
            : name(name), path(path), optional(optional)
        {
            checkNonRelative("Plugin", name, path);
        }

        QString name;
        QString path;
        bool optional = false;
    };

    struct Component
    {
        Component() = default;

        Component(const QString &typeName, const QString &fileName, QTypeRevision version)
            : typeName(typeName), fileName(fileName), version(version),
            internal(false), singleton(false)
        {
            checkNonRelative("Component", typeName, fileName);
        }

        QString typeName;
        QString fileName;
        QTypeRevision version = QTypeRevision::zero();
        bool internal = false;
        bool singleton = false;
    };

    struct Script
    {
        Script() = default;

        Script(const QString &nameSpace, const QString &fileName, QTypeRevision version)
            : nameSpace(nameSpace), fileName(fileName), version(version)
        {
            checkNonRelative("Script", nameSpace, fileName);
        }

        QString nameSpace;
        QString fileName;
        QTypeRevision version = QTypeRevision::zero();
    };

    struct Import
    {
        enum Flag {
            Default = 0x0,
            Auto = 0x1, // forward the version of the importing module
            Optional = 0x2, // is not automatically imported but only a tooling hint
            OptionalDefault =
                    0x4, // tooling hint only, denotes this entry should be imported by tooling
        };
        Q_DECLARE_FLAGS(Flags, Flag)

        Import() = default;
        Import(QString module, QTypeRevision version, Flags flags)
            : module(module), version(version), flags(flags)
        {
        }

        QString module;
        QTypeRevision version;     // invalid version is latest version, unless Flag::Auto
        Flags flags;

        friend bool operator==(const Import &a, const Import &b)
        {
            return a.module == b.module && a.version == b.version && a.flags == b.flags;
        }
    };

    QMultiHash<QString,Component> components() const { return _components; }
    QList<Import> dependencies() const { return _dependencies; }
    QList<Import> imports() const { return _imports; }
    QList<Script> scripts() const { return _scripts; }
    QList<Plugin> plugins() const { return _plugins; }
    bool designerSupported() const { return _designerSupported; }
    bool isStaticModule() const { return _isStaticModule; }
    bool isSystemModule() const { return _isSystemModule; }

    QStringList typeInfos() const { return _typeInfos; }
    QStringList classNames() const { return _classNames; }
    QString preferredPath() const { return _preferredPath; }
    QString linkTarget() const { return _linkTarget; }

private:
    bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash<QString,Component> &hash, int lineNumber = -1, bool multi = true);
    void reportError(quint16 line, quint16 column, const QString &message);

private:
    QList<QQmlJS::DiagnosticMessage> _errors;
    QString _typeNamespace;
    QString _preferredPath;
    QMultiHash<QString,Component> _components;
    QList<Import> _dependencies;
    QList<Import> _imports;
    QList<Script> _scripts;
    QList<Plugin> _plugins;
    bool _designerSupported = false;
    bool _isStaticModule = false;
    bool _isSystemModule = false;
    QStringList _typeInfos;
    QStringList _classNames;
    QString _linkTarget;
};

using QQmlDirComponents = QMultiHash<QString,QQmlDirParser::Component>;
using QQmlDirScripts = QList<QQmlDirParser::Script>;
using QQmlDirPlugins = QList<QQmlDirParser::Plugin>;
using QQmlDirImports = QList<QQmlDirParser::Import>;

QDebug &operator<< (QDebug &, const QQmlDirParser::Component &);
QDebug &operator<< (QDebug &, const QQmlDirParser::Script &);

QT_END_NAMESPACE

#endif // QQMLDIRPARSER_P_H