forked from qt-creator/qt-creator
QmlJS: Avoid infinite loop with recursive prototypes.
This commit is contained in:
@@ -1055,11 +1055,13 @@ protected:
|
||||
{
|
||||
Bind *bind = m_lookupContext->document()->bind();
|
||||
const Interpreter::ObjectValue *objValue = bind->findQmlObject(ast);
|
||||
QStringList prototypes;
|
||||
if (!objValue)
|
||||
return false;
|
||||
|
||||
while (objValue) {
|
||||
prototypes.append(objValue->className());
|
||||
objValue = objValue->prototype(m_lookupContext->context());
|
||||
QStringList prototypes;
|
||||
foreach (const Interpreter::ObjectValue *value,
|
||||
Interpreter::PrototypeIterator(objValue, m_lookupContext->context()).all()) {
|
||||
prototypes.append(value->className());
|
||||
}
|
||||
|
||||
return prototypes.contains(QString("QGraphicsObject"));
|
||||
|
||||
@@ -71,12 +71,16 @@ static const ObjectValue *prototypeWithMember(const Context *context, const Obje
|
||||
const Value *value = object->property(name, context);
|
||||
if (!value)
|
||||
return 0;
|
||||
forever {
|
||||
const ObjectValue *prototype = object->prototype(context);
|
||||
if (!prototype || prototype->property(name, context) != value)
|
||||
return object;
|
||||
object = prototype;
|
||||
const ObjectValue *prev = object;
|
||||
PrototypeIterator iter(object, context);
|
||||
iter.next();
|
||||
while (iter.hasNext()) {
|
||||
const ObjectValue *prototype = iter.next();
|
||||
if (prototype->property(name, context) != value)
|
||||
return prev;
|
||||
prev = prototype;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -237,17 +237,19 @@ void HoverHandler::prettyPrintTooltip(const QmlJS::Interpreter::Value *value,
|
||||
|
||||
if (const Interpreter::ObjectValue *objectValue = value->asObjectValue()) {
|
||||
bool found = false;
|
||||
do {
|
||||
const QString className = objectValue->className();
|
||||
Interpreter::PrototypeIterator iter(objectValue, context);
|
||||
while (iter.hasNext()) {
|
||||
const Interpreter::ObjectValue *prototype = iter.next();
|
||||
const QString className = prototype->className();
|
||||
|
||||
if (! className.isEmpty()) {
|
||||
found = !qmlHelpId(className).isEmpty();
|
||||
if (toolTip().isEmpty() || found)
|
||||
setToolTip(className);
|
||||
}
|
||||
|
||||
objectValue = objectValue->prototype(context);
|
||||
} while (objectValue && !found);
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
} else if (const Interpreter::QmlEnumValue *enumValue =
|
||||
dynamic_cast<const Interpreter::QmlEnumValue *>(value)) {
|
||||
setToolTip(enumValue->name());
|
||||
|
||||
@@ -115,19 +115,21 @@ void QuickToolBar::apply(TextEditor::BaseTextEditorEditable *editor, Document::P
|
||||
|
||||
const Interpreter::ObjectValue *scopeObject = document->bind()->findQmlObject(node);
|
||||
|
||||
if (!lookupContext.isNull()) {
|
||||
if (!lookupContext.isNull() && scopeObject) {
|
||||
m_prototypes.clear();
|
||||
while (scopeObject) {
|
||||
m_prototypes.append(scopeObject->className());
|
||||
scopeObject = scopeObject->prototype(lookupContext->context());
|
||||
foreach (const Interpreter::ObjectValue *object,
|
||||
Interpreter::PrototypeIterator(scopeObject, lookupContext->context()).all()) {
|
||||
m_prototypes.append(object->className());
|
||||
}
|
||||
|
||||
if (m_prototypes.contains("PropertyChanges")) {
|
||||
const Interpreter::ObjectValue *targetObject = getPropertyChangesTarget(node, lookupContext);
|
||||
m_prototypes.clear();
|
||||
while (targetObject) {
|
||||
m_prototypes.append(targetObject->className());
|
||||
targetObject = targetObject->prototype(lookupContext->context());
|
||||
if (targetObject) {
|
||||
foreach (const Interpreter::ObjectValue *object,
|
||||
Interpreter::PrototypeIterator(targetObject, lookupContext->context()).all()) {
|
||||
m_prototypes.append(object->className());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user