LibraryInfo::LibraryInfo()
: _valid(false)
- , _dumpStatus(DumpNotStartedOrRunning)
+ , _dumpStatus(NoTypeInfo)
{
}
: _valid(true)
, _components(parser.components())
, _plugins(parser.plugins())
- , _dumpStatus(DumpNotStartedOrRunning)
+ , _dumpStatus(NoTypeInfo)
{
}
class QMLJS_EXPORT LibraryInfo
{
public:
- enum DumpStatus {
- DumpNotStartedOrRunning,
+ enum PluginTypeInfoStatus {
+ NoTypeInfo,
DumpDone,
- DumpError
+ DumpError,
+ TypeInfoFileDone,
+ TypeInfoFileError
};
private:
typedef QList<LanguageUtils::FakeMetaObject::ConstPtr> FakeMetaObjectList;
FakeMetaObjectList _metaObjects;
- DumpStatus _dumpStatus;
+ PluginTypeInfoStatus _dumpStatus;
QString _dumpError;
public:
bool isValid() const
{ return _valid; }
- DumpStatus dumpStatus() const
+ PluginTypeInfoStatus pluginTypeInfoStatus() const
{ return _dumpStatus; }
- QString dumpError() const
+ QString pluginTypeInfoError() const
{ return _dumpError; }
- void setDumpStatus(DumpStatus dumped, const QString &error = QString())
+ void setPluginTypeInfoStatus(PluginTypeInfoStatus dumped, const QString &error = QString())
{ _dumpStatus = dumped; _dumpError = error; }
};
return _ast;
}
+TypeEnvironment::Import::Import()
+ : object(0)
+{}
+
TypeEnvironment::TypeEnvironment(Engine *engine)
: ObjectValue(engine)
{
}
}
-void TypeEnvironment::addImport(const ObjectValue *import, const ImportInfo &info)
+void TypeEnvironment::addImport(const Import &import)
{
- Import i;
- i.object = import;
- i.info = info;
- _imports.append(i);
+ _imports.append(import);
}
ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *context) const
return ImportInfo();
}
+QList<TypeEnvironment::Import> TypeEnvironment::imports() const
+{
+ return _imports;
+}
+
#ifdef QT_DEBUG
class MemberDumper: public MemberProcessor
class QMLJS_EXPORT TypeEnvironment: public ObjectValue
{
+public:
class Import {
public:
- const ObjectValue *object;
+ Import();
+
+ // const!
+ ObjectValue *object;
ImportInfo info;
+ // uri imports: path to library, else empty
+ QString libraryPath;
};
- // holds imports in the order they appeared,
- // lookup order is back to front
- QList<Import> _imports;
-
public:
TypeEnvironment(Engine *engine);
bool examinePrototypes = true) const;
virtual void processMembers(MemberProcessor *processor) const;
- void addImport(const ObjectValue *import, const ImportInfo &info);
+ void addImport(const Import &import);
+
ImportInfo importInfo(const QString &name, const Context *context) const;
+ QList<Import> imports() const;
#ifdef QT_DEBUG
void dump() const;
#endif
+
+private:
+ // holds imports in the order they appeared,
+ // lookup order is back to front
+ QList<Import> _imports;
};
} } // namespace QmlJS::Interpreter
Interpreter::Context *context;
QStringList importPaths;
- QHash<ImportCacheKey, Interpreter::ObjectValue *> importCache;
+ QHash<ImportCacheKey, TypeEnvironment::Import> importCache;
Document::Ptr doc;
QList<DiagnosticMessage> *diagnosticMessages;
// explicit imports, whether directories, files or libraries
foreach (const ImportInfo &info, doc->bind()->imports()) {
- ObjectValue *import = d->importCache.value(ImportCacheKey(info));
+ TypeEnvironment::Import import = d->importCache.value(ImportCacheKey(info));
- if (!import) {
+ if (!import.object) {
switch (info.type()) {
case ImportInfo::FileImport:
case ImportInfo::DirectoryImport:
default:
break;
}
- if (import)
+ if (import.object)
d->importCache.insert(ImportCacheKey(info), import);
}
- if (import)
- typeEnv->addImport(import, info);
+ typeEnv->addImport(import);
}
}
import "http://www.ovi.com/" as Ovi
*/
-ObjectValue *Link::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo)
+TypeEnvironment::Import Link::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo)
{
Q_D(Link);
- ObjectValue *import = 0;
+ TypeEnvironment::Import import;
+ import.info = importInfo;
+ import.object = 0;
+
const QString &path = importInfo.name();
if (importInfo.type() == ImportInfo::DirectoryImport
|| importInfo.type() == ImportInfo::ImplicitDirectoryImport) {
- import = new ObjectValue(engine());
+ import.object = new ObjectValue(engine());
- importLibrary(doc, import, path, importInfo);
+ importLibrary(doc, path, &import);
const QList<Document::Ptr> &documentsInDirectory = d->snapshot.documentsInDirectory(path);
foreach (Document::Ptr importedDoc, documentsInDirectory) {
if (importedDoc->bind()->rootObjectValue()) {
const QString targetName = importedDoc->componentName();
- import->setProperty(targetName, importedDoc->bind()->rootObjectValue());
+ import.object->setProperty(targetName, importedDoc->bind()->rootObjectValue());
}
}
} else if (importInfo.type() == ImportInfo::FileImport) {
Document::Ptr importedDoc = d->snapshot.document(path);
if (importedDoc)
- import = importedDoc->bind()->rootObjectValue();
+ import.object = importedDoc->bind()->rootObjectValue();
}
return import;
import Qt 4.6 as Xxx
(import com.nokia.qt is the same as the ones above)
*/
-ObjectValue *Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo)
+TypeEnvironment::Import Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo)
{
Q_D(Link);
- ObjectValue *import = new ObjectValue(engine());
+ TypeEnvironment::Import import;
+ import.info = importInfo;
+ import.object = new ObjectValue(engine());
+
const QString packageName = Bind::toString(importInfo.ast()->importUri, '.');
const ComponentVersion version = importInfo.version();
libraryPath += QDir::separator();
libraryPath += packagePath;
- if (importLibrary(doc, import, libraryPath, importInfo, importPath)) {
+ if (importLibrary(doc, libraryPath, &import, importPath)) {
importFound = true;
break;
}
importFound = true;
foreach (QmlObjectValue *object,
engine()->cppQmlTypes().typesForImport(packageName, version)) {
- import->setProperty(object->className(), object);
+ import.object->setProperty(object->className(), object);
}
}
return import;
}
-bool Link::importLibrary(Document::Ptr doc, Interpreter::ObjectValue *import,
+bool Link::importLibrary(Document::Ptr doc,
const QString &libraryPath,
- const Interpreter::ImportInfo &importInfo,
+ TypeEnvironment::Import *import,
const QString &importPath)
{
Q_D(Link);
+ const ImportInfo &importInfo = import->info;
+
const LibraryInfo libraryInfo = d->snapshot.libraryInfo(libraryPath);
if (!libraryInfo.isValid())
return false;
+ import->libraryPath = libraryPath;
+
const ComponentVersion version = importInfo.version();
const UiImport *ast = importInfo.ast();
SourceLocation errorLoc;
errorLoc = locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation());
if (!libraryInfo.plugins().isEmpty()) {
- if (libraryInfo.dumpStatus() == LibraryInfo::DumpNotStartedOrRunning) {
+ if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::NoTypeInfo) {
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
if (modelManager) {
if (importInfo.type() == ImportInfo::LibraryImport) {
warning(doc, errorLoc,
tr("Library contains C++ plugins, type dump is in progress."));
}
- } else if (libraryInfo.dumpStatus() == LibraryInfo::DumpError) {
+ } else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError
+ || libraryInfo.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileError) {
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
// Only underline import if package/version isn't described in .qmltypes anyway
const QString packageName = importInfo.name().replace(QDir::separator(), QLatin1Char('.'));
if (!builtinPackages.value(packageName).contains(importInfo.version())) {
if (errorLoc.isValid()) {
- error(doc, errorLoc, libraryInfo.dumpError());
+ error(doc, errorLoc, libraryInfo.pluginTypeInfoError());
}
}
} else {
engine()->cppQmlTypes().load(engine(), libraryInfo.metaObjects());
foreach (QmlObjectValue *object, loadedObjects) {
if (object->packageName().isEmpty()) {
- import->setProperty(object->className(), object);
+ import->object->setProperty(object->className(), object);
}
}
}
}
- loadQmldirComponents(import, version, libraryInfo, libraryPath);
+ loadQmldirComponents(import->object, version, libraryInfo, libraryPath);
return true;
}
ImportInfo implcitDirectoryImportInfo(
ImportInfo::ImplicitDirectoryImport, doc->path());
- ObjectValue *directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
- if (!directoryImport) {
+ TypeEnvironment::Import directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
+ if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo);
- if (directoryImport)
+ if (directoryImport.object)
d->importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport);
}
- if (directoryImport)
- typeEnv->addImport(directoryImport, implcitDirectoryImportInfo);
+ if (directoryImport.object) {
+ typeEnv->addImport(directoryImport);
+ }
}
void Link::loadImplicitDefaultImports(TypeEnvironment *typeEnv)
const QString defaultPackage = CppQmlTypes::defaultPackage;
if (engine()->cppQmlTypes().hasPackage(defaultPackage)) {
ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
- ObjectValue *import = d->importCache.value(ImportCacheKey(info));
- if (!import) {
- import = new ObjectValue(engine());
+ TypeEnvironment::Import import = d->importCache.value(ImportCacheKey(info));
+ if (!import.object) {
+ import.info = info;
+ import.object = new ObjectValue(engine());
foreach (QmlObjectValue *object,
engine()->cppQmlTypes().typesForImport(defaultPackage, ComponentVersion())) {
- import->setProperty(object->className(), object);
+ import.object->setProperty(object->className(), object);
}
d->importCache.insert(ImportCacheKey(info), import);
}
- typeEnv->addImport(import, info);
+ typeEnv->addImport(import);
}
}
void linkImports();
void populateImportedTypes(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc);
- Interpreter::ObjectValue *importFileOrDirectory(Document::Ptr doc, const Interpreter::ImportInfo &importInfo);
- Interpreter::ObjectValue *importNonFile(Document::Ptr doc, const Interpreter::ImportInfo &importInfo);
+ Interpreter::TypeEnvironment::Import importFileOrDirectory(
+ Document::Ptr doc,
+ const Interpreter::ImportInfo &importInfo);
+ Interpreter::TypeEnvironment::Import importNonFile(
+ Document::Ptr doc,
+ const Interpreter::ImportInfo &importInfo);
void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace);
bool importLibrary(Document::Ptr doc,
- Interpreter::ObjectValue *import,
const QString &libraryPath,
- const Interpreter::ImportInfo &importInfo,
+ Interpreter::TypeEnvironment::Import *import,
const QString &importPath = QString());
void loadQmldirComponents(Interpreter::ObjectValue *import,
LanguageUtils::ComponentVersion version,
return;
QList<AST::Node *> astPath = semanticInfo.astPath(pos);
- if (astPath.isEmpty())
- return;
const Document::Ptr qmlDocument = semanticInfo.document;
LookupContext::Ptr lookupContext = semanticInfo.lookupContext(astPath);
+ AST::Node *node = semanticInfo.nodeUnderCursor(pos);
+ if (astPath.isEmpty()) {
+ if (AST::UiImport *import = AST::cast<AST::UiImport *>(node))
+ handleImport(lookupContext, import);
+ return;
+ }
if (matchColorItem(lookupContext, qmlDocument, astPath, pos))
return;
- AST::Node *node = semanticInfo.nodeUnderCursor(pos);
handleOrdinaryMatch(lookupContext, node);
TextEditor::HelpItem helpItem = qmlHelpItem(lookupContext, node);
}
}
+void HoverHandler::handleImport(const LookupContext::Ptr &lookupContext, AST::UiImport *node)
+{
+ const Interpreter::TypeEnvironment *typeEnv = lookupContext->context()->typeEnvironment(lookupContext->document().data());
+ if (!typeEnv)
+ return;
+
+ foreach (const Interpreter::TypeEnvironment::Import &import, typeEnv->imports()) {
+ if (import.info.ast() == node) {
+ if (import.info.type() == Interpreter::ImportInfo::LibraryImport
+ && !import.libraryPath.isEmpty()) {
+ QString msg = tr("Library at %1").arg(import.libraryPath);
+ const LibraryInfo &libraryInfo = lookupContext->snapshot().libraryInfo(import.libraryPath);
+ if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpDone) {
+ msg += QLatin1Char('\n');
+ msg += tr("Dumped plugins successfully.");
+ } else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
+ msg += QLatin1Char('\n');
+ msg += tr("Read typeinfo files successfully.");
+ }
+ setToolTip(msg);
+ } else {
+ setToolTip(import.info.name());
+ }
+ break;
+ }
+ }
+}
+
void HoverHandler::reset()
{
m_colorTip = QColor();
unsigned pos);
void handleOrdinaryMatch(const QmlJS::LookupContext::Ptr &lookupContext,
QmlJS::AST::Node *node);
+ void handleImport(const QmlJS::LookupContext::Ptr &lookupContext,
+ QmlJS::AST::UiImport *node);
void prettyPrintTooltip(const QmlJS::Interpreter::Value *value,
const QmlJS::Interpreter::Context *context);
return;
const Snapshot snapshot = m_modelManager->snapshot();
const LibraryInfo libraryInfo = snapshot.libraryInfo(canonicalLibraryPath);
- if (libraryInfo.dumpStatus() != LibraryInfo::DumpNotStartedOrRunning)
+ if (libraryInfo.pluginTypeInfoStatus() != LibraryInfo::NoTypeInfo)
return;
// avoid inserting the same plugin twice
Core::MessageManager *messageManager = Core::MessageManager::instance();
const QString errorMessages = process->readAllStandardError();
messageManager->printToOutputPane(qmldumpErrorMessage(libraryPath, errorMessages));
- libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
}
const QByteArray output = process->readAllStandardOutput();
QString error;
QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
if (exitCode == 0 && !error.isEmpty()) {
- libraryInfo.setDumpStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
}
if (exitCode == 0 && error.isEmpty()) {
// ### disabled code path for running qmldump to get Qt's builtins
// if (libraryPath.isEmpty())
// Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList);
- libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone);
}
if (!libraryPath.isEmpty())
if (!libraryPath.isEmpty()) {
const Snapshot snapshot = m_modelManager->snapshot();
LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
- libraryInfo.setDumpStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(errorMessages));
m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
}
}
const QString &path = plugin.predumpedQmlTypesFilePath();
Utils::FileReader reader;
if (!reader.fetch(path, QFile::Text)) {
- libraryInfo.setDumpStatus(LibraryInfo::DumpError, reader.errorString());
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError, reader.errorString());
m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
return;
}
if (error.isEmpty()) {
libraryInfo.setMetaObjects(objectsList);
- libraryInfo.setDumpStatus(LibraryInfo::DumpDone);
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileDone);
} else {
- libraryInfo.setDumpStatus(LibraryInfo::DumpError,
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError,
tr("Failed to parse '%1'.\nError: %2").arg(path, error));
}
m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
if (!libraryInfo.isValid())
return;
- libraryInfo.setDumpStatus(LibraryInfo::DumpError,
+ libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError,
tr("Could not locate the helper application for dumping type information from C++ plugins.\n"
"Please build the debugging helpers on the Qt version options page."));
m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);