Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qmlpropertyarguments.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5#include "location.h"
6
7using namespace Qt::Literals::StringLiterals;
8
9QT_BEGIN_NAMESPACE
10
11/*!
12 \class QmlPropertyArguments
13 \brief Helper class for parsing QML property and QML method arguments.
14*/
15
16/*!
17 \enum QmlPropertyArguments::ParsingOptions
18
19 \value None
20 No options specified.
21 \value RequireQualifiedPath
22 Require the path segment to be qualified with a
23 QML type name.
24 \value IgnoreType
25 Don’t require a type segment when parsing.
26 \value ParseAsMethod
27 Parse input as a method, expecting to see also
28 QML method/signal parameters.
29
30 \sa parse()
31*/
32
33/*!
34 Parses a QML property from the input string \a str, with parsing options
35 \a opts. \a str contains the argument string passed to e.g. the
36 \\qmlproperty command.
37
38 A valid QML property has the following syntax:
39
40 \badcode
41 <type> <QML-type>::<name>
42 <type> <QML-module>::<QML-type>::<name>
43 \endcode
44
45 In addition, if parsing option RequireQualifiedPath is \b not set, the
46 following is also accepted:
47
48 \badcode
49 <type> <name>
50 \endcode
51
52 \e {<type>} can be omitted if \c IgnoreType option is set.
53
54 This syntax is accepted in QmlDocVisitor where the associated QML type
55 is already known.
56
57 If \c ParseAsMethod option is set, a parameter list enclosed in
58 parentheses must appear at the end. An empty list, i.e. \e {()}, is accepted.
59
60 Returns a populated QmlPropertyArguments container with the property type
61 (m_type), whether the type is a list type (m_isList), property name
62 (m_name), and optionally, the parent QML type name (m_qmltype) and QML
63 module name (m_module) if those were present in the argument string.
64 For methods, the parameter list (m_params) is also set.
65
66 If the argument string is incorrect, outputs a warning using \a loc and
67 returns \c nullopt.
68*/
69std::optional<QmlPropertyArguments>
70QmlPropertyArguments::parse(const QString &str, const Location &loc, ParsingOptions opts)
71{
72 // Special case: an empty string received from DocParser due to syntax error
73 // Assumes a warning was issued already.
74 if (str.isEmpty())
75 return std::nullopt;
76
77 auto input{str.trimmed()};
78 QmlPropertyArguments args;
79
80 bool is_method = (opts & ParsingOptions::ParseAsMethod) != ParsingOptions::None;
81
82 auto paramStart = input.indexOf('('_L1);
83 if (paramStart != -1) {
84 if (auto paramEnd = input.indexOf(')'_L1, ++paramStart); paramEnd != -1)
85 args.m_params = input.sliced(paramStart, paramEnd - paramStart).trimmed();
86 input.resize(paramStart - 1);
87 input = input.trimmed();
88 }
89 if (is_method && args.m_params.isNull()) {
90 loc.warning("Invalid syntax for \\qmlmethod: %1"_L1.arg(str));
91 return std::nullopt;
92 }
93
94 auto offset = input.indexOf(' '_L1);
95 if (offset == -1) {
96 if ((opts & ParsingOptions::IgnoreType) == ParsingOptions::None) {
97 loc.warning("Missing %1 type for %2"_L1
98 .arg(is_method ? "return"_L1 : "property"_L1, str));
99 return std::nullopt;
100 }
101 } else {
102 args.m_type = input.first(offset);
103 if ((args.m_isList = args.m_type.startsWith("list<"_L1)) && !is_method)
104 args.m_type.slice(5).chop(1);
105 }
106
107 auto segments = input.slice(++offset).split("::"_L1);
108 if (segments.size() > 3 || (segments.size() == 1 &&
109 (opts & ParsingOptions::RequireQualifiedPath) != ParsingOptions::None)) {
110 loc.warning("Unrecognizable QML module/type qualifier for %1"_L1.arg(str));
111 return std::nullopt;
112 }
113 args.m_name = segments.takeLast();
114 if (segments.size() > 0)
115 args.m_qmltype = segments.takeLast();
116 if (segments.size() > 0)
117 args.m_module = segments[0];
118
119 return std::optional(args);
120}
121
122QT_END_NAMESPACE