Commit 1d4cd9b7 authored by Christian Kamm's avatar Christian Kamm

QmlJS: Remove the strict separation of types and attached types.

The problem was that several lookup calls suddenly failed because
the actual QML types were no longer in the default scope chain. However,
the QML documentation says the type names are in the scope.

Also, 'MyComponent.' in a JS-expression context only showed the attached
properties of MyComponent and missed the enums.

With this change completion now may offers too many options, but that's
better than missing some.

This reverts parts of 490f2797

Reviewed-by: Leandro Melo
parent 9232b3d5
......@@ -826,7 +826,7 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
bool isAttachedProperty = false;
if (! propertyName.isEmpty() && propertyName[0].isUpper()) {
isAttachedProperty = true;
if (const ObjectValue *qmlTypes = _context.scopeChain().qmlAttachedTypes)
if (const ObjectValue *qmlTypes = _context.scopeChain().qmlTypes)
scopeObjects += qmlTypes;
}
......
......@@ -651,6 +651,9 @@ void QmlObjectValue::processMembers(MemberProcessor *processor) const
}
}
if (_attachedType)
_attachedType->processMembers(processor);
ObjectValue::processMembers(processor);
}
......@@ -1305,7 +1308,6 @@ void StringValue::accept(ValueVisitor *visitor) const
ScopeChain::ScopeChain()
: globalScope(0)
, qmlTypes(0)
, qmlAttachedTypes(0)
{
}
......@@ -1365,8 +1367,8 @@ void ScopeChain::update()
_all += qmlScopeObjects;
if (ids)
_all += ids;
if (qmlAttachedTypes)
_all += qmlAttachedTypes;
if (qmlTypes)
_all += qmlTypes;
// qmlTypes are not added on purpose
_all += jsScopes;
}
......@@ -3425,66 +3427,3 @@ ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *conte
}
return ImportInfo();
}
namespace {
class AttachedTypeProcessor: public MemberProcessor
{
MemberProcessor *_wrapped;
public:
AttachedTypeProcessor(MemberProcessor *wrapped) : _wrapped(wrapped) {}
static const QmlObjectValue *attachedType(const Value *v)
{
if (const QmlObjectValue *qmlValue = dynamic_cast<const QmlObjectValue *>(v)) {
return qmlValue->attachedType();
}
return 0;
}
virtual bool processProperty(const QString &name, const Value *value)
{
const QmlObjectValue *qmlValue = attachedType(value);
return qmlValue ? _wrapped->processProperty(name, qmlValue) : true;
}
virtual bool processEnumerator(const QString &name, const Value *value)
{
const QmlObjectValue *qmlValue = attachedType(value);
return qmlValue ? _wrapped->processEnumerator(name, qmlValue) : true;
}
virtual bool processSignal(const QString &name, const Value *value)
{
const QmlObjectValue *qmlValue = attachedType(value);
return qmlValue ? _wrapped->processSignal(name, qmlValue) : true;
}
virtual bool processSlot(const QString &name, const Value *value)
{
const QmlObjectValue *qmlValue = attachedType(value);
return qmlValue ? _wrapped->processSlot(name, qmlValue) : true;
}
virtual bool processGeneratedSlot(const QString &name, const Value *value)
{
const QmlObjectValue *qmlValue = attachedType(value);
return qmlValue ? _wrapped->processGeneratedSlot(name, qmlValue) : true;
}
};
} // anonymous namespace
AttachedTypeEnvironment::AttachedTypeEnvironment(const TypeEnvironment *typeEnv)
: ObjectValue(typeEnv->engine())
, _typeEnvironment(typeEnv)
{
}
const Value *AttachedTypeEnvironment::lookupMember(const QString &name, const Context *context,
const ObjectValue **, bool) const
{
const Value *v = _typeEnvironment->lookupMember(name, context);
return AttachedTypeProcessor::attachedType(v);
}
void AttachedTypeEnvironment::processMembers(MemberProcessor *processor) const
{
AttachedTypeProcessor wrappedProcessor(processor);
_typeEnvironment->processMembers(&wrappedProcessor);
}
......@@ -305,7 +305,6 @@ public:
QSharedPointer<const QmlComponentChain> qmlComponentScope;
QList<const ObjectValue *> qmlScopeObjects;
const TypeEnvironment *qmlTypes;
const AttachedTypeEnvironment *qmlAttachedTypes;
QList<const ObjectValue *> jsScopes;
// rebuilds the flat list of all scopes
......@@ -1038,19 +1037,6 @@ public:
ImportInfo importInfo(const QString &name, const Context *context) const;
};
class QMLJS_EXPORT AttachedTypeEnvironment: public ObjectValue
{
const TypeEnvironment *_typeEnvironment;
public:
AttachedTypeEnvironment(const TypeEnvironment *typeEnv);
virtual const Value *lookupMember(const QString &name, const Context *context,
const ObjectValue **foundInObject = 0,
bool examinePrototypes = true) const;
virtual void processMembers(MemberProcessor *processor) const;
};
} } // namespace QmlJS::Interpreter
#endif // QMLJS_INTERPRETER_H
......@@ -131,7 +131,6 @@ void ScopeBuilder::initializeScopeChain()
if (const TypeEnvironment *typeEnvironment = _context->typeEnvironment(_doc.data())) {
scopeChain.qmlTypes = typeEnvironment;
scopeChain.qmlAttachedTypes = new AttachedTypeEnvironment(typeEnvironment);
}
} else {
// add scope chains for all components that import this file
......
......@@ -308,7 +308,7 @@ public:
bool isAttachedProperty = false;
if (! propertyName.isEmpty() && propertyName[0].isUpper()) {
isAttachedProperty = true;
if (const Interpreter::ObjectValue *qmlTypes = m_context->scopeChain().qmlAttachedTypes)
if (const Interpreter::ObjectValue *qmlTypes = m_context->scopeChain().qmlTypes)
scopeObjects += qmlTypes;
}
......
......@@ -178,7 +178,7 @@ protected:
const ScopeChain &chain = _context->scopeChain();
if (chain.jsScopes.contains(scope)
|| chain.qmlScopeObjects.contains(scope)
|| chain.qmlAttachedTypes == scope
|| chain.qmlTypes == scope
|| chain.globalScope == scope)
return false;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment