Commit 96e5cae4 authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

Added metainfo classes from Bauhaus for use in the QML editor.

parent 5a0b7f8e
......@@ -42,14 +42,16 @@
using namespace QmlEditor;
using namespace QmlEditor::Internal;
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager,QObject *parent)
QmlCodeCompletion::QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent)
: TextEditor::ICompletionCollector(parent),
m_modelManager(modelManager),
m_editor(0),
m_startPosition(0),
m_caseSensitivity(Qt::CaseSensitive)
m_caseSensitivity(Qt::CaseSensitive),
m_typeSystem(typeSystem)
{
Q_ASSERT(modelManager);
Q_ASSERT(typeSystem);
}
QmlCodeCompletion::~QmlCodeCompletion()
......@@ -119,13 +121,13 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
cursor.setPosition(pos);
expressionUnderCursor(cursor, qmlDocument);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot());
QmlLookupContext context(expressionUnderCursor.expressionScopes(), qmlDocument, m_modelManager->snapshot(), m_typeSystem);
QmlResolveExpression resolver(context);
// qDebug()<<"*** expression under cursor:"<<expressionUnderCursor.expressionNode();
QList<QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
QList<Qml::QmlSymbol*> symbols = resolver.visibleSymbols(expressionUnderCursor.expressionNode());
// qDebug()<<"***"<<symbols.size()<<"visible symbols";
foreach (QmlSymbol *symbol, symbols) {
foreach (Qml::QmlSymbol *symbol, symbols) {
QString word;
if (symbol->isIdSymbol()) {
......
#ifndef QMLCODECOMPLETION_H
#define QMLCODECOMPLETION_H
#include <qml/metatype/qmltypesystem.h>
#include <texteditor/icompletioncollector.h>
namespace TextEditor {
......@@ -18,7 +19,7 @@ class QmlCodeCompletion: public TextEditor::ICompletionCollector
Q_OBJECT
public:
QmlCodeCompletion(QmlModelManagerInterface *modelManager, QObject *parent = 0);
QmlCodeCompletion(QmlModelManagerInterface *modelManager, Qml::MetaType::QmlTypeSystem *typeSystem, QObject *parent = 0);
virtual ~QmlCodeCompletion();
Qt::CaseSensitivity caseSensitivity() const;
......@@ -38,6 +39,7 @@ private:
int m_startPosition;
QList<TextEditor::CompletionItem> m_completions;
Qt::CaseSensitivity m_caseSensitivity;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
......
......@@ -37,6 +37,7 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
......@@ -68,6 +69,7 @@ enum {
UPDATE_DOCUMENT_DEFAULT_INTERVAL = 250
};
using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
using namespace SharedTools;
......@@ -378,7 +380,8 @@ ScriptEditorEditable::ScriptEditorEditable(ScriptEditor *editor)
ScriptEditor::ScriptEditor(QWidget *parent) :
TextEditor::BaseTextEditor(parent),
m_methodCombo(0),
m_modelManager(0)
m_modelManager(0),
m_typeSystem(0)
{
setParenthesesMatchingEnabled(true);
setMarksVisible(true);
......@@ -397,6 +400,7 @@ ScriptEditor::ScriptEditor(QWidget *parent) :
baseTextDocument()->setSyntaxHighlighter(new QmlHighlighter);
m_modelManager = ExtensionSystem::PluginManager::instance()->getObject<QmlModelManagerInterface>();
m_typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
if (m_modelManager) {
connect(m_modelManager, SIGNAL(documentUpdated(QmlEditor::QmlDocument::Ptr)),
......@@ -768,7 +772,7 @@ TextEditor::BaseTextEditor::Link ScriptEditor::findLinkAt(const QTextCursor &cur
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(expressionCursor, doc);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, snapshot, m_typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *symbol = resolver.typeOf(expressionUnderCursor.expressionNode());
......
......@@ -43,6 +43,12 @@ namespace Core {
class ICore;
}
namespace Qml {
namespace MetaType {
class QmlTypeSystem;
}
}
namespace QmlEditor {
class QmlModelManagerInterface;
......@@ -146,6 +152,7 @@ private:
QList<QmlJS::DiagnosticMessage> m_diagnosticMessages;
QmlDocument::Ptr m_document;
QmlModelManagerInterface *m_modelManager;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal
......
......@@ -94,6 +94,8 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
m_modelManager = new QmlModelManager(this);
addAutoReleasedObject(m_modelManager);
Qml::MetaType::QmlTypeSystem *typeSystem = new Qml::MetaType::QmlTypeSystem;
addAutoReleasedObject(typeSystem);
QList<int> context;
context<< core->uniqueIDManager()->uniqueIdentifier(QmlEditor::Constants::C_QMLEDITOR);
......@@ -122,7 +124,7 @@ bool QmlEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION);
contextMenu->addAction(cmd);
m_completion = new QmlCodeCompletion(m_modelManager);
m_completion = new QmlCodeCompletion(m_modelManager, typeSystem);
addAutoReleasedObject(m_completion);
addAutoReleasedObject(new QmlHoverHandler());
......
......@@ -9,6 +9,7 @@
#include <QDebug>
using namespace Qml;
using namespace QmlJS;
using namespace QmlJS::AST;
......@@ -118,7 +119,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectBinding *ast)
{
if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}
......@@ -128,7 +129,7 @@ namespace QmlEditor {
virtual bool visit(UiObjectDefinition *ast)
{
if (ast->initializer && ast->initializer->rbraceToken.offset < _pos && _pos <= ast->initializer->lbraceToken.end()) {
if (ast->initializer && ast->initializer->lbraceToken.offset < _pos && _pos <= ast->initializer->rbraceToken.end()) {
push(ast);
Node::accept(ast->initializer, this);
}
......
......@@ -26,7 +26,7 @@ public:
void operator()(const QTextCursor &cursor, const QmlDocument::Ptr &doc);
QStack<QmlSymbol *> expressionScopes() const
QStack<Qml::QmlSymbol *> expressionScopes() const
{ return _expressionScopes; }
QmlJS::AST::Node *expressionNode() const
......@@ -45,7 +45,7 @@ private:
QmlJS::AST::UiObjectMember *tryBinding(const QString &text);
private:
QStack<QmlSymbol *> _expressionScopes;
QStack<Qml::QmlSymbol *> _expressionScopes;
QmlJS::AST::Node *_expressionNode;
int _expressionOffset;
int _expressionLength;
......
......@@ -52,6 +52,7 @@
#include <QtHelp/QHelpEngineCore>
using namespace Core;
using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
......@@ -186,7 +187,9 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in
QmlExpressionUnderCursor expressionUnderCursor;
expressionUnderCursor(tc, doc);
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot());
Qml::MetaType::QmlTypeSystem *typeSystem = ExtensionSystem::PluginManager::instance()->getObject<Qml::MetaType::QmlTypeSystem>();
QmlLookupContext context(expressionUnderCursor.expressionScopes(), doc, m_modelManager->snapshot(), typeSystem);
QmlResolveExpression resolver(context);
QmlSymbol *resolvedSymbol = resolver.typeOf(expressionUnderCursor.expressionNode());
......
......@@ -2,11 +2,14 @@
#include "qmllookupcontext.h"
#include "qmlresolveexpression.h"
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
#include <QDebug>
using namespace Qml;
using namespace Qml::MetaType;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
......@@ -14,11 +17,14 @@ using namespace QmlJS::AST;
QmlLookupContext::QmlLookupContext(const QStack<QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
const Snapshot &snapshot):
const Snapshot &snapshot,
QmlTypeSystem *typeSystem):
_scopes(scopes),
_doc(doc),
_snapshot(snapshot)
_snapshot(snapshot),
m_typeSystem(typeSystem)
{
Q_ASSERT(typeSystem != 0);
}
static inline int findFirstQmlObjectScope(const QStack<QmlSymbol*> &scopes, int startIdx)
......@@ -114,104 +120,12 @@ QmlSymbol *QmlLookupContext::resolveType(const QString &name, const QString &fil
return resolveBuildinType(name);
}
// FIXME: use a REAL mete-type system here!
static QSet<QString> qmlMetaTypes = QSet<QString>()
<< QLatin1String("AnchorChanges")
<< QLatin1String("AnimatedImage")
<< QLatin1String("Animation")
<< QLatin1String("Behavior")
<< QLatin1String("Binding")
<< QLatin1String("BorderImage")
<< QLatin1String("ColorAnimation")
<< QLatin1String("Column")
<< QLatin1String("Component")
<< QLatin1String("Connection")
<< QLatin1String("DateTimeFormatter")
<< QLatin1String("EaseFollow")
<< QLatin1String("Flickable")
<< QLatin1String("Flipable")
<< QLatin1String("FocusPanel")
<< QLatin1String("FocusScope")
<< QLatin1String("FolderListModel")
<< QLatin1String("FontLoader")
<< QLatin1String("Gradient")
<< QLatin1String("GradientStop")
<< QLatin1String("GraphicsObjectContainer")
<< QLatin1String("Grid")
<< QLatin1String("GridView")
<< QLatin1String("Image")
<< QLatin1String("Item")
<< QLatin1String("KeyEvent")
<< QLatin1String("Keys")
<< QLatin1String("LayoutItem")
<< QLatin1String("ListModel")
<< QLatin1String("ListView")
<< QLatin1String("Loader")
<< QLatin1String("MouseEvent")
<< QLatin1String("MouseRegion")
<< QLatin1String("NumberAnimation")
<< QLatin1String("NumberFormatter")
<< QLatin1String("ParallelAnimation")
<< QLatin1String("ParentAction")
<< QLatin1String("ParentChange")
<< QLatin1String("ParticleMotionGravity")
<< QLatin1String("ParticleMotionLinear")
<< QLatin1String("ParticleMotionWander")
<< QLatin1String("Particles")
<< QLatin1String("Path")
<< QLatin1String("PathAttribute")
<< QLatin1String("PathCubic")
<< QLatin1String("PathElement")
<< QLatin1String("PathLine")
<< QLatin1String("PathPercent")
<< QLatin1String("PathQuad")
<< QLatin1String("PathView")
<< QLatin1String("PauseAnimation")
<< QLatin1String("PropertyAction")
<< QLatin1String("PropertyAnimation")
<< QLatin1String("PropertyChanges")
<< QLatin1String("Rectangle")
<< QLatin1String("Repeater")
<< QLatin1String("Rotation")
<< QLatin1String("Row")
<< QLatin1String("Scale")
<< QLatin1String("Script")
<< QLatin1String("ScriptAction")
<< QLatin1String("SequentialAnimation")
<< QLatin1String("SpringFollow")
<< QLatin1String("SqlBind")
<< QLatin1String("SqlConnection")
<< QLatin1String("SqlQuery")
<< QLatin1String("State")
<< QLatin1String("StateChangeScript")
<< QLatin1String("SystemPalette")
<< QLatin1String("Text")
<< QLatin1String("TextEdit")
<< QLatin1String("TextInput")
<< QLatin1String("Timer")
<< QLatin1String("Transform")
<< QLatin1String("Transition")
<< QLatin1String("VisualItemModel")
<< QLatin1String("WebView")
<< QLatin1String("XmlListModel")
<< QLatin1String("XmlRole");
QmlSymbol *QmlLookupContext::resolveBuildinType(const QString &name)
{
// FIXME: use a REAL mete-type system here!
if (name == "Rectangle") {
QmlBuildInSymbol *rectSymbol = new QmlBuildInSymbol(name);
rectSymbol->addMember(new QmlBuildInSymbol("x"));
rectSymbol->addMember(new QmlBuildInSymbol("y"));
rectSymbol->addMember(new QmlBuildInSymbol("height"));
rectSymbol->addMember(new QmlBuildInSymbol("width"));
return rectSymbol;
} else if (qmlMetaTypes.contains(name)) {
return new QmlBuildInSymbol(name);
} else {
return 0;
}
QList<Qml::PackageInfo> packages;
// FIXME:
packages.append(PackageInfo("Qt", 4, 6));
return m_typeSystem->resolve(name, packages);
}
QmlSymbol *QmlLookupContext::resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName)
......@@ -270,7 +184,11 @@ QList<QmlSymbol*> QmlLookupContext::visibleSymbolsInScope()
if (!_scopes.isEmpty()) {
QmlSymbol *scope = _scopes.top();
// add members defined in this symbol:
result.append(scope->members());
// add the members of the type of this scope (= object):
result.append(expandType(scope));
}
return result;
......@@ -301,9 +219,27 @@ QList<QmlSymbol*> QmlLookupContext::visibleTypes()
}
}
// TODO: handle Qt imports, hack for now:
foreach (const QString &name, qmlMetaTypes)
result.append(resolveBuildinType(name));
result.append(m_typeSystem->availableTypes("Qt", 4, 6));
return result;
}
QList<QmlSymbol*> QmlLookupContext::expandType(Qml::QmlSymbol *symbol)
{
if (symbol == 0) {
return QList<QmlSymbol*>();
} else if (QmlBuildInSymbol *buildInSymbol = symbol->asBuildInSymbol()) {
return buildInSymbol->members(true);
} else if (QmlSymbolFromFile *symbolFromFile = symbol->asSymbolFromFile()){
QList<QmlSymbol*> result;
if (QmlSymbol *superTypeSymbol = resolveType(symbolFromFile->name(), symbolFromFile->fileName())) {
result.append(superTypeSymbol->members());
result.append(expandType(superTypeSymbol));
}
return result;
} else {
return QList<QmlSymbol*>();
}
}
#ifndef QMLLOOKUPCONTEXT_H
#define QMLLOOKUPCONTEXT_H
#include <qml/metatype/qmltypesystem.h>
#include <qml/parser/qmljsastvisitor_p.h>
#include <qml/qmldocument.h>
#include <qml/qmlsymbol.h>
......@@ -13,33 +14,37 @@ namespace Internal {
class QmlLookupContext
{
public:
QmlLookupContext(const QStack<QmlSymbol *> &scopes,
QmlLookupContext(const QStack<Qml::QmlSymbol *> &scopes,
const QmlDocument::Ptr &doc,
const Snapshot &snapshot);
const Snapshot &snapshot,
Qml::MetaType::QmlTypeSystem *typeSystem);
QmlSymbol *resolve(const QString &name);
QmlSymbol *resolveType(const QString &name)
Qml::QmlSymbol *resolve(const QString &name);
Qml::QmlSymbol *resolveType(const QString &name)
{ return resolveType(name, _doc->fileName()); }
QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
Qml::QmlSymbol *resolveType(QmlJS::AST::UiQualifiedId *name)
{ return resolveType(toString(name), _doc->fileName()); }
QmlDocument::Ptr document() const
{ return _doc; }
QList<QmlSymbol*> visibleSymbolsInScope();
QList<QmlSymbol*> visibleTypes();
QList<Qml::QmlSymbol*> visibleSymbolsInScope();
QList<Qml::QmlSymbol*> visibleTypes();
QList<Qml::QmlSymbol*> expandType(Qml::QmlSymbol *symbol);
private:
QmlSymbol *resolveType(const QString &name, const QString &fileName);
QmlSymbol *resolveProperty(const QString &name, QmlSymbol *scope, const QString &fileName);
QmlSymbol *resolveBuildinType(const QString &name);
Qml::QmlSymbol *resolveType(const QString &name, const QString &fileName);
Qml::QmlSymbol *resolveProperty(const QString &name, Qml::QmlSymbol *scope, const QString &fileName);
Qml::QmlSymbol *resolveBuildinType(const QString &name);
static QString toString(QmlJS::AST::UiQualifiedId *id);
private:
QStack<QmlSymbol *> _scopes;
QStack<Qml::QmlSymbol *> _scopes;
QmlDocument::Ptr _doc;
Snapshot _snapshot;
Qml::MetaType::QmlTypeSystem *m_typeSystem;
};
} // namespace Internal
......
......@@ -37,6 +37,7 @@
#include <QSharedPointer>
#include <qml/qmldocument.h>
#include <qml/metatype/qmltypesystem.h>
namespace QmlEditor {
......
......@@ -3,6 +3,7 @@
#include <qml/parser/qmljsast_p.h>
#include <qml/parser/qmljsengine_p.h>
using namespace Qml;
using namespace QmlEditor;
using namespace QmlEditor::Internal;
using namespace QmlJS;
......@@ -16,8 +17,7 @@ QmlResolveExpression::QmlResolveExpression(const QmlLookupContext &context)
QmlSymbol *QmlResolveExpression::typeOf(Node *node)
{
QmlSymbol *previousValue = switchValue(0);
if (node)
node->accept(this);
Node::accept(node, this);
return switchValue(previousValue);
}
......
......@@ -14,13 +14,13 @@ class QmlResolveExpression: protected QmlJS::AST::Visitor
public:
QmlResolveExpression(const QmlLookupContext &context);
QmlSymbol *typeOf(QmlJS::AST::Node *node);
QList<QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
Qml::QmlSymbol *typeOf(QmlJS::AST::Node *node);
QList<Qml::QmlSymbol*> visibleSymbols(QmlJS::AST::Node *node);
protected:
using QmlJS::AST::Visitor::visit;
QmlSymbol *switchValue(QmlSymbol *symbol);
Qml::QmlSymbol *switchValue(Qml::QmlSymbol *symbol);
virtual bool visit(QmlJS::AST::FieldMemberExpression *ast);
virtual bool visit(QmlJS::AST::IdentifierExpression *ast);
......@@ -28,7 +28,7 @@ protected:
private:
QmlLookupContext _context;
QmlSymbol *_value;
Qml::QmlSymbol *_value;
};
} // namespace Internal
......
#include "QmlMetaTypeBackend.h"
#include "qmltypesystem.h"
using namespace Qml::MetaType;
QmlMetaTypeBackend::QmlMetaTypeBackend(QmlTypeSystem *typeSystem):
m_typeSystem(typeSystem)
{
Q_ASSERT(typeSystem);
}
QmlMetaTypeBackend::~QmlMetaTypeBackend()
{
}
#ifndef QMLMETATYPEBACKEND_H
#define QMLMETATYPEBACKEND_H
#include <qml/qml_global.h>
#include <qml/qmlpackageinfo.h>
#include <qml/qmlsymbol.h>
namespace Qml {
namespace MetaType {
class QmlTypeSystem;
class QML_EXPORT QmlMetaTypeBackend
{
public:
QmlMetaTypeBackend(QmlTypeSystem *typeSystem);
virtual ~QmlMetaTypeBackend() = 0;
virtual QList<QmlSymbol *> availableTypes(const QString &package, int majorVersion, int minorVersion) = 0;
virtual QmlSymbol *resolve(const QString &typeName, const QList<PackageInfo> &packages) = 0;
protected:
QmlTypeSystem *typeSystem() const
{ return m_typeSystem; }
private:
QmlTypeSystem *m_typeSystem;
};
} // namespace MetaType
} // namespace Qml
#endif // QMLMETATYPEBACKEND_H
#include "metainfo.h"
#include "QtDeclarativeMetaTypeBackend.h"
#include <QDebug>
namespace Qml {
namespace MetaType {
namespace Internal {
class QmlDeclarativeSymbol: public QmlBuildInSymbol
{
public:
virtual ~QmlDeclarativeSymbol()
{}
protected:
QmlDeclarativeSymbol(QtDeclarativeMetaTypeBackend* backend):
m_backend(backend)
{ Q_ASSERT(backend); }
QtDeclarativeMetaTypeBackend* backend() const
{ return m_backend; }
private:
QtDeclarativeMetaTypeBackend* m_backend;
};
class QmlDeclarativeObjectSymbol: public QmlDeclarativeSymbol
{
QmlDeclarativeObjectSymbol(const QmlDeclarativeObjectSymbol &);
QmlDeclarativeObjectSymbol &operator=(const QmlDeclarativeObjectSymbol &);
public:
QmlDeclarativeObjectSymbol(const QKineticDesigner::NodeMetaInfo &metaInfo, QtDeclarativeMetaTypeBackend* backend):
QmlDeclarativeSymbol(backend),
m_metaInfo(metaInfo)
{
Q_ASSERT(metaInfo.isValid());
m_name = m_metaInfo.typeName();
const int slashIdx = m_name.indexOf('/');
if (slashIdx != -1)
m_name = m_name.mid(slashIdx + 1);
}
virtual ~QmlDeclarativeObjectSymbol()
{ qDeleteAll(m_members); }
virtual const QString name() const