<dependencyList>
<dependency name=\"TextEditor\" version=\"$$QTCREATOR_VERSION\"/>
<dependency name=\"ProjectExplorer\" version=\"$$QTCREATOR_VERSION\"/>
+ <dependency name=\"Locator\" version=\"$$QTCREATOR_VERSION\"/>
</dependencyList>
</plugin>
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qmljsfunctionfilter.h"
+#include "qmljslocatordata.h"
+
+#include <texteditor/itexteditor.h>
+#include <texteditor/basetexteditor.h>
+
+#include <QtCore/QStringMatcher>
+
+using namespace QmlJSTools::Internal;
+
+Q_DECLARE_METATYPE(LocatorData::Entry);
+
+FunctionFilter::FunctionFilter(LocatorData *data, QObject *parent)
+ : Locator::ILocatorFilter(parent)
+ , m_data(data)
+{
+ setShortcutString(QString(QLatin1Char('m')));
+ setIncludedByDefault(false);
+}
+
+FunctionFilter::~FunctionFilter()
+{ }
+
+void FunctionFilter::refresh(QFutureInterface<void> &)
+{
+}
+
+static bool compareLexigraphically(const Locator::FilterEntry &a,
+ const Locator::FilterEntry &b)
+{
+ return a.displayName < b.displayName;
+}
+
+QList<Locator::FilterEntry> FunctionFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry)
+{
+ QString entry = trimWildcards(origEntry);
+ QList<Locator::FilterEntry> goodEntries;
+ QList<Locator::FilterEntry> betterEntries;
+ const QChar asterisk = QLatin1Char('*');
+ QStringMatcher matcher(entry, Qt::CaseInsensitive);
+ const QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
+ if (!regexp.isValid())
+ return goodEntries;
+ bool hasWildcard = (entry.contains(asterisk) || entry.contains('?'));
+
+ QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries());
+ while (it.hasNext()) {
+ if (future.isCanceled())
+ break;
+
+ it.next();
+
+ const QList<LocatorData::Entry> items = it.value();
+ foreach (const LocatorData::Entry &info, items) {
+ if (info.type != LocatorData::Function)
+ continue;
+ if ((hasWildcard && regexp.exactMatch(info.symbolName))
+ || (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) {
+
+ QVariant id = qVariantFromValue(info);
+ Locator::FilterEntry filterEntry(this, info.displayName, id/*, info.icon*/);
+ filterEntry.extraInfo = info.extraInfo;
+
+ if (info.symbolName.startsWith(entry))
+ betterEntries.append(filterEntry);
+ else
+ goodEntries.append(filterEntry);
+ }
+ }
+ }
+
+ if (goodEntries.size() < 1000)
+ qSort(goodEntries.begin(), goodEntries.end(), compareLexigraphically);
+ if (betterEntries.size() < 1000)
+ qSort(betterEntries.begin(), betterEntries.end(), compareLexigraphically);
+
+ betterEntries += goodEntries;
+ return betterEntries;
+}
+
+void FunctionFilter::accept(Locator::FilterEntry selection) const
+{
+ const LocatorData::Entry entry = qvariant_cast<LocatorData::Entry>(selection.internalData);
+ TextEditor::BaseTextEditor::openEditorAt(entry.fileName, entry.line, entry.column,
+ QString(), Core::EditorManager::ModeSwitch);
+}
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef QMLJSFUNCTIONFILTER_H
+#define QMLJSFUNCTIONFILTER_H
+
+#include <locator/ilocatorfilter.h>
+
+namespace QmlJSTools {
+namespace Internal {
+
+class LocatorData;
+
+class FunctionFilter : public Locator::ILocatorFilter
+{
+ Q_OBJECT
+public:
+ explicit FunctionFilter(LocatorData *data, QObject *parent = 0);
+ ~FunctionFilter();
+
+ QString displayName() const { return tr("Functions"); }
+ QString id() const { return QLatin1String("Functions"); }
+ Priority priority() const { return Medium; }
+ QList<Locator::FilterEntry> matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry);
+ void accept(Locator::FilterEntry selection) const;
+ void refresh(QFutureInterface<void> &future);
+
+private:
+ LocatorData *m_data;
+};
+
+} // namespace Internal
+} // namespace QmlJSTools
+
+#endif // QMLJSFUNCTIONFILTER_H
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "qmljslocatordata.h"
+
+#include <qmljs/qmljsmodelmanagerinterface.h>
+#include <qmljs/qmljsbind.h>
+#include <qmljs/qmljsinterpreter.h>
+#include <qmljs/parser/qmljsast_p.h>
+
+using namespace QmlJSTools::Internal;
+using namespace QmlJS;
+using namespace QmlJS::Interpreter;
+using namespace QmlJS::AST;
+
+LocatorData::LocatorData(QObject *parent)
+ : QObject(parent)
+{
+ QmlJS::ModelManagerInterface *manager = QmlJS::ModelManagerInterface::instance();
+
+ connect(manager, SIGNAL(documentUpdated(QmlJS::Document::Ptr)),
+ this, SLOT(onDocumentUpdated(QmlJS::Document::Ptr)));
+ connect(manager, SIGNAL(aboutToRemoveFiles(QStringList)),
+ this, SLOT(onAboutToRemoveFiles(QStringList)));
+}
+
+LocatorData::~LocatorData()
+{}
+
+namespace {
+static QString findId(UiObjectInitializer *initializer)
+{
+ if (!initializer)
+ return QString();
+ for (UiObjectMemberList *member = initializer->members; member; member = member->next) {
+ if (UiScriptBinding *script = cast<UiScriptBinding *>(member->member)) {
+ if (!script->qualifiedId || !script->qualifiedId->name || script->qualifiedId->next)
+ continue;
+ if (script->qualifiedId->name->asString() != QLatin1String("id"))
+ continue;
+ if (ExpressionStatement *expStmt = cast<ExpressionStatement *>(script->statement)) {
+ if (IdentifierExpression *identExp = cast<IdentifierExpression *>(expStmt->expression)) {
+ if (identExp->name)
+ return identExp->name->asString();
+ }
+ }
+ }
+ }
+ return QString();
+}
+
+class FunctionFinder : protected AST::Visitor
+{
+ QList<LocatorData::Entry> m_entries;
+ Document::Ptr m_doc;
+ QString m_context;
+ QString m_documentContext;
+
+public:
+ FunctionFinder()
+ {}
+
+ QList<LocatorData::Entry> run(const Document::Ptr &doc)
+ {
+ m_doc = doc;
+ if (!doc->componentName().isEmpty()) {
+ m_documentContext = doc->componentName();
+ } else {
+ m_documentContext = QFileInfo(doc->fileName()).fileName();
+ }
+ accept(doc->ast(), m_documentContext);
+ return m_entries;
+ }
+
+protected:
+ QString contextString(const QString &extra)
+ {
+ return QString("%1, %2").arg(extra, m_documentContext);
+ }
+
+ LocatorData::Entry basicEntry(SourceLocation loc)
+ {
+ LocatorData::Entry entry;
+ entry.type = LocatorData::Function;
+ entry.extraInfo = m_context;
+ entry.fileName = m_doc->fileName();
+ entry.line = loc.startLine;
+ entry.column = loc.startColumn - 1;
+ return entry;
+ }
+
+ void accept(Node *ast, const QString &context)
+ {
+ const QString old = m_context;
+ m_context = context;
+ Node::accept(ast, this);
+ m_context = old;
+ }
+
+ bool visit(FunctionDeclaration *ast)
+ {
+ return visit(static_cast<FunctionExpression *>(ast));
+ }
+
+ bool visit(FunctionExpression *ast)
+ {
+ if (!ast->name)
+ return true;
+
+ LocatorData::Entry entry = basicEntry(ast->identifierToken);
+
+ entry.type = LocatorData::Function;
+ entry.displayName = ast->name->asString();
+ entry.displayName += QLatin1Char('(');
+ for (FormalParameterList *it = ast->formals; it; it = it->next) {
+ if (it != ast->formals)
+ entry.displayName += QLatin1String(", ");
+ if (it->name)
+ entry.displayName += it->name->asString();
+ }
+ entry.displayName += QLatin1Char(')');
+ entry.symbolName = entry.displayName;
+
+ m_entries += entry;
+
+ accept(ast->body, contextString(QString("function %1").arg(entry.displayName)));
+ return false;
+ }
+
+ bool visit(UiScriptBinding *ast)
+ {
+ if (!ast->qualifiedId)
+ return true;
+ const QString qualifiedIdString = Bind::toString(ast->qualifiedId);
+
+ if (cast<Block *>(ast->statement)) {
+ LocatorData::Entry entry = basicEntry(ast->qualifiedId->identifierToken);
+ entry.displayName = qualifiedIdString;
+ entry.symbolName = qualifiedIdString;
+ m_entries += entry;
+ }
+
+ accept(ast->statement, contextString(Bind::toString(ast->qualifiedId)));
+ return false;
+ }
+
+ bool visit(UiObjectBinding *ast)
+ {
+ if (!ast->qualifiedTypeNameId)
+ return true;
+
+ QString context = Bind::toString(ast->qualifiedTypeNameId);
+ const QString id = findId(ast->initializer);
+ if (!id.isEmpty())
+ context = QString("%1 (%2)").arg(id, context);
+ accept(ast->initializer, contextString(context));
+ return false;
+ }
+
+ bool visit(UiObjectDefinition *ast)
+ {
+ if (!ast->qualifiedTypeNameId)
+ return true;
+
+ QString context = Bind::toString(ast->qualifiedTypeNameId);
+ const QString id = findId(ast->initializer);
+ if (!id.isEmpty())
+ context = QString("%1 (%2)").arg(id, context);
+ accept(ast->initializer, contextString(context));
+ return false;
+ }
+};
+} // anonymous namespace
+
+QHash<QString, QList<LocatorData::Entry> > LocatorData::entries() const
+{
+ return m_entries;
+}
+
+void LocatorData::onDocumentUpdated(const QmlJS::Document::Ptr &doc)
+{
+ QList<Entry> entries = FunctionFinder().run(doc);
+ m_entries.insert(doc->fileName(), entries);
+}
+
+void LocatorData::onAboutToRemoveFiles(const QStringList &files)
+{
+ foreach (const QString &file, files) {
+ m_entries.remove(file);
+ }
+}
+
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#ifndef QMLJSLOCATORDATA_H
+#define QMLJSLOCATORDATA_H
+
+#include <qmljs/qmljsdocument.h>
+
+#include <QtCore/QObject>
+#include <QtCore/QHash>
+
+namespace QmlJSTools {
+namespace Internal {
+
+class LocatorData : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LocatorData(QObject *parent = 0);
+ ~LocatorData();
+
+ enum EntryType
+ {
+ Function,
+ };
+
+ class Entry
+ {
+ public:
+ EntryType type;
+ QString symbolName;
+ QString displayName;
+ QString extraInfo;
+ QString fileName;
+ int line;
+ int column;
+ };
+
+ QHash<QString, QList<Entry> > entries() const;
+
+private slots:
+ void onDocumentUpdated(const QmlJS::Document::Ptr &doc);
+ void onAboutToRemoveFiles(const QStringList &files);
+
+private:
+ QHash<QString, QList<Entry> > m_entries;
+};
+
+} // namespace Internal
+} // namespace QmlJSTools
+
+#endif // QMLJSLOCATORDATA_H
$$PWD/qmljsmodelmanager.h \
$$PWD/qmljsqtstylecodeformatter.h \
$$PWD/qmljsrefactoringchanges.h \
- $$PWD/qmljsplugindumper.h
+ $$PWD/qmljsplugindumper.h \
+ $$PWD/qmljsfunctionfilter.h \
+ $$PWD/qmljslocatordata.h
SOURCES += \
$$PWD/qmljstoolsplugin.cpp \
$$PWD/qmljsmodelmanager.cpp \
$$PWD/qmljsqtstylecodeformatter.cpp \
$$PWD/qmljsrefactoringchanges.cpp \
- $$PWD/qmljsplugindumper.cpp
+ $$PWD/qmljsplugindumper.cpp \
+ $$PWD/qmljsfunctionfilter.cpp \
+ $$PWD/qmljslocatordata.cpp
#include "qmljstoolsplugin.h"
#include "qmljsmodelmanager.h"
+#include "qmljsfunctionfilter.h"
+#include "qmljslocatordata.h"
#include <extensionsystem/pluginmanager.h>
// m_modelManager, SLOT(updateSourceFiles(QStringList)));
addAutoReleasedObject(m_modelManager);
+ LocatorData *locatorData = new LocatorData;
+ addAutoReleasedObject(locatorData);
+ addAutoReleasedObject(new FunctionFilter(locatorData));
+
return true;
}