QmlJS: Find prototype resolution errors.

To avoid lots of follow-up errors where the root cause is a failed
prototype resolution or a prototype cycle.

Task-number: QTCREATORBUG-4952
Change-Id: Id474c8c6c152c993aca8c6c421b6d88eb1481676
Reviewed-on: http://codereview.qt.nokia.com/36
Reviewed-by: Thomas Hartmann <Thomas.Hartmann@nokia.com>
This commit is contained in:
Christian Kamm
2011-05-20 13:19:16 +02:00
committed by Thomas Hartmann
parent 044915b2c1
commit 0bf18d008b
3 changed files with 74 additions and 9 deletions

View File

@@ -469,12 +469,42 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId,
return;
}
_scopeBuilder.push(ast);
if (! _context.lookupType(_doc.data(), typeId)) {
bool typeError = false;
const ObjectValue *prototype = _context.lookupType(_doc.data(), typeId);
if (!prototype) {
typeError = true;
if (_options & ErrCheckTypeErrors)
error(typeId->identifierToken,
Check::tr("unknown type"));
} else {
PrototypeIterator iter(prototype, &_context);
QList<const ObjectValue *> prototypes = iter.all();
if (iter.error() != PrototypeIterator::NoError)
typeError = true;
if (_options & ErrCheckTypeErrors) {
const ObjectValue *lastPrototype = prototypes.last();
if (iter.error() == PrototypeIterator::ReferenceResolutionError) {
if (const QmlPrototypeReference *ref =
dynamic_cast<const QmlPrototypeReference *>(lastPrototype->prototype())) {
error(typeId->identifierToken,
Check::tr("could not resolve the prototype %1 of %2").arg(
Bind::toString(ref->qmlTypeName()), lastPrototype->className()));
} else {
error(typeId->identifierToken,
Check::tr("could not resolve the prototype of %1").arg(
lastPrototype->className()));
}
} else if (iter.error() == PrototypeIterator::CycleError) {
error(typeId->identifierToken,
Check::tr("prototype cycle, the last non-repeated object is %1").arg(
lastPrototype->className()));
}
}
}
_scopeBuilder.push(ast);
if (typeError) {
// suppress subsequent errors about scope object lookup by clearing
// the scope object list
// ### todo: better way?