QmlJS checks: Disable some checks when imports failed.

The important error in this case is on the import.

Change-Id: I3a547ca7ac44a89aba6819ea80ec52185071408a
Reviewed-on: http://codereview.qt-project.org/5879
Reviewed-by: Christian Kamm <christian.d.kamm@nokia.com>
Sanity-Review: Christian Kamm <christian.d.kamm@nokia.com>
This commit is contained in:
Christian Kamm
2011-09-29 11:48:13 +02:00
parent f3c78d3522
commit 038111c384
5 changed files with 59 additions and 20 deletions

View File

@@ -513,7 +513,12 @@ Check::Check(Document::Ptr doc, const ContextPtr &context)
, _scopeChain(doc, _context)
, _scopeBuilder(&_scopeChain)
, _lastValue(0)
, _importsOk(false)
{
const Imports *imports = context->imports(doc.data());
if (imports && !imports->importFailed())
_importsOk = true;
_enabledMessages = Message::allMessageTypes().toSet();
disableMessage(HintAnonymousFunctionSpacing);
disableMessage(HintDeclareVarsInOneLine);
@@ -623,29 +628,31 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId,
}
bool typeError = false;
const SourceLocation typeErrorLocation = fullLocationForQualifiedId(typeId);
const ObjectValue *prototype = _context->lookupType(_doc.data(), typeId);
if (!prototype) {
typeError = true;
addMessage(ErrUnknownComponent, typeErrorLocation);
} else {
PrototypeIterator iter(prototype, _context);
QList<const ObjectValue *> prototypes = iter.all();
if (iter.error() != PrototypeIterator::NoError)
if (_importsOk) {
const SourceLocation typeErrorLocation = fullLocationForQualifiedId(typeId);
const ObjectValue *prototype = _context->lookupType(_doc.data(), typeId);
if (!prototype) {
typeError = true;
const ObjectValue *lastPrototype = prototypes.last();
if (iter.error() == PrototypeIterator::ReferenceResolutionError) {
if (const QmlPrototypeReference *ref =
dynamic_cast<const QmlPrototypeReference *>(lastPrototype->prototype())) {
addMessage(ErrCouldNotResolvePrototypeOf, typeErrorLocation,
toString(ref->qmlTypeName()), lastPrototype->className());
} else {
addMessage(ErrCouldNotResolvePrototype, typeErrorLocation,
addMessage(ErrUnknownComponent, typeErrorLocation);
} else {
PrototypeIterator iter(prototype, _context);
QList<const ObjectValue *> prototypes = iter.all();
if (iter.error() != PrototypeIterator::NoError)
typeError = true;
const ObjectValue *lastPrototype = prototypes.last();
if (iter.error() == PrototypeIterator::ReferenceResolutionError) {
if (const QmlPrototypeReference *ref =
dynamic_cast<const QmlPrototypeReference *>(lastPrototype->prototype())) {
addMessage(ErrCouldNotResolvePrototypeOf, typeErrorLocation,
toString(ref->qmlTypeName()), lastPrototype->className());
} else {
addMessage(ErrCouldNotResolvePrototype, typeErrorLocation,
lastPrototype->className());
}
} else if (iter.error() == PrototypeIterator::CycleError) {
addMessage(ErrPrototypeCycle, typeErrorLocation,
lastPrototype->className());
}
} else if (iter.error() == PrototypeIterator::CycleError) {
addMessage(ErrPrototypeCycle, typeErrorLocation,
lastPrototype->className());
}
}
@@ -1197,6 +1204,9 @@ bool Check::visit(StatementList *ast)
/// ### Maybe put this into the context as a helper method.
const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
{
if (!_importsOk)
return 0;
QList<const ObjectValue *> scopeObjects = _scopeChain.qmlScopeObjects();
if (scopeObjects.isEmpty())
return 0;

View File

@@ -129,6 +129,8 @@ private:
QList<AST::Node *> _chain;
QStack<StringSet> m_idStack;
QStack<StringSet> m_propertyStack;
bool _importsOk;
};
} // namespace QmlJS

View File

@@ -2141,6 +2141,7 @@ void JSImportScope::processMembers(MemberProcessor *processor) const
Imports::Imports(ValueOwner *valueOwner)
: _typeScope(new TypeScope(this, valueOwner))
, _jsImportScope(new JSImportScope(this, valueOwner))
, _importFailed(false)
{}
void Imports::append(const Import &import)
@@ -2159,6 +2160,14 @@ void Imports::append(const Import &import)
// not found, append
_imports.append(import);
}
if (!import.valid)
_importFailed = true;
}
void Imports::setImportFailed()
{
_importFailed = true;
}
ImportInfo Imports::info(const QString &name, const Context *context) const
@@ -2219,6 +2228,11 @@ QString Imports::nameForImportedObject(const ObjectValue *value, const Context *
return QString();
}
bool Imports::importFailed() const
{
return _importFailed;
}
QList<Import> Imports::all() const
{
return _imports;

View File

@@ -866,6 +866,8 @@ public:
ImportInfo info;
// uri imports: path to library, else empty
QString libraryPath;
// whether the import succeeded
bool valid;
};
class Imports;
@@ -904,9 +906,12 @@ public:
Imports(ValueOwner *valueOwner);
void append(const Import &import);
void setImportFailed();
ImportInfo info(const QString &name, const Context *context) const;
QString nameForImportedObject(const ObjectValue *value, const Context *context) const;
bool importFailed() const;
QList<Import> all() const;
const TypeScope *typeScope() const;
@@ -922,6 +927,7 @@ private:
QList<Import> _imports;
TypeScope *_typeScope;
JSImportScope *_jsImportScope;
bool _importFailed;
};
} // namespace QmlJS

View File

@@ -257,6 +257,7 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
import = importNonFile(doc, info);
break;
case ImportInfo::UnknownFileImport:
imports->setImportFailed();
if (info.ast()) {
error(doc, info.ast()->fileNameToken,
Link::tr("file or directory not found"));
@@ -288,6 +289,7 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
Import import;
import.info = importInfo;
import.object = 0;
import.valid = true;
const QString &path = importInfo.path();
@@ -323,6 +325,7 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
Import import;
import.info = importInfo;
import.object = new ObjectValue(valueOwner);
import.valid = true;
const QString packageName = importInfo.name();
const ComponentVersion version = importInfo.version();
@@ -370,6 +373,7 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
}
if (!importFound && importInfo.ast()) {
import.valid = false;
error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(),
importInfo.ast()->lastSourceLocation()),
Link::tr(
@@ -422,6 +426,7 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
if (errorLoc.isValid()) {
warning(doc, errorLoc,
Link::tr("QML module contains C++ plugins, currently reading type information..."));
import->valid = false;
}
} else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError
|| libraryInfo.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileError) {
@@ -429,6 +434,7 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
QString packageName = importInfo.name();
if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName))) {
error(doc, errorLoc, libraryInfo.pluginTypeInfoError());
import->valid = false;
}
} else {
const QString packageName = importInfo.name();
@@ -513,6 +519,7 @@ void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
const ImportInfo info = ImportInfo::moduleImport(defaultPackage, maxVersion, QString());
Import import = importCache.value(ImportCacheKey(info));
if (!import.object) {
import.valid = true;
import.info = info;
import.object = new ObjectValue(valueOwner);
foreach (const QmlObjectValue *object,