qmljs: support inline components

* add inline components to bind.
* inserts inline components in the component that contains them (makes
  Context:lookupType simpler)
* unify Context:lookupType overloads without adding extra heap allocations
  using a template (avoid code duplication)
* add tests for inline components
* warn about nested components
* use model manager to load dependencies in tst_check (old test did
  not load dependencies and simply skipped all checks on imports)

Fixes: QTCREATORBUG-24766
Fixes: QTCREATORBUG-24705
Change-Id: Ibcade7752cdaa08e960f66db3a724ab7fb3268cf
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Fawzi Mohamed
2021-01-19 20:34:51 +01:00
parent b8d99af6fd
commit 5c1cbf6b3f
7 changed files with 155 additions and 47 deletions

View File

@@ -152,16 +152,32 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
}
parentObjectValue = switchObjectValue(objectValue);
if (parentObjectValue) {
objectValue->setMember(QLatin1String("parent"), parentObjectValue);
} else if (!_rootObjectValue) {
ObjectValue *nextRoot = _rootObjectValue;
QString parentComponentName = _currentComponentName;
if (!_rootObjectValue) {
_rootObjectValue = objectValue;
_rootObjectValue->setClassName(_doc->componentName());
_inlineComponents[_currentComponentName] = objectValue;
if (!_currentComponentName.isEmpty()) {
if (_currentComponentName.contains('.'))
parentComponentName = _currentComponentName.mid(0,_currentComponentName.lastIndexOf('.'));
else
parentComponentName = "";
nextRoot = _inlineComponents.value(parentComponentName);
// we add the inline component inside its parent
nextRoot->setMember(_currentComponentName.mid(_currentComponentName.lastIndexOf('.') + 1), objectValue);
_rootObjectValue->setClassName(_doc->componentName() + "." + _currentComponentName); // use :: instead of .?
} else {
nextRoot = _rootObjectValue;
_rootObjectValue->setClassName(_doc->componentName());
}
} else if (parentObjectValue) {
objectValue->setMember(QLatin1String("parent"), parentObjectValue);
}
accept(initializer);
_rootObjectValue = nextRoot;
_currentComponentName = parentComponentName;
return switchObjectValue(parentObjectValue);
}
@@ -318,6 +334,18 @@ bool Bind::visit(UiArrayBinding *)
return true;
}
bool Bind::visit(UiInlineComponent *ast)
{
if (!_currentComponentName.isEmpty()) {
_currentComponentName += ".";
_diagnosticMessages->append(
errorMessage(ast, tr("Nested inline components are not supported")));
}
_currentComponentName += ast->name;
_rootObjectValue = nullptr;
return true;
}
bool Bind::visit(PatternElement *ast)
{
if (ast->bindingIdentifier.isEmpty() || !ast->isVariableDeclaration())