Allow the user to add instantiating components

This feature is needed to enable code-completion in a dynamically loaded
qml file e.g. let's say that Main.qml is our application entry point and
in it will load *dynamically* another qml file: MyView.qml. At runtime
MyView.qml will see all Main.qml ids and properties. The problem is that
QtCreator doesn't know that MyView.qml will be loaded dynamically by
Main.qml and it can't offer code-completion of Main.qml ids and
properties. This patch allows the user to inform QtCreator that
MyView.qml will be loaded by Main.qml using a simple annotation in
MyView.qml: // @scope Main.qml

It also works recursively e.g. if MyView.qml loads dynamically another
qml file (MyView1.qml) and in MyView1.qml we can add "// @socpe
MyView.qml" annotation. This way QtCreator will offer code-completion of
MyView.qml and Main.qml ids and properties when coding on MyView1.qml.

Change-Id: If50aee81cae40c8b95dbb4c0653e5a91f7a4cff4
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@theqtcompany.com>
This commit is contained in:
BogDan Vatra
2015-02-12 13:21:30 +02:00
parent 5b6d89dd95
commit bb0dc34c50

View File

@@ -286,6 +286,36 @@ void ScopeChain::update() const
m_all += m_jsScopes;
}
static void addInstantiatingComponents(ContextPtr context, QmlComponentChain *chain)
{
const QRegExp importCommentPattern(QLatin1String("@scope\\s+(.*)"));
foreach (const AST::SourceLocation &commentLoc, chain->document()->engine()->comments()) {
const QString &comment = chain->document()->source().mid(commentLoc.begin(), commentLoc.length);
// find all @scope annotations
QStringList additionalScopes;
int lastOffset = -1;
forever {
lastOffset = importCommentPattern.indexIn(comment, lastOffset + 1);
if (lastOffset == -1)
break;
additionalScopes << QFileInfo(chain->document()->path() + QLatin1Char('/') + importCommentPattern.cap(1).trimmed()).absoluteFilePath();
}
foreach (const QmlComponentChain *c, chain->instantiatingComponents())
additionalScopes.removeAll(c->document()->fileName());
foreach (const QString &scope, additionalScopes) {
Document::Ptr doc = context->snapshot().document(scope);
if (doc) {
QmlComponentChain *ch = new QmlComponentChain(doc);
chain->addInstantiatingComponent(ch);
addInstantiatingComponents(context, ch);
}
}
}
}
void ScopeChain::initializeRootScope()
{
ValueOwner *valueOwner = m_context->valueOwner();
@@ -329,7 +359,7 @@ void ScopeChain::initializeRootScope()
if (bind->rootObjectValue())
m_jsScopes += bind->rootObjectValue();
}
addInstantiatingComponents(m_context, chain);
m_modified = true;
}