20 const QQmlSA::Element &fromElement,
21 const QQmlSA::Element &toElement)
24 auto from = QQmlJSScope::scope(fromElement);
25 auto to = QQmlJSScope::scope(toElement);
29 if (!resolver->canConvertFromTo(from, to))
32 const bool fromIsString = from == resolver->stringType();
34 if (to == resolver->stringType()
35 || to == resolver->stringListType()
36 || to == resolver->byteArrayType()
37 || to == resolver->urlType()) {
41 if (resolver->isNumeric(to))
42 return resolver->isNumeric(from);
44 if (to == resolver->boolType())
45 return from == resolver->boolType();
65 case QQmlSA::BindingType::BoolLiteral:
67 case QQmlSA::BindingType::NumberLiteral:
69 case QQmlSA::BindingType::StringLiteral:
71 case QQmlSA::BindingType::RegExpLiteral:
73 case QQmlSA::BindingType::Null:
78 Q_UNREACHABLE_RETURN(QString());
81QQmlSA::Property LiteralBindingCheckBase::getProperty(
const QString &propertyName,
82 const QQmlSA::Binding &binding,
83 const QQmlSA::Element &bindingScope)
const
85 if (!QQmlSA::Binding::isLiteralBinding(binding.bindingType()))
88 const QString unqualifiedPropertyName = [&propertyName]() -> QString {
89 if (
auto idx = propertyName.lastIndexOf(u'.'); idx != -1 && idx != propertyName.size() - 1)
90 return propertyName.sliced(idx + 1);
94 return bindingScope.property(unqualifiedPropertyName);
97void LiteralBindingCheckBase::warnOnCheckedBinding(
98 const QQmlSA::Binding &binding,
const QQmlSA::Element &propertyType)
100 auto construction = check(propertyType.internalId(), binding.stringValue());
101 if (!construction.isValid())
104 const QString warningMessage =
105 u"Construction from string is deprecated. Use structured value type "
106 u"construction instead for type \"%1\""_s.arg(propertyType.internalId());
108 if (construction.code.isEmpty()) {
109 emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation());
113 const QQmlSA::FixSuggestion suggestion(
114 u"Replace string by structured value construction"_s,
115 binding.sourceLocation(), construction.code);
116 emitWarning(warningMessage, qmlIncompatibleType, binding.sourceLocation(), suggestion);
119void QQmlJSLiteralBindingCheck::onBinding(
const QQmlSA::Element &element,
120 const QString &propertyName,
121 const QQmlSA::Binding &binding,
122 const QQmlSA::Element &bindingScope,
123 const QQmlSA::Element &value)
127 const auto property = getProperty(propertyName, binding, bindingScope);
128 if (!property.isValid())
133 if (property.isReadonly() && !element.hasOwnProperty(propertyName)) {
134 emitWarning(u"Cannot assign to read-only property %1"_s.arg(propertyName),
135 qmlReadOnlyProperty, binding.sourceLocation());
139 if (
const auto propertyType = property.type())
140 warnOnCheckedBinding(binding, propertyType);
142 if (!canConvertForLiteralBinding(m_resolver, resolveLiteralType(binding), property.type())) {
143 emitWarning(u"Cannot assign literal of type %1 to %2"_s.arg(
144 literalPrettyTypeName(binding.bindingType()),
145 QQmlJSScope::prettyName(property.typeName())),
146 qmlIncompatibleType, binding.sourceLocation());