aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlls/qqmllsutils_p.h
blob: c83e889870e7db3bce0a90aff22a6fa0f49ea3f4 (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
// Copyright (C) 2023 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 QLANGUAGESERVERUTILS_P_H
#define QLANGUAGESERVERUTILS_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 <QtLanguageServer/private/qlanguageserverspectypes_p.h>
#include <QtQmlDom/private/qqmldomexternalitems_p.h>
#include <QtQmlDom/private/qqmldomtop_p.h>
#include <algorithm>
#include <optional>
#include <tuple>
#include <variant>

QT_BEGIN_NAMESPACE

struct QQmlLSUtilsItemLocation
{
    QQmlJS::Dom::DomItem domItem;
    QQmlJS::Dom::FileLocations::Tree fileLocation;
};

struct QQmlLSUtilsTextPosition
{
    int line;
    int character;
};

enum QQmlLSUtilsIdentifierType : char {
    JavaScriptIdentifier,
    PropertyIdentifier,
    PropertyChangedSignalIdentifier,
    PropertyChangedHandlerIdentifier,
    SignalIdentifier,
    SignalHandlerIdentifier,
    MethodIdentifier,
    QmlObjectIdIdentifier,
    QmlObjectIdentifier
};

struct QQmlLSUtilsErrorMessage
{
    int code;
    QString message;
};

struct QQmlLSUtilsExpressionType
{
    std::optional<QString> name;
    QQmlJSScope::ConstPtr semanticScope;
    QQmlLSUtilsIdentifierType type;
};

struct QQmlLSUtilsLocation
{
    QString filename;
    QQmlJS::SourceLocation sourceLocation;

    static QQmlLSUtilsLocation from(const QString &fileName, const QString &code, quint32 startLine,
                                    quint32 startCharacter, quint32 length);

    friend bool operator<(const QQmlLSUtilsLocation &a, const QQmlLSUtilsLocation &b)
    {
        return std::make_tuple(a.filename, a.sourceLocation.begin(), a.sourceLocation.end())
                < std::make_tuple(b.filename, b.sourceLocation.begin(), b.sourceLocation.end());
    }
    friend bool operator==(const QQmlLSUtilsLocation &a, const QQmlLSUtilsLocation &b)
    {
        return std::make_tuple(a.filename, a.sourceLocation.begin(), a.sourceLocation.end())
                == std::make_tuple(b.filename, b.sourceLocation.begin(), b.sourceLocation.end());
    }
};

struct QQmlLSUtilsEdit
{
    QQmlLSUtilsLocation location;
    QString replacement;

    static QQmlLSUtilsEdit from(const QString &fileName, const QString &code, quint32 startLine,
                                quint32 startCharacter, quint32 length, const QString &newName);

    friend bool operator<(const QQmlLSUtilsEdit &a, const QQmlLSUtilsEdit &b)
    {
        return std::make_tuple(a.location, a.replacement)
                < std::make_tuple(b.location, b.replacement);
    }
    friend bool operator==(const QQmlLSUtilsEdit &a, const QQmlLSUtilsEdit &b)
    {
        return std::make_tuple(a.location, a.replacement)
                == std::make_tuple(b.location, b.replacement);
    }
};

/*!
   \internal
    Choose whether to resolve the owner type or the entire type (the latter is only required to
    resolve the types of qualified names and property accesses).
 */
enum QQmlLSUtilsResolveOptions {
    ResolveOwnerType,
    ResolveActualTypeForFieldMemberExpression,
};

class QQmlLSUtils
{
public:
    static qsizetype textOffsetFrom(const QString &code, int row, int character);
    static QQmlLSUtilsTextPosition textRowAndColumnFrom(const QString &code, qsizetype offset);
    static QList<QQmlLSUtilsItemLocation> itemsFromTextLocation(QQmlJS::Dom::DomItem file, int line,
                                                                int character);
    static QQmlJS::Dom::DomItem sourceLocationToDomItem(QQmlJS::Dom::DomItem file,
                                                        const QQmlJS::SourceLocation &location);
    static QByteArray lspUriToQmlUrl(const QByteArray &uri);
    static QByteArray qmlUrlToLspUri(const QByteArray &url);
    static QLspSpecification::Range qmlLocationToLspLocation(const QString &code,
                                                             QQmlJS::SourceLocation qmlLocation);
    static QQmlJS::Dom::DomItem baseObject(QQmlJS::Dom::DomItem qmlObject);
    static std::optional<QQmlLSUtilsLocation> findTypeDefinitionOf(QQmlJS::Dom::DomItem item);
    static std::optional<QQmlLSUtilsLocation> findDefinitionOf(QQmlJS::Dom::DomItem item);
    static QList<QQmlLSUtilsLocation> findUsagesOf(QQmlJS::Dom::DomItem item);

    static std::optional<QQmlLSUtilsErrorMessage>
    checkNameForRename(QQmlJS::Dom::DomItem item, const QString &newName,
                       std::optional<QQmlLSUtilsExpressionType> targetType = std::nullopt);
    static QList<QQmlLSUtilsEdit>
    renameUsagesOf(QQmlJS::Dom::DomItem item, const QString &newName,
                   std::optional<QQmlLSUtilsExpressionType> targetType = std::nullopt);

    static std::optional<QQmlLSUtilsExpressionType>
    resolveExpressionType(QQmlJS::Dom::DomItem item, QQmlLSUtilsResolveOptions);
    static bool isValidEcmaScriptIdentifier(QStringView view);
};
QT_END_NAMESPACE

#endif // QLANGUAGESERVERUTILS_P_H