aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorThomas Hartmann <[email protected]>2010-10-19 16:15:32 +0200
committerChristian Kamm <[email protected]>2010-11-11 11:49:10 +0100
commit4255220c35414dee49ab1c1c48bb96d44e4a241a (patch)
tree99f3c319b70fceb2317bf7fca0a2c31cb22237a4 /src/libs
parent87afbf39338de40b81878fa890c311433ce2bf41 (diff)
QmlJS: Fixing type hierarchy for holes (non exported types)
Done-with: Christian Kamm
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp92
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h13
2 files changed, 80 insertions, 25 deletions
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index b1fa28a28d6..7ecb6e076b0 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -755,12 +755,14 @@ private:
} // end of anonymous namespace
-QmlObjectValue::QmlObjectValue(const FakeMetaObject *metaObject, int exportIndex, Engine *engine)
+QmlObjectValue::QmlObjectValue(const FakeMetaObject *metaObject, const QString &className,
+ const QString &packageName, const QmlJS::ComponentVersion version, Engine *engine)
: ObjectValue(engine),
_metaObject(metaObject),
- _exportIndex(exportIndex)
+ _packageName(packageName),
+ _componentVersion(version)
{
- setClassName(metaObject->exports().at(exportIndex).type); // ### TODO: we probably need to do more than just this...
+ setClassName(className);
}
QmlObjectValue::~QmlObjectValue()
@@ -877,10 +879,10 @@ const Value *QmlObjectValue::propertyValue(const FakeMetaProperty &prop) const
}
QString QmlObjectValue::packageName() const
-{ return _metaObject->exports().at(_exportIndex).package; }
+{ return _packageName; }
QmlJS::ComponentVersion QmlObjectValue::version() const
-{ return _metaObject->exports().at(_exportIndex).version; }
+{ return _componentVersion; }
QString QmlObjectValue::defaultPropertyName() const
{ return _metaObject->defaultPropertyName(); }
@@ -2031,35 +2033,34 @@ void CppQmlTypes::load(Engine *engine, const QList<const FakeMetaObject *> &obje
if (_typesByFullyQualifiedName.contains(exp.packageNameVersion))
continue;
- QmlObjectValue *objectValue = new QmlObjectValue(metaObject, i, engine);
+ QmlObjectValue *objectValue = new QmlObjectValue(
+ metaObject, exp.type, exp.package, exp.version, engine);
_typesByPackage[exp.package].append(objectValue);
_typesByFullyQualifiedName[exp.packageNameVersion] = objectValue;
}
}
- // set prototype correctly
+ // set prototypes
foreach (const FakeMetaObject *metaObject, objects) {
foreach (const FakeMetaObject::Export &exp, metaObject->exports()) {
QmlObjectValue *objectValue = _typesByFullyQualifiedName.value(exp.packageNameVersion);
if (!objectValue || !metaObject->superClass())
continue;
- bool found = false;
- // try to get a prototype from the library first
- foreach (const FakeMetaObject::Export &superExports, metaObject->superClass()->exports()) {
- if (superExports.package == exp.package) {
- objectValue->setPrototype(_typesByFullyQualifiedName.value(superExports.packageNameVersion));
- found = true;
- break;
- }
- }
- if (found)
- continue;
- // otherwise, just use the first available
- if (!metaObject->superClass()->exports().isEmpty()) {
- objectValue->setPrototype(_typesByFullyQualifiedName.value(metaObject->superClass()->exports().first().packageNameVersion));
- continue;
+
+ // set prototypes for whole chain, creating new QmlObjectValues if necessary
+ // for instance, if an type isn't exported in the package of the super type
+ // Example: QObject (Qt, QtQuick) -> Positioner (not exported) -> Column (Qt, QtQuick)
+ // needs to create Positioner (Qt) and Positioner (QtQuick)
+ bool created = true;
+ QmlObjectValue *v = objectValue;
+ const FakeMetaObject *fmo = metaObject;
+ while (created && fmo->superClass()) {
+ QmlObjectValue *superValue = getOrCreate(exp.package, fmo->superclassName(),
+ fmo->superClass(), engine, &created);
+ v->setPrototype(superValue);
+ v = superValue;
+ fmo = fmo->superClass();
}
- //qWarning() << "Could not find super class for " << exp.packageNameVersion;
}
}
}
@@ -2123,6 +2124,51 @@ bool CppQmlTypes::hasPackage(const QString &package) const
return _typesByPackage.contains(package);
}
+QString CppQmlTypes::qualifiedName(const QString &package, const QString &type, QmlJS::ComponentVersion version)
+{
+ return QString("%1.%2 %3.%4").arg(
+ package, type,
+ QString::number(version.majorVersion()),
+ QString::number(version.minorVersion()));
+}
+
+QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &name) const
+{
+ return _typesByFullyQualifiedName.value(name);
+}
+
+QmlObjectValue *CppQmlTypes::typeByQualifiedName(const QString &package, const QString &type, QmlJS::ComponentVersion version) const
+{
+ return typeByQualifiedName(qualifiedName(package, type, version));
+}
+
+QmlObjectValue *CppQmlTypes::getOrCreate(const QString &package, const QString &cppName,
+ const FakeMetaObject *metaObject, Engine *engine, bool *created)
+{
+ QString typeName = cppName;
+ ComponentVersion version;
+ foreach (const FakeMetaObject::Export &exp, metaObject->exports()) {
+ if (exp.package == package) {
+ typeName = exp.type;
+ version = exp.version;
+ break;
+ }
+ }
+
+ const QString qName = qualifiedName(package, typeName, version);
+ QmlObjectValue *value = typeByQualifiedName(qName);
+ if (!value) {
+ *created = true;
+ value = new QmlObjectValue(
+ metaObject, typeName, package, QmlJS::ComponentVersion(), engine);
+ _typesByFullyQualifiedName[qName] = value;
+ } else {
+ *created = false;
+ }
+
+ return value;
+}
+
ConvertToNumber::ConvertToNumber(Engine *engine)
: _engine(engine), _result(0)
{
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 8288d7871c4..586e8a81629 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -383,7 +383,8 @@ private:
class QMLJS_EXPORT QmlObjectValue: public ObjectValue
{
public:
- QmlObjectValue(const FakeMetaObject *metaObject, int exportIndex, Engine *engine);
+ QmlObjectValue(const FakeMetaObject *metaObject, const QString &className,
+ const QString &packageName, const ComponentVersion version, Engine *engine);
virtual ~QmlObjectValue();
virtual void processMembers(MemberProcessor *processor) const;
@@ -404,7 +405,8 @@ protected:
private:
const FakeMetaObject *_metaObject;
- const int _exportIndex;
+ const QString _packageName;
+ const ComponentVersion _componentVersion;
mutable QHash<int, const Value *> _metaSignature;
};
@@ -534,7 +536,14 @@ public:
QHash<QString, QmlObjectValue *> types() const
{ return _typesByFullyQualifiedName; }
+ static QString qualifiedName(const QString &package, const QString &type, ComponentVersion version);
+ QmlObjectValue *typeByQualifiedName(const QString &name) const;
+ QmlObjectValue *typeByQualifiedName(const QString &package, const QString &type, ComponentVersion version) const;
+
private:
+ QmlObjectValue *getOrCreate(const QString &package, const QString &cppName, const FakeMetaObject *metaObject, Engine *engine, bool *created);
+
+
QHash<QString, QList<QmlObjectValue *> > _typesByPackage;
QHash<QString, QmlObjectValue *> _typesByFullyQualifiedName;
};