File: qmetaobjectvalidator.cpp

package info (click to toggle)
gammaray 3.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 21,612 kB
  • sloc: cpp: 94,643; ansic: 2,227; sh: 336; python: 164; yacc: 90; lex: 82; xml: 61; makefile: 26
file content (96 lines) | stat: -rw-r--r-- 3,162 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
  qmetaobjectvalidator.cpp

  This file is part of GammaRay, the Qt application inspection and manipulation tool.

  SPDX-FileCopyrightText: 2016 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
  Author: Volker Krause <volker.krause@kdab.com>

  SPDX-License-Identifier: GPL-2.0-or-later

  Contact KDAB at <info@kdab.com> for commercial licensing options.
*/

#include <config-gammaray.h>

#include "qmetaobjectvalidator.h"
#include "execution.h"
#include "metaobjectregistry.h"
#include "probe.h"
#include "problemcollector.h"

#include <QDebug>
#include <QMetaMethod>
#include <QMetaObject>
#include <QMetaProperty>

#include <private/qobject_p.h>
#include <private/qmetaobject_p.h>

using namespace GammaRay;

QMetaObjectValidatorResult::Results QMetaObjectValidator::checkProperty(const QMetaObject *mo, const QMetaProperty &property)
{
    QMetaObjectValidatorResult::Results r = QMetaObjectValidatorResult::NoIssue;

    // check if property overrides base-class declaration
    if (mo->superClass()) {
        const auto baseIdx = mo->superClass()->indexOfProperty(property.name());
        if (baseIdx >= 0)
            r |= QMetaObjectValidatorResult::PropertyOverride;
    }

    // check if property uses a known type
    if (property.userType() == QMetaType::UnknownType)
        r |= QMetaObjectValidatorResult::UnknownPropertyType;

    return r;
}

QMetaObjectValidatorResult::Results QMetaObjectValidator::checkMethod(const QMetaObject *mo, const QMetaMethod &method)
{
    QMetaObjectValidatorResult::Results r = QMetaObjectValidatorResult::NoIssue;

    // check for parameters with unknown type
    // don't check internal methods such as _q_createJSWrapper() from QQuickItem
    if (!method.name().startsWith("_q")) { // krazy:exclude=strings
        for (int j = 0; j < method.parameterCount(); ++j) {
            if (method.parameterType(j) == QMetaType::UnknownType)
                r |= QMetaObjectValidatorResult::UnknownMethodParameterType;
        }
    }

    // check for signal overrides
    if (method.methodType() == QMetaMethod::Signal && mo->superClass()) {
        const auto baseIdx = mo->superClass()->indexOfMethod(method.methodSignature());
        if (baseIdx >= 0)
            r |= QMetaObjectValidatorResult::SignalOverride;
    }

    return r;
}

static bool isDynamicMetaObject(const QMetaObject *mo)
{
    Q_ASSERT(reinterpret_cast<const QMetaObjectPrivate *>(mo->d.data)->revision >= 3);
    return reinterpret_cast<const QMetaObjectPrivate *>(mo->d.data)->flags & DynamicMetaObject;
}

QMetaObjectValidatorResult::Results QMetaObjectValidator::check(const QMetaObject *mo)
{
    QMetaObjectValidatorResult::Results r = QMetaObjectValidatorResult::NoIssue;
    if (isDynamicMetaObject(mo)) // those may dynamically add properties we query...
        return r;

    for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i) {
        const auto prop = mo->property(i);
        r |= checkProperty(mo, prop);
    }

    for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
        const auto method = mo->method(i);
        r |= checkMethod(mo, method);
    }

    return r;
}