1 | // Copyright (C) 2021 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #ifndef QQMLJSSOURCELOCATION_P_H |
5 | #define QQMLJSSOURCELOCATION_P_H |
6 | |
7 | #include <QtCore/private/qglobal_p.h> |
8 | #include <QtCore/qhashfunctions.h> |
9 | |
10 | // |
11 | // W A R N I N G |
12 | // ------------- |
13 | // |
14 | // This file is not part of the Qt API. It exists purely as an |
15 | // implementation detail. This header file may change from version to |
16 | // version without notice, or even be removed. |
17 | // |
18 | // We mean it. |
19 | // |
20 | |
21 | QT_BEGIN_NAMESPACE |
22 | |
23 | namespace QQmlJS { |
24 | |
25 | class SourceLocation |
26 | { |
27 | public: |
28 | explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) |
29 | : offset(offset), length(length), |
30 | startLine(line), startColumn(column) |
31 | { } |
32 | |
33 | bool isValid() const { return *this != SourceLocation(); } |
34 | |
35 | quint32 begin() const { return offset; } |
36 | quint32 end() const { return offset + length; } |
37 | |
38 | // Returns a zero length location at the start of the current one. |
39 | SourceLocation startZeroLengthLocation() const |
40 | { |
41 | return SourceLocation(offset, 0, startLine, startColumn); |
42 | } |
43 | // Returns a zero length location at the end of the current one. |
44 | SourceLocation endZeroLengthLocation(QStringView text) const |
45 | { |
46 | quint32 i = offset; |
47 | quint32 endLine = startLine; |
48 | quint32 endColumn = startColumn; |
49 | while (i < end()) { |
50 | QChar c = text.at(n: i); |
51 | switch (c.unicode()) { |
52 | case '\n': |
53 | if (i + 1 < end() && text.at(n: i + 1) == QLatin1Char('\r')) |
54 | ++i; |
55 | Q_FALLTHROUGH(); |
56 | case '\r': |
57 | ++endLine; |
58 | endColumn = 1; |
59 | break; |
60 | default: |
61 | ++endColumn; |
62 | } |
63 | ++i; |
64 | } |
65 | return SourceLocation(offset + length, 0, endLine, endColumn); |
66 | } |
67 | |
68 | // attributes |
69 | // ### encode |
70 | quint32 offset; |
71 | quint32 length; |
72 | quint32 startLine; |
73 | quint32 startColumn; |
74 | |
75 | friend size_t qHash(const SourceLocation &location, size_t seed = 0) |
76 | { |
77 | return qHashMulti(seed, args: location.offset, args: location.length, |
78 | args: location.startLine, args: location.startColumn); |
79 | } |
80 | |
81 | friend bool operator==(const SourceLocation &a, const SourceLocation &b) |
82 | { |
83 | return a.offset == b.offset && a.length == b.length |
84 | && a.startLine == b.startLine && a.startColumn == b.startColumn; |
85 | } |
86 | |
87 | friend bool operator!=(const SourceLocation &a, const SourceLocation &b) { return !(a == b); } |
88 | |
89 | // Returns a source location starting at the beginning of l1, l2 and ending at the end of them. |
90 | // Ignores invalid source locations. |
91 | friend SourceLocation combine(const SourceLocation &l1, const SourceLocation &l2) { |
92 | quint32 e = qMax(a: l1.end(), b: l2.end()); |
93 | SourceLocation res; |
94 | if (l1.offset <= l2.offset) |
95 | res = (l1.isValid() ? l1 : l2); |
96 | else |
97 | res = (l2.isValid() ? l2 : l1); |
98 | res.length = e - res.offset; |
99 | return res; |
100 | } |
101 | }; |
102 | |
103 | } // namespace QQmlJS |
104 | |
105 | QT_END_NAMESPACE |
106 | |
107 | #endif |
108 | |