forked from qt-creator/qt-creator
QmlDesigner: Adding missing property error notifier
Alias properties are quite often broken. So we have to handle that broken aliases. Task-number: QDS-12761 Change-Id: Id9b53b98080733e5939de6b3761c923fa35e1dcf Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -3165,21 +3165,25 @@ void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations &
|
||||
auto typeId = fetchTypeId(alias.aliasImportedTypeNameId);
|
||||
|
||||
if (typeId) {
|
||||
auto [propertyImportedTypeNameId, propertyTypeId, aliasId, propertyTraits]
|
||||
= fetchPropertyDeclarationByTypeIdAndNameUngarded(typeId, alias.aliasPropertyName);
|
||||
auto propertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
typeId, alias.aliasPropertyName);
|
||||
if (propertyDeclaration) {
|
||||
auto [propertyImportedTypeNameId, propertyTypeId, aliasId, propertyTraits] = *propertyDeclaration;
|
||||
|
||||
s->updatePropertyDeclarationWithAliasAndTypeStatement.write(alias.propertyDeclarationId,
|
||||
propertyTypeId,
|
||||
propertyTraits,
|
||||
propertyImportedTypeNameId,
|
||||
aliasId);
|
||||
} else {
|
||||
errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(
|
||||
alias.aliasImportedTypeNameId),
|
||||
fetchTypeSourceId(alias.typeId));
|
||||
s->resetAliasPropertyDeclarationStatement.write(alias.propertyDeclarationId,
|
||||
Storage::PropertyDeclarationTraits{});
|
||||
s->updatePropertyDeclarationWithAliasAndTypeStatement
|
||||
.write(alias.propertyDeclarationId,
|
||||
propertyTypeId,
|
||||
propertyTraits,
|
||||
propertyImportedTypeNameId,
|
||||
aliasId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(alias.aliasImportedTypeNameId),
|
||||
fetchTypeSourceId(alias.typeId));
|
||||
s->resetAliasPropertyDeclarationStatement.write(alias.propertyDeclarationId,
|
||||
Storage::PropertyDeclarationTraits{});
|
||||
},
|
||||
TypeCompare<AliasPropertyDeclaration>{});
|
||||
}
|
||||
@@ -3321,7 +3325,10 @@ PropertyDeclarationId ProjectStorage::fetchAliasId(TypeId aliasTypeId,
|
||||
|
||||
auto stemAlias = fetchPropertyDeclarationByTypeIdAndNameUngarded(aliasTypeId, aliasPropertyName);
|
||||
|
||||
return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias.propertyTypeId,
|
||||
if (!stemAlias)
|
||||
return PropertyDeclarationId{};
|
||||
|
||||
return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias->propertyTypeId,
|
||||
aliasPropertyNameTail);
|
||||
}
|
||||
|
||||
@@ -3341,10 +3348,22 @@ void ProjectStorage::linkAliasPropertyDeclarationAliasIds(
|
||||
aliasDeclaration.aliasPropertyName,
|
||||
aliasDeclaration.aliasPropertyNameTail);
|
||||
|
||||
s->updatePropertyDeclarationAliasIdAndTypeNameIdStatement
|
||||
.write(aliasDeclaration.propertyDeclarationId,
|
||||
aliasId,
|
||||
aliasDeclaration.aliasImportedTypeNameId);
|
||||
if (aliasId) {
|
||||
s->updatePropertyDeclarationAliasIdAndTypeNameIdStatement
|
||||
.write(aliasDeclaration.propertyDeclarationId,
|
||||
aliasId,
|
||||
aliasDeclaration.aliasImportedTypeNameId);
|
||||
} else {
|
||||
s->resetAliasPropertyDeclarationStatement.write(aliasDeclaration.propertyDeclarationId,
|
||||
Storage::PropertyDeclarationTraits{});
|
||||
s->updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement
|
||||
.write(aliasDeclaration.propertyDeclarationId,
|
||||
TypeId{},
|
||||
Storage::PropertyDeclarationTraits{});
|
||||
|
||||
errorNotifier->propertyNameDoesNotExists(aliasDeclaration.composedProperyName(),
|
||||
aliasDeclaration.sourceId);
|
||||
}
|
||||
} else if (raiseError == RaiseError::Yes) {
|
||||
errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(
|
||||
aliasDeclaration.aliasImportedTypeNameId),
|
||||
@@ -4516,10 +4535,18 @@ void ProjectStorage::syncDefaultProperties(Storage::Synchronization::Types &type
|
||||
keyValue("view", view)};
|
||||
|
||||
PropertyDeclarationId valueDefaultPropertyId;
|
||||
if (value.defaultPropertyName.size())
|
||||
valueDefaultPropertyId = fetchPropertyDeclarationByTypeIdAndNameUngarded(value.typeId,
|
||||
value.defaultPropertyName)
|
||||
.propertyDeclarationId;
|
||||
if (value.defaultPropertyName.size()) {
|
||||
auto defaultPropertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
value.typeId, value.defaultPropertyName);
|
||||
|
||||
if (defaultPropertyDeclaration) {
|
||||
valueDefaultPropertyId = defaultPropertyDeclaration->propertyDeclarationId;
|
||||
} else {
|
||||
errorNotifier->missingDefaultProperty(value.typeName,
|
||||
value.defaultPropertyName,
|
||||
value.sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
|
||||
return Sqlite::UpdateChange::No;
|
||||
@@ -4563,10 +4590,8 @@ void ProjectStorage::resetDefaultPropertiesIfChanged(Storage::Synchronization::T
|
||||
|
||||
PropertyDeclarationId valueDefaultPropertyId;
|
||||
if (value.defaultPropertyName.size()) {
|
||||
auto optionalValueDefaultPropertyId = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
valueDefaultPropertyId = fetchPropertyDeclarationIdByTypeIdAndNameUngarded(
|
||||
value.typeId, value.defaultPropertyName);
|
||||
if (optionalValueDefaultPropertyId)
|
||||
valueDefaultPropertyId = optionalValueDefaultPropertyId->propertyDeclarationId;
|
||||
}
|
||||
|
||||
if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
|
||||
@@ -4814,8 +4839,8 @@ TypeId ProjectStorage::fetchTypeId(ImportedTypeNameId typeNameId,
|
||||
}
|
||||
|
||||
std::optional<ProjectStorage::FetchPropertyDeclarationResult>
|
||||
ProjectStorage::fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId,
|
||||
Utils::SmallStringView name)
|
||||
ProjectStorage::fetchPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId,
|
||||
Utils::SmallStringView name)
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch optional property declaration by type id and name ungarded"_t,
|
||||
@@ -4833,24 +4858,6 @@ ProjectStorage::fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId t
|
||||
return propertyDeclaration;
|
||||
}
|
||||
|
||||
ProjectStorage::FetchPropertyDeclarationResult ProjectStorage::fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
TypeId typeId, Utils::SmallStringView name)
|
||||
{
|
||||
using NanotraceHR::keyValue;
|
||||
NanotraceHR::Tracer tracer{"fetch property declaration by type id and name ungarded"_t,
|
||||
projectStorageCategory(),
|
||||
keyValue("type id", typeId),
|
||||
keyValue("property name", name)};
|
||||
|
||||
auto propertyDeclaration = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(typeId, name);
|
||||
tracer.end(keyValue("property declaration", propertyDeclaration));
|
||||
|
||||
if (propertyDeclaration)
|
||||
return *propertyDeclaration;
|
||||
|
||||
throw PropertyNameDoesNotExists{};
|
||||
}
|
||||
|
||||
PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameUngarded(
|
||||
TypeId typeId, Utils::SmallStringView name)
|
||||
{
|
||||
@@ -4864,10 +4871,7 @@ PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameU
|
||||
|
||||
tracer.end(keyValue("property declaration id", propertyDeclarationId));
|
||||
|
||||
if (propertyDeclarationId)
|
||||
return propertyDeclarationId;
|
||||
|
||||
throw PropertyNameDoesNotExists{};
|
||||
return propertyDeclarationId;
|
||||
}
|
||||
|
||||
SourceContextId ProjectStorage::readSourceContextId(Utils::SmallStringView sourceContextPath)
|
||||
|
||||
@@ -411,6 +411,14 @@ private:
|
||||
convertToString(string, dict);
|
||||
}
|
||||
|
||||
Utils::PathString composedProperyName() const
|
||||
{
|
||||
if (aliasPropertyNameTail.empty())
|
||||
return aliasPropertyName;
|
||||
|
||||
return Utils::PathString::join({aliasPropertyName, ".", aliasPropertyNameTail});
|
||||
}
|
||||
|
||||
public:
|
||||
TypeId typeId;
|
||||
PropertyDeclarationId propertyDeclarationId;
|
||||
@@ -991,10 +999,7 @@ private:
|
||||
Storage::PropertyDeclarationTraits propertyTraits;
|
||||
};
|
||||
|
||||
std::optional<FetchPropertyDeclarationResult> fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
TypeId typeId, Utils::SmallStringView name);
|
||||
|
||||
FetchPropertyDeclarationResult fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
std::optional<FetchPropertyDeclarationResult> fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||
TypeId typeId, Utils::SmallStringView name);
|
||||
|
||||
PropertyDeclarationId fetchPropertyDeclarationIdByTypeIdAndNameUngarded(TypeId typeId,
|
||||
|
||||
@@ -14,4 +14,20 @@ void ProjectStorageErrorNotifier::typeNameCannotBeResolved(Utils::SmallStringVie
|
||||
<< " in file: " << m_pathCache.sourcePath(sourceId).toStringView();
|
||||
}
|
||||
|
||||
void ProjectStorageErrorNotifier::missingDefaultProperty(Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView propertyName,
|
||||
SourceId sourceId)
|
||||
|
||||
{
|
||||
qDebug() << "Missing default property: " << propertyName << " in type: " << typeName
|
||||
<< " in file: " << m_pathCache.sourcePath(sourceId).toStringView();
|
||||
}
|
||||
|
||||
void ProjectStorageErrorNotifier::propertyNameDoesNotExists(Utils::SmallStringView propertyName,
|
||||
SourceId sourceId)
|
||||
{
|
||||
qDebug() << "Missing property: " << propertyName
|
||||
<< " in file: " << m_pathCache.sourcePath(sourceId).toStringView();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
||||
@@ -16,7 +16,11 @@ public:
|
||||
: m_pathCache{pathCache}
|
||||
{}
|
||||
|
||||
void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId souceId) override;
|
||||
void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId sourceId) override;
|
||||
void missingDefaultProperty(Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView propertyName,
|
||||
SourceId sourceId) override;
|
||||
void propertyNameDoesNotExists(Utils::SmallStringView propertyName, SourceId sourceId) override;
|
||||
|
||||
private:
|
||||
PathCacheType &m_pathCache;
|
||||
|
||||
@@ -18,7 +18,12 @@ public:
|
||||
ProjectStorageErrorNotifierInterface(const ProjectStorageErrorNotifierInterface &) = delete;
|
||||
ProjectStorageErrorNotifierInterface &operator=(const ProjectStorageErrorNotifierInterface &) = delete;
|
||||
|
||||
virtual void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId souceId) = 0;
|
||||
virtual void typeNameCannotBeResolved(Utils::SmallStringView typeName, SourceId sourceId) = 0;
|
||||
virtual void missingDefaultProperty(Utils::SmallStringView typeName,
|
||||
Utils::SmallStringView propertyName,
|
||||
SourceId sourceId)
|
||||
= 0;
|
||||
virtual void propertyNameDoesNotExists(Utils::SmallStringView propertyName, SourceId sourceId) = 0;
|
||||
|
||||
protected:
|
||||
~ProjectStorageErrorNotifierInterface() = default;
|
||||
|
||||
@@ -98,16 +98,6 @@ TypeNameDoesNotExists::TypeNameDoesNotExists(std::string_view typeName, SourceId
|
||||
keyValue("source id", sourceId));
|
||||
}
|
||||
|
||||
PropertyNameDoesNotExists::PropertyNameDoesNotExists()
|
||||
{
|
||||
category().threadEvent("PropertyNameDoesNotExists"_t);
|
||||
}
|
||||
|
||||
const char *PropertyNameDoesNotExists::what() const noexcept
|
||||
{
|
||||
return "The property name does not exist!";
|
||||
}
|
||||
|
||||
PrototypeChainCycle::PrototypeChainCycle()
|
||||
{
|
||||
category().threadEvent("PrototypeChainCycle"_t);
|
||||
|
||||
@@ -95,13 +95,6 @@ public:
|
||||
TypeNameDoesNotExists(std::string_view typeName, SourceId sourceId = SourceId{});
|
||||
};
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT PropertyNameDoesNotExists : public ProjectStorageError
|
||||
{
|
||||
public:
|
||||
PropertyNameDoesNotExists();
|
||||
const char *what() const noexcept override;
|
||||
};
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT PrototypeChainCycle : public ProjectStorageError
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user