aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/language/evaluatorscriptclass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/corelib/language/evaluatorscriptclass.cpp')
-rw-r--r--src/lib/corelib/language/evaluatorscriptclass.cpp776
1 files changed, 0 insertions, 776 deletions
diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp
deleted file mode 100644
index 375954133..000000000
--- a/src/lib/corelib/language/evaluatorscriptclass.cpp
+++ /dev/null
@@ -1,776 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qbs.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "evaluatorscriptclass.h"
-
-#include "evaluationdata.h"
-#include "evaluator.h"
-#include "filecontext.h"
-#include "item.h"
-#include "scriptengine.h"
-#include "propertydeclaration.h"
-#include "value.h"
-#include <logging/translator.h>
-#include <tools/fileinfo.h>
-#include <tools/qbsassert.h>
-#include <tools/qttools.h>
-#include <tools/scripttools.h>
-#include <tools/stringconstants.h>
-
-#include <QtCore/qbytearray.h>
-#include <QtCore/qdebug.h>
-#include <QtCore/qsettings.h>
-
-#include <QtScript/qscriptclasspropertyiterator.h>
-#include <QtScript/qscriptstring.h>
-#include <QtScript/qscriptvalue.h>
-
-#include <utility>
-
-namespace qbs {
-namespace Internal {
-
-class SVConverter : ValueHandler
-{
- EvaluatorScriptClass * const scriptClass;
- ScriptEngine * const engine;
- QScriptContext * const scriptContext;
- const QScriptValue * const object;
- Value * const valuePtr;
- const Item * const itemOfProperty;
- const QScriptString * const propertyName;
- const EvaluationData * const data;
- QScriptValue * const result;
- char pushedScopesCount;
-
-public:
-
- SVConverter(EvaluatorScriptClass *esc, const QScriptValue *obj, const ValuePtr &v,
- const Item *_itemOfProperty, const QScriptString *propertyName, const EvaluationData *data,
- QScriptValue *result)
- : scriptClass(esc)
- , engine(static_cast<ScriptEngine *>(esc->engine()))
- , scriptContext(esc->engine()->currentContext())
- , object(obj)
- , valuePtr(v.get())
- , itemOfProperty(_itemOfProperty)
- , propertyName(propertyName)
- , data(data)
- , result(result)
- , pushedScopesCount(0)
- {
- }
-
- void start()
- {
- valuePtr->apply(this);
- }
-
-private:
- friend class AutoScopePopper;
-
- class AutoScopePopper
- {
- public:
- AutoScopePopper(SVConverter *converter)
- : m_converter(converter)
- {
- }
-
- ~AutoScopePopper()
- {
- m_converter->popScopes();
- }
-
- private:
- SVConverter *m_converter;
- };
-
- void setupConvenienceProperty(const QString &conveniencePropertyName, QScriptValue *extraScope,
- const QScriptValue &scriptValue)
- {
- if (!extraScope->isObject())
- *extraScope = engine->newObject();
- const PropertyDeclaration::Type type
- = itemOfProperty->propertyDeclaration(propertyName->toString()).type();
- const bool isArray = type == PropertyDeclaration::StringList
- || type == PropertyDeclaration::PathList
- || type == PropertyDeclaration::Variant // TODO: Why?
- || type == PropertyDeclaration::VariantList;
- QScriptValue valueToSet = scriptValue;
- if (isArray) {
- if (!valueToSet.isValid() || valueToSet.isUndefined())
- valueToSet = engine->newArray();
- } else if (!valueToSet.isValid()) {
- valueToSet = engine->undefinedValue();
- }
- extraScope->setProperty(conveniencePropertyName, valueToSet);
- }
-
- std::pair<QScriptValue, bool> createExtraScope(const JSSourceValue *value, Item *outerItem,
- QScriptValue *outerScriptValue)
- {
- std::pair<QScriptValue, bool> result;
- auto &extraScope = result.first;
- result.second = true;
- if (value->sourceUsesBase()) {
- QScriptValue baseValue;
- if (value->baseValue()) {
- SVConverter converter(scriptClass, object, value->baseValue(), itemOfProperty,
- propertyName, data, &baseValue);
- converter.start();
- }
- setupConvenienceProperty(StringConstants::baseVar(), &extraScope, baseValue);
- }
- if (value->sourceUsesOuter()) {
- QScriptValue v;
- if (outerItem) {
- v = data->evaluator->property(outerItem, *propertyName);
- if (engine->hasErrorOrException(v)) {
- extraScope = engine->lastErrorValue(v);
- result.second = false;
- return result;
- }
- } else if (outerScriptValue) {
- v = *outerScriptValue;
- }
- if (v.isValid())
- setupConvenienceProperty(StringConstants::outerVar(), &extraScope, v);
- }
- if (value->sourceUsesOriginal()) {
- QScriptValue originalValue;
- if (data->item->propertyDeclaration(propertyName->toString()).isScalar()) {
- const Item *item = itemOfProperty;
- if (item->type() == ItemType::Module || item->type() == ItemType::Export) {
- const QString errorMessage = Tr::tr("The special value 'original' cannot "
- "be used on the right-hand side of a property declaration.");
- extraScope = engine->currentContext()->throwError(errorMessage);
- result.second = false;
- return result;
- }
-
- // TODO: Provide a dedicated item type for not-yet-instantiated things that
- // look like module instances in the AST visitor.
- if (item->type() == ItemType::ModuleInstance
- && !item->hasProperty(StringConstants::presentProperty())) {
- const QString errorMessage = Tr::tr("Trying to assign property '%1' "
- "on something that is not a module.").arg(propertyName->toString());
- extraScope = engine->currentContext()->throwError(errorMessage);
- result.second = false;
- return result;
- }
-
- while (item->type() == ItemType::ModuleInstance)
- item = item->prototype();
- if (item->type() != ItemType::Module && item->type() != ItemType::Export) {
- const QString errorMessage = Tr::tr("The special value 'original' can only "
- "be used with module properties.");
- extraScope = engine->currentContext()->throwError(errorMessage);
- result.second = false;
- return result;
- }
- const ValuePtr v = item->property(*propertyName);
-
- // This can happen when resolving shadow products. The error will be ignored
- // in that case.
- if (!v) {
- const QString errorMessage = Tr::tr("Error setting up 'original'.");
- extraScope = engine->currentContext()->throwError(errorMessage);
- result.second = false;
- return result;
- }
-
- SVConverter converter(scriptClass, object, v, item,
- propertyName, data, &originalValue);
- converter.start();
- } else {
- originalValue = engine->newArray(0);
- }
- setupConvenienceProperty(StringConstants::originalVar(), &extraScope, originalValue);
- }
- return result;
- }
-
- void pushScope(const QScriptValue &scope)
- {
- if (scope.isObject()) {
- scriptContext->pushScope(scope);
- ++pushedScopesCount;
- }
- }
-
- void pushItemScopes(const Item *item)
- {
- const Item *scope = item->scope();
- if (scope) {
- pushItemScopes(scope);
- pushScope(data->evaluator->scriptValue(scope));
- }
- }
-
- void popScopes()
- {
- for (; pushedScopesCount; --pushedScopesCount)
- scriptContext->popScope();
- }
-
- void handle(JSSourceValue *value) override
- {
- QScriptValue outerScriptValue;
- for (const JSSourceValue::Alternative &alternative : value->alternatives()) {
- if (alternative.value->sourceUsesOuter()
- && !data->item->outerItem()
- && !outerScriptValue.isValid()) {
- JSSourceValueEvaluationResult sver = evaluateJSSourceValue(value, nullptr);
- if (sver.hasError) {
- *result = sver.scriptValue;
- return;
- }
- outerScriptValue = sver.scriptValue;
- }
- JSSourceValueEvaluationResult sver = evaluateJSSourceValue(alternative.value.get(),
- data->item->outerItem(),
- &alternative,
- value, &outerScriptValue);
- if (!sver.tryNextAlternative || sver.hasError) {
- *result = sver.scriptValue;
- return;
- }
- }
- *result = evaluateJSSourceValue(value, data->item->outerItem()).scriptValue;
- }
-
- struct JSSourceValueEvaluationResult
- {
- QScriptValue scriptValue;
- bool tryNextAlternative = true;
- bool hasError = false;
- };
-
- void injectErrorLocation(QScriptValue &sv, const CodeLocation &loc)
- {
- if (sv.isError() && !engine->lastErrorLocation(sv).isValid())
- sv = engine->currentContext()->throwError(engine->lastError(sv, loc).toString());
- }
-
- JSSourceValueEvaluationResult evaluateJSSourceValue(const JSSourceValue *value, Item *outerItem,
- const JSSourceValue::Alternative *alternative = nullptr,
- JSSourceValue *elseCaseValue = nullptr, QScriptValue *outerScriptValue = nullptr)
- {
- JSSourceValueEvaluationResult result;
- QBS_ASSERT(!alternative || value == alternative->value.get(), return result);
- AutoScopePopper autoScopePopper(this);
- auto maybeExtraScope = createExtraScope(value, outerItem, outerScriptValue);
- if (!maybeExtraScope.second) {
- result.scriptValue = maybeExtraScope.first;
- result.hasError = true;
- return result;
- }
- const Evaluator::FileContextScopes fileCtxScopes
- = data->evaluator->fileContextScopes(value->file());
- if (fileCtxScopes.importScope.isError()) {
- result.scriptValue = fileCtxScopes.importScope;
- result.hasError = true;
- return result;
- }
- pushScope(fileCtxScopes.fileScope);
- pushItemScopes(data->item);
- if (itemOfProperty->type() != ItemType::ModuleInstance) {
- // Own properties of module instances must not have the instance itself in the scope.
- pushScope(*object);
- }
- if (value->definingItem())
- pushItemScopes(value->definingItem());
- pushScope(maybeExtraScope.first);
- pushScope(fileCtxScopes.importScope);
- if (alternative) {
- QScriptValue sv = engine->evaluate(alternative->condition.value);
- if (engine->hasErrorOrException(sv)) {
- result.scriptValue = sv;
- result.hasError = true;
- injectErrorLocation(result.scriptValue, alternative->condition.location);
- return result;
- }
- if (sv.toBool()) {
- // The condition is true. Continue evaluating the value.
- result.tryNextAlternative = false;
- } else {
- // The condition is false. Try the next alternative or the else value.
- result.tryNextAlternative = true;
- return result;
- }
- sv = engine->evaluate(alternative->overrideListProperties.value);
- if (engine->hasErrorOrException(sv)) {
- result.scriptValue = sv;
- result.hasError = true;
- injectErrorLocation(result.scriptValue,
- alternative->overrideListProperties.location);
- return result;
- }
- if (sv.toBool())
- elseCaseValue->setIsExclusiveListValue();
- }
- result.scriptValue = engine->evaluate(value->sourceCodeForEvaluation(),
- value->file()->filePath(), value->line());
- return result;
- }
-
- void handle(ItemValue *value) override
- {
- *result = data->evaluator->scriptValue(value->item());
- if (!result->isValid())
- qDebug() << "SVConverter returned invalid script value.";
- }
-
- void handle(VariantValue *variantValue) override
- {
- *result = engine->toScriptValue(variantValue->value());
- }
-};
-
-bool debugProperties = false;
-
-enum QueryPropertyType
-{
- QPTDefault,
- QPTParentProperty
-};
-
-EvaluatorScriptClass::EvaluatorScriptClass(ScriptEngine *scriptEngine)
- : QScriptClass(scriptEngine)
- , m_valueCacheEnabled(false)
-{
-}
-
-QScriptClass::QueryFlags EvaluatorScriptClass::queryProperty(const QScriptValue &object,
- const QScriptString &name,
- QScriptClass::QueryFlags flags,
- uint *id)
-{
- Q_UNUSED(flags);
-
- // We assume that it's safe to save the result of the query in a member of the scriptclass.
- // It must be cleared in the property method before doing any further lookup.
- QBS_ASSERT(m_queryResult.isNull(), return {});
-
- if (debugProperties)
- qDebug() << "[SC] queryProperty " << object.objectId() << " " << name;
-
- auto const data = attachedPointer<EvaluationData>(object);
- const QString nameString = name.toString();
- if (nameString == QStringLiteral("parent")) {
- *id = QPTParentProperty;
- m_queryResult.data = data;
- return QScriptClass::HandlesReadAccess;
- }
-
- *id = QPTDefault;
- if (!data) {
- if (debugProperties)
- qDebug() << "[SC] queryProperty: no data attached";
- return {};
- }
-
- return queryItemProperty(data, nameString);
-}
-
-QScriptClass::QueryFlags EvaluatorScriptClass::queryItemProperty(const EvaluationData *data,
- const QString &name,
- bool ignoreParent)
-{
- for (const Item *item = data->item; item; item = item->prototype()) {
- m_queryResult.value = item->ownProperty(name);
- if (m_queryResult.value) {
- m_queryResult.data = data;
- m_queryResult.itemOfProperty = item;
- return HandlesReadAccess;
- }
- }
-
- if (!ignoreParent && data->item && data->item->parent()) {
- if (debugProperties)
- qDebug() << "[SC] queryProperty: query parent";
- EvaluationData parentdata = *data;
- parentdata.item = data->item->parent();
- const QueryFlags qf = queryItemProperty(&parentdata, name, true);
- if (qf.testFlag(HandlesReadAccess)) {
- m_queryResult.foundInParent = true;
- m_queryResult.data = data;
- return qf;
- }
- }
-
- if (debugProperties)
- qDebug() << "[SC] queryProperty: no such property";
- return {};
-}
-
-QString EvaluatorScriptClass::resultToString(const QScriptValue &scriptValue)
-{
- return (scriptValue.isObject()
- ? QStringLiteral("[Object: ")
- + QString::number(scriptValue.objectId()) + QLatin1Char(']')
- : scriptValue.toVariant().toString());
-}
-
-void EvaluatorScriptClass::collectValuesFromNextChain(const EvaluationData *data, QScriptValue *result,
- const QString &propertyName, const ValuePtr &value)
-{
- QScriptValueList lst;
- Set<Value *> oldNextChain = m_currentNextChain;
- for (ValuePtr next = value; next; next = next->next())
- m_currentNextChain.insert(next.get());
-
- for (ValuePtr next = value; next; next = next->next()) {
- QScriptValue v = data->evaluator->property(next->definingItem(), propertyName);
- const auto se = static_cast<const ScriptEngine *>(engine());
- if (se->hasErrorOrException(v)) {
- *result = se->lastErrorValue(v);
- return;
- }
- if (v.isUndefined())
- continue;
- lst << v;
- if (next->type() == Value::JSSourceValueType
- && std::static_pointer_cast<JSSourceValue>(next)->isExclusiveListValue()) {
- lst = lst.mid(lst.length() - 2);
- break;
- }
- }
- m_currentNextChain = oldNextChain;
-
- *result = engine()->newArray();
- quint32 k = 0;
- for (const QScriptValue &v : qAsConst(lst)) {
- QBS_ASSERT(!v.isError(), continue);
- if (v.isArray()) {
- const quint32 vlen = v.property(StringConstants::lengthProperty()).toInt32();
- for (quint32 j = 0; j < vlen; ++j)
- result->setProperty(k++, v.property(j));
- } else {
- result->setProperty(k++, v);
- }
- }
-}
-
-static QString overriddenSourceDirectory(const Item *item, const QString &defaultValue)
-{
- const VariantValuePtr v = item->variantProperty
- (StringConstants::qbsSourceDirPropertyInternal());
- return v ? v->value().toString() : defaultValue;
-}
-
-static void makeTypeError(const ErrorInfo &error, QScriptValue &v)
-{
- v = v.engine()->currentContext()->throwError(QScriptContext::TypeError,
- error.toString());
-}
-
-static void makeTypeError(const PropertyDeclaration &decl, const CodeLocation &location,
- QScriptValue &v)
-{
- const ErrorInfo error(Tr::tr("Value assigned to property '%1' does not have type '%2'.")
- .arg(decl.name(), decl.typeString()), location);
- makeTypeError(error, v);
-}
-
-static void convertToPropertyType_impl(const QString &pathPropertiesBaseDir, const Item *item,
- const PropertyDeclaration& decl,
- const CodeLocation &location, QScriptValue &v)
-{
- if (v.isUndefined() || v.isError())
- return;
- QString srcDir;
- QString actualBaseDir;
- if (item && !pathPropertiesBaseDir.isEmpty()) {
- const VariantValueConstPtr itemSourceDir
- = item->variantProperty(QStringLiteral("sourceDirectory"));
- actualBaseDir = itemSourceDir ? itemSourceDir->value().toString() : pathPropertiesBaseDir;
- }
- switch (decl.type()) {
- case PropertyDeclaration::UnknownType:
- case PropertyDeclaration::Variant:
- break;
- case PropertyDeclaration::Boolean:
- if (!v.isBool())
- v = v.toBool();
- break;
- case PropertyDeclaration::Integer:
- if (!v.isNumber())
- makeTypeError(decl, location, v);
- break;
- case PropertyDeclaration::Path:
- {
- if (!v.isString()) {
- makeTypeError(decl, location, v);
- break;
- }
- const QString srcDir = item ? overriddenSourceDirectory(item, actualBaseDir)
- : pathPropertiesBaseDir;
- if (!srcDir.isEmpty())
- v = v.engine()->toScriptValue(QDir::cleanPath(
- FileInfo::resolvePath(srcDir, v.toString())));
- break;
- }
- case PropertyDeclaration::String:
- if (!v.isString())
- makeTypeError(decl, location, v);
- break;
- case PropertyDeclaration::PathList:
- srcDir = item ? overriddenSourceDirectory(item, actualBaseDir)
- : pathPropertiesBaseDir;
- // Fall-through.
- case PropertyDeclaration::StringList:
- {
- if (!v.isArray()) {
- QScriptValue x = v.engine()->newArray(1);
- x.setProperty(0, v);
- v = x;
- }
- const quint32 c = v.property(StringConstants::lengthProperty()).toUInt32();
- for (quint32 i = 0; i < c; ++i) {
- QScriptValue elem = v.property(i);
- if (elem.isUndefined()) {
- ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is undefined. "
- "String expected.").arg(i).arg(decl.name()), location);
- makeTypeError(error, v);
- break;
- }
- if (elem.isNull()) {
- ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' is null. "
- "String expected.").arg(i).arg(decl.name()), location);
- makeTypeError(error, v);
- break;
- }
- if (!elem.isString()) {
- ErrorInfo error(Tr::tr("Element at index %1 of list property '%2' does not have "
- "string type.").arg(i).arg(decl.name()), location);
- makeTypeError(error, v);
- break;
- }
- if (srcDir.isEmpty())
- continue;
- elem = v.engine()->toScriptValue(
- QDir::cleanPath(FileInfo::resolvePath(srcDir, elem.toString())));
- v.setProperty(i, elem);
- }
- break;
- }
- case PropertyDeclaration::VariantList:
- if (!v.isArray()) {
- QScriptValue x = v.engine()->newArray(1);
- x.setProperty(0, v);
- v = x;
- }
- break;
- }
-}
-
-void EvaluatorScriptClass::convertToPropertyType(const PropertyDeclaration &decl,
- const CodeLocation &loc, QScriptValue &v)
-{
- convertToPropertyType_impl(QString(), nullptr, decl, loc, v);
-}
-
-void EvaluatorScriptClass::convertToPropertyType(const Item *item, const PropertyDeclaration& decl,
- const Value *value, QScriptValue &v)
-{
- if (value->type() == Value::VariantValueType && v.isUndefined() && !decl.isScalar()) {
- v = v.engine()->newArray(); // QTBUG-51237
- return;
- }
- convertToPropertyType_impl(m_pathPropertiesBaseDir, item, decl, value->location(), v);
-}
-
-class PropertyStackManager
-{
-public:
- PropertyStackManager(const Item *itemOfProperty, const QScriptString &name, const Value *value,
- std::stack<QualifiedId> &requestedProperties,
- PropertyDependencies &propertyDependencies)
- : m_requestedProperties(requestedProperties)
- {
- if (value->type() == Value::JSSourceValueType
- && (itemOfProperty->type() == ItemType::ModuleInstance
- || itemOfProperty->type() == ItemType::Module
- || itemOfProperty->type() == ItemType::Export)) {
- const VariantValueConstPtr varValue
- = itemOfProperty->variantProperty(StringConstants::nameProperty());
- if (!varValue)
- return;
- m_stackUpdate = true;
- const QualifiedId fullPropName
- = QualifiedId::fromString(varValue->value().toString()) << name.toString();
- if (!requestedProperties.empty())
- propertyDependencies[fullPropName].insert(requestedProperties.top());
- m_requestedProperties.push(fullPropName);
- }
- }
-
- ~PropertyStackManager()
- {
- if (m_stackUpdate)
- m_requestedProperties.pop();
- }
-
-private:
- std::stack<QualifiedId> &m_requestedProperties;
- bool m_stackUpdate = false;
-};
-
-QScriptValue EvaluatorScriptClass::property(const QScriptValue &object, const QScriptString &name,
- uint id)
-{
- const bool foundInParent = m_queryResult.foundInParent;
- const EvaluationData *data = m_queryResult.data;
- const Item * const itemOfProperty = m_queryResult.itemOfProperty;
- m_queryResult.foundInParent = false;
- m_queryResult.data = nullptr;
- m_queryResult.itemOfProperty = nullptr;
- QBS_ASSERT(data, {});
-
- const auto qpt = static_cast<QueryPropertyType>(id);
- if (qpt == QPTParentProperty) {
- return data->item->parent()
- ? data->evaluator->scriptValue(data->item->parent())
- : engine()->undefinedValue();
- }
-
- ValuePtr value;
- m_queryResult.value.swap(value);
- QBS_ASSERT(value, return {});
- QBS_ASSERT(m_queryResult.isNull(), return {});
-
- if (debugProperties)
- qDebug() << "[SC] property " << name;
-
- PropertyStackManager propStackmanager(itemOfProperty, name, value.get(),
- m_requestedProperties, m_propertyDependencies);
-
- QScriptValue result;
- if (m_valueCacheEnabled) {
- result = data->valueCache.value(name);
- if (result.isValid()) {
- if (debugProperties)
- qDebug() << "[SC] cache hit " << name << ": " << resultToString(result);
- return result;
- }
- }
-
- if (value->next() && !m_currentNextChain.contains(value.get())) {
- collectValuesFromNextChain(data, &result, name.toString(), value);
- } else {
- QScriptValue parentObject;
- if (foundInParent)
- parentObject = data->evaluator->scriptValue(data->item->parent());
- SVConverter converter(this, foundInParent ? &parentObject : &object, value, itemOfProperty,
- &name, data, &result);
- converter.start();
-
- const PropertyDeclaration decl = data->item->propertyDeclaration(name.toString());
- convertToPropertyType(data->item, decl, value.get(), result);
- }
-
- if (debugProperties)
- qDebug() << "[SC] cache miss " << name << ": " << resultToString(result);
- if (m_valueCacheEnabled)
- data->valueCache.insert(name, result);
- return result;
-}
-
-class EvaluatorScriptClassPropertyIterator : public QScriptClassPropertyIterator
-{
-public:
- EvaluatorScriptClassPropertyIterator(const QScriptValue &object, EvaluationData *data)
- : QScriptClassPropertyIterator(object), m_it(data->item->properties())
- {
- }
-
- bool hasNext() const override
- {
- return m_it.hasNext();
- }
-
- void next() override
- {
- m_it.next();
- }
-
- bool hasPrevious() const override
- {
- return m_it.hasPrevious();
- }
-
- void previous() override
- {
- m_it.previous();
- }
-
- void toFront() override
- {
- m_it.toFront();
- }
-
- void toBack() override
- {
- m_it.toBack();
- }
-
- QScriptString name() const override
- {
- return object().engine()->toStringHandle(m_it.key());
- }
-
-private:
- QMapIterator<QString, ValuePtr> m_it;
-};
-
-QScriptClassPropertyIterator *EvaluatorScriptClass::newIterator(const QScriptValue &object)
-{
- auto const data = attachedPointer<EvaluationData>(object);
- return data ? new EvaluatorScriptClassPropertyIterator(object, data) : nullptr;
-}
-
-void EvaluatorScriptClass::setValueCacheEnabled(bool enabled)
-{
- m_valueCacheEnabled = enabled;
-}
-
-} // namespace Internal
-} // namespace qbs