aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qmljs/qmljsdescribevalue.cpp
diff options
context:
space:
mode:
authorFawzi Mohamed <[email protected]>2014-05-21 16:14:29 +0200
committerFawzi Mohamed <[email protected]>2014-05-23 10:03:43 +0200
commit1d961d4ea4e8dc5584c1564314570f5cce3dbc6b (patch)
treee426a226f9443b809bd9a30226d17f4c081e1960 /src/libs/qmljs/qmljsdescribevalue.cpp
parent35128701cd5a051f49f233a25c94815e442d9ada (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.cpp404
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