diff options
author | Fawzi Mohamed <[email protected]> | 2014-05-21 16:14:29 +0200 |
---|---|---|
committer | Fawzi Mohamed <[email protected]> | 2014-05-23 10:03:43 +0200 |
commit | 1d961d4ea4e8dc5584c1564314570f5cce3dbc6b (patch) | |
tree | e426a226f9443b809bd9a30226d17f4c081e1960 /src/libs/qmljs/qmljsdescribevalue.cpp | |
parent | 35128701cd5a051f49f233a25c94815e442d9ada (diff) |
qmljs: adding dumper for value types
Change-Id: I3ae420ea29ed32b08f95f388b0ced5b5293219da
Reviewed-by: Thomas Hartmann <[email protected]>
Diffstat (limited to 'src/libs/qmljs/qmljsdescribevalue.cpp')
-rw-r--r-- | src/libs/qmljs/qmljsdescribevalue.cpp | 404 |
1 files changed, 404 insertions, 0 deletions
diff --git a/src/libs/qmljs/qmljsdescribevalue.cpp b/src/libs/qmljs/qmljsdescribevalue.cpp new file mode 100644 index 00000000000..90898212926 --- /dev/null +++ b/src/libs/qmljs/qmljsdescribevalue.cpp @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmljsdescribevalue.h" + +#include "qmljsinterpreter.h" +#include "parser/qmljsast_p.h" + +#include <QString> + +namespace QmlJS { + +QString DescribeValueVisitor::describe(const Value *value, int depth) +{ + DescribeValueVisitor describer(-depth); + return describer(value); +} + +DescribeValueVisitor::DescribeValueVisitor(int detailDepth, int startIndent, int indentIncrement) + : m_depth(-detailDepth), m_indent(startIndent), m_indentIncrement(indentIncrement) +{ } + +DescribeValueVisitor::~DescribeValueVisitor() +{ +} + +QString DescribeValueVisitor::operator()(const Value *value) +{ + if (value) + value->accept(this); + else + dump("**NULL**"); + return description(); +} + +void DescribeValueVisitor::basicDump(const char *baseName, const Value *value, bool opensContext) +{ + dump(QLatin1String(baseName)); + dump(QString::fromLatin1("@%1").arg((quintptr)(void *)value, 0, 16)); + QString fileName; + int line, column; + if (value && value->getSourceLocation(&fileName, &line, &column)) + dump(QString::fromLatin1(" - %1:%2:%3").arg(fileName) + .arg(line).arg(column)); + if (opensContext) + openContext(); +} + +void DescribeValueVisitor::dump(const QString &toAdd) +{ + m_description += toAdd; + m_emptyContext = false; +} + +void DescribeValueVisitor::dump(const char *toAdd) +{ + m_description += QLatin1String(toAdd); + m_emptyContext = false; +} + +void DescribeValueVisitor::dumpNewline() +{ + dump("\n"); + int indent = m_indent; + QString indentStr = QLatin1String(" "); + while (indent > 10) { + dump(indentStr); + indent -= 10; + } + if (indent > 0) + dump(indentStr.left(indent)); +} + +void DescribeValueVisitor::openContext(const char *openStr) +{ + dump(openStr); + m_indent += m_indentIncrement; + m_emptyContext = true; +} + +void DescribeValueVisitor::closeContext(const char *closeStr) +{ + m_indent -= m_indentIncrement; + if (m_emptyContext) { + dump(" "); + } else if (strlen(closeStr)) { + dumpNewline(); + } + dump(closeStr); +} + +void DescribeValueVisitor::visit(const NullValue *value) +{ + basicDump("NullValue", value, false); +} + +void DescribeValueVisitor::visit(const UndefinedValue *value) +{ + basicDump("UndefinedValue", value, false); +} + +void DescribeValueVisitor::visit(const UnknownValue *value) +{ + basicDump("UnknownValue", value, false); +} + +void DescribeValueVisitor::visit(const NumberValue *value) +{ + if (const QmlEnumValue *v = value->asQmlEnumValue()) { + basicDump("QmlEnumValue", v, true); + dumpNewline(); + dump(QString::fromLatin1("%2, ").arg((quintptr)(void *)v) + .arg(v->name())); + openContext("["); + foreach (const QString &key, v->keys()) { + dumpNewline(); + dump(key); + } + closeContext("]"); + dumpNewline(); + m_indent -= m_indentIncrement; + closeContext(); + } else if (const IntValue *v = value->asIntValue()) { + basicDump("IntValue", v, false); + } else if (const RealValue *v = value->asRealValue()) { + basicDump("RealValue", v, false); + } else { + basicDump("NumberValue", value, false); + } +} + +void DescribeValueVisitor::visit(const BooleanValue *value) +{ + basicDump("BooleanValue", value, false); +} + +void DescribeValueVisitor::visit(const StringValue *value) +{ + if (const UrlValue *v = value->asUrlValue()) + basicDump("UrlValue", v, false); + else + basicDump("StringValue", value, false); +} + +class PrintMembers : public MemberProcessor { +public: + DescribeValueVisitor &d; + PrintMembers(DescribeValueVisitor &describer) + : d(describer) { } + + bool dump(const QString &name, const Value *value) + { + d.dumpNewline(); + d.dump(name); + d.openContext(":"); + value->accept(&d); + d.closeContext(""); + return true; + } + + bool processProperty(const QString &name, const Value *value) QTC_OVERRIDE + { + return dump(name, value); + } + bool processEnumerator(const QString &name, const Value *value) QTC_OVERRIDE + { + return dump(name, value); + } + bool processSignal(const QString &name, const Value *value) QTC_OVERRIDE + { + return dump(name, value); + } + bool processSlot(const QString &name, const Value *value) QTC_OVERRIDE + { + return dump(name, value); + } + bool processGeneratedSlot(const QString &name, const Value *value) QTC_OVERRIDE + { + return dump(name, value); + } +}; + +void DescribeValueVisitor::visit(const ObjectValue *value) +{ + bool printDetail = (++m_depth <= 0 && ! m_visited.contains(value)); + m_visited.insert(value); + if (const ASTObjectValue *v = value->asAstObjectValue()) { + basicDump("ASTObjectValue", value, printDetail); + if (v->typeName()) { + dumpNewline(); + dump("typeName:"); + dump(v->typeName()->name.toString()); + } + dumpNewline(); + dump("defaultPropertyName:"); + dump(v->defaultPropertyName()); + } else if (const FunctionValue *f = value->asFunctionValue()) { + if (const ASTFunctionValue *v = f->asAstFunctionValue()) { + basicDump("ASTFunctionValue", v, printDetail); + if (printDetail && v->ast()) { + dumpNewline(); + dump("name:"); + dump(v->ast()->name.toString()); + } + } else if (const ASTSignal *v = f->asAstSignal()) { + basicDump("ASTSignal", v, printDetail); + if (printDetail) { + if (v->ast()) { + dumpNewline(); + dump("name:"); + dump(v->ast()->name.toString()); + } + dumpNewline(); + dump("slotName:"); + dump(v->slotName()); + } + } else if (f->asFunction()) { + basicDump("Function", f, printDetail); + } else if (f->asMetaFunction()) { + basicDump("MetaFunction", f, printDetail); + } else { + basicDump("FunctionValue", f, printDetail); + } + if (printDetail) { + dumpNewline(); + dump("returnValue:"); + (*this)(f->returnValue()); + dump("arguments:"); + openContext("["); + for (int i = 1; i < f->namedArgumentCount() - f->optionalNamedArgumentCount(); ++i) { + dumpNewline(); + (*this)(f->argument(i)); + dump(" "); + dump(f->argumentName(i)); + } + if (f->optionalNamedArgumentCount()) { + dumpNewline(); + dump("// optional arguments"); + dumpNewline(); + } + for (int i = f->namedArgumentCount() - f->optionalNamedArgumentCount(); + i < f->namedArgumentCount(); ++i) { + dumpNewline(); + (*this)(f->argument(i)); + dump(" "); + dump(f->argumentName(i)); + } + closeContext("]"); + dumpNewline(); + if (f->isVariadic()) + dump("isVariadic: true"); + } + } else if (const CppComponentValue *v = value->asCppComponentValue()) { + basicDump("CppComponentValue", value, printDetail); + if (printDetail) { + LanguageUtils::FakeMetaObject::ConstPtr metaObject = v->metaObject(); + dumpNewline(); + dump("metaObject:"); + if (metaObject.isNull()) + dump("**NULL**"); + else + metaObject->describe(true, m_indent + m_indentIncrement); + dumpNewline(); + dump("moduleName:"); + dump(v->moduleName()); + dumpNewline(); + dump("componentVersion:"); + dump(v->componentVersion().toString()); + dumpNewline(); + dump("importVersion:"); + dump(v->importVersion().toString()); + dumpNewline(); + dump("defaultPropertyName:"); + dump(v->defaultPropertyName()); + + /*QString propertyType(const QString &propertyName) const; + bool isListProperty(const QString &name) const; + bool isWritable(const QString &propertyName) const; + bool isPointer(const QString &propertyName) const; + bool hasLocalProperty(const QString &typeName) const; + bool hasProperty(const QString &typeName) const;*/ + + } + } else if (value->asJSImportScope()) { + basicDump("JSImportScope", value, printDetail); + } else if (value->asTypeScope()) { + basicDump("TypeScope", value, printDetail); + } else { + basicDump("ObjectValue", value, printDetail); + } + if (printDetail) { + if (value) { + dumpNewline(); + dump("className:"); + dump(value->className()); + dumpNewline(); + dump("members:"); + openContext("["); + PrintMembers printMembers(*this); + value->processMembers(&printMembers); + closeContext("]"); + dumpNewline(); + dump("prototype:"); + (*this)(value->prototype()); + } + closeContext(); + } + --m_depth; +} + +void DescribeValueVisitor::visit(const FunctionValue *f) +{ + const ObjectValue *o = f; + visit(o); +} + +void DescribeValueVisitor::visit(const Reference *value) +{ + bool printDetail = (++m_depth <= 0 && ! m_visited.contains(value)); + m_visited.insert(value); + if (const ASTPropertyReference *v = value->asAstPropertyReference()) { + basicDump("ASTPropertyReference", v, printDetail); + if (printDetail) { + if (AST::UiPublicMember *ast = v->ast()) { + dumpNewline(); + dump("property:"); + dump(ast->name.toString()); + } + dumpNewline(); + dump("onChangedSlotName:"); + dump(v->onChangedSlotName()); + } + } else if (const ASTVariableReference *v = value->asAstVariableReference()) { + basicDump("ASTVariableReference", v, printDetail); + const AST::VariableDeclaration *var = v->ast(); + if (printDetail && var) { + dumpNewline(); + dump("variable:"); + dump(var->name.toString()); + } + } else if (const QmlPrototypeReference *v = value->asQmlPrototypeReference()) { + basicDump("QmlPrototypeReference", v, printDetail); + const AST::UiQualifiedId *qmlTypeName = v->qmlTypeName(); + if (printDetail && qmlTypeName) { + dumpNewline(); + dump("qmlTypeName:"); + dump(qmlTypeName->name.toString()); + } + } else if (value->asQtObjectPrototypeReference()) { + basicDump("QtObjectPrototypeReference", value, printDetail); + } else { + basicDump("Reference", value, printDetail); + } + if (printDetail) { + ValueOwner *vOwner = value->valueOwner(); + dump(QLatin1String("\n valueOwner@")); + dump(QString::fromLatin1("@%1").arg((quintptr)(void *)vOwner, 0, 16)); + closeContext(); + } + --m_depth; +} + +void DescribeValueVisitor::visit(const ColorValue *value) +{ + basicDump("ColorValue", value, false); +} + +void DescribeValueVisitor::visit(const AnchorLineValue *value) +{ + basicDump("AnchorLineValue", value, false); +} + +QString DescribeValueVisitor::description() const +{ + return m_description; +} + +} // namespace QmlJS |