annotate generator/abstractmetabuilder.cpp @ 259:515d6e1c7b10 lifetime

another iteration
author maxter
date Thu, 17 Sep 2009 16:28:41 +0000
parents 17b5e13364b7
children b5773ccab07d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
e78566595089 initial import
mandel
parents:
diff changeset
1 /****************************************************************************
e78566595089 initial import
mandel
parents:
diff changeset
2 **
e78566595089 initial import
mandel
parents:
diff changeset
3 ** Copyright (C) 1992-2008 Nokia. All rights reserved.
e78566595089 initial import
mandel
parents:
diff changeset
4 **
e78566595089 initial import
mandel
parents:
diff changeset
5 ** This file is part of Qt Jambi.
e78566595089 initial import
mandel
parents:
diff changeset
6 **
e78566595089 initial import
mandel
parents:
diff changeset
7 ** * Commercial Usage
e78566595089 initial import
mandel
parents:
diff changeset
8 * Licensees holding valid Qt Commercial licenses may use this file in
e78566595089 initial import
mandel
parents:
diff changeset
9 * accordance with the Qt Commercial License Agreement provided with the
e78566595089 initial import
mandel
parents:
diff changeset
10 * Software or, alternatively, in accordance with the terms contained in
e78566595089 initial import
mandel
parents:
diff changeset
11 * a written agreement between you and Nokia.
e78566595089 initial import
mandel
parents:
diff changeset
12 *
e78566595089 initial import
mandel
parents:
diff changeset
13 *
e78566595089 initial import
mandel
parents:
diff changeset
14 * GNU General Public License Usage
e78566595089 initial import
mandel
parents:
diff changeset
15 * Alternatively, this file may be used under the terms of the GNU
e78566595089 initial import
mandel
parents:
diff changeset
16 * General Public License versions 2.0 or 3.0 as published by the Free
e78566595089 initial import
mandel
parents:
diff changeset
17 * Software Foundation and appearing in the file LICENSE.GPL included in
e78566595089 initial import
mandel
parents:
diff changeset
18 * the packaging of this file. Please review the following information
e78566595089 initial import
mandel
parents:
diff changeset
19 * to ensure GNU General Public Licensing requirements will be met:
e78566595089 initial import
mandel
parents:
diff changeset
20 * http://www.fsf.org/licensing/licenses/info/GPLv2.html and
e78566595089 initial import
mandel
parents:
diff changeset
21 * http://www.gnu.org/copyleft/gpl.html. In addition, as a special
e78566595089 initial import
mandel
parents:
diff changeset
22 * exception, Nokia gives you certain additional rights. These rights
e78566595089 initial import
mandel
parents:
diff changeset
23 * are described in the Nokia Qt GPL Exception version 1.2, included in
e78566595089 initial import
mandel
parents:
diff changeset
24 * the file GPL_EXCEPTION.txt in this package.
e78566595089 initial import
mandel
parents:
diff changeset
25 *
e78566595089 initial import
mandel
parents:
diff changeset
26 * Qt for Windows(R) Licensees
e78566595089 initial import
mandel
parents:
diff changeset
27 * As a special exception, Nokia, as the sole copyright holder for Qt
e78566595089 initial import
mandel
parents:
diff changeset
28 * Designer, grants users of the Qt/Eclipse Integration plug-in the
e78566595089 initial import
mandel
parents:
diff changeset
29 * right for the Qt/Eclipse Integration to link to functionality
e78566595089 initial import
mandel
parents:
diff changeset
30 * provided by Qt Designer and its related libraries.
e78566595089 initial import
mandel
parents:
diff changeset
31 *
e78566595089 initial import
mandel
parents:
diff changeset
32 *
e78566595089 initial import
mandel
parents:
diff changeset
33 * If you are unsure which license is appropriate for your use, please
e78566595089 initial import
mandel
parents:
diff changeset
34 * contact the sales department at qt-sales@nokia.com.
e78566595089 initial import
mandel
parents:
diff changeset
35
e78566595089 initial import
mandel
parents:
diff changeset
36 **
e78566595089 initial import
mandel
parents:
diff changeset
37 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
e78566595089 initial import
mandel
parents:
diff changeset
38 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
e78566595089 initial import
mandel
parents:
diff changeset
39 **
e78566595089 initial import
mandel
parents:
diff changeset
40 ****************************************************************************/
e78566595089 initial import
mandel
parents:
diff changeset
41
e78566595089 initial import
mandel
parents:
diff changeset
42 #include "abstractmetabuilder.h"
e78566595089 initial import
mandel
parents:
diff changeset
43 #include "reporthandler.h"
e78566595089 initial import
mandel
parents:
diff changeset
44
e78566595089 initial import
mandel
parents:
diff changeset
45 #include "ast.h"
e78566595089 initial import
mandel
parents:
diff changeset
46 #include "binder.h"
e78566595089 initial import
mandel
parents:
diff changeset
47 #include "control.h"
e78566595089 initial import
mandel
parents:
diff changeset
48 #include "default_visitor.h"
e78566595089 initial import
mandel
parents:
diff changeset
49 #include "dumptree.h"
e78566595089 initial import
mandel
parents:
diff changeset
50 #include "lexer.h"
e78566595089 initial import
mandel
parents:
diff changeset
51 #include "parser.h"
e78566595089 initial import
mandel
parents:
diff changeset
52 #include "tokens.h"
e78566595089 initial import
mandel
parents:
diff changeset
53
e78566595089 initial import
mandel
parents:
diff changeset
54 #include <QtCore/QDebug>
e78566595089 initial import
mandel
parents:
diff changeset
55 #include <QtCore/QFile>
e78566595089 initial import
mandel
parents:
diff changeset
56 #include <QtCore/QFileInfo>
e78566595089 initial import
mandel
parents:
diff changeset
57 #include <QtCore/QTextCodec>
e78566595089 initial import
mandel
parents:
diff changeset
58 #include <QtCore/QTextStream>
e78566595089 initial import
mandel
parents:
diff changeset
59 #include <QtCore/QVariant>
e78566595089 initial import
mandel
parents:
diff changeset
60
259
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
61 #include <iostream>
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
62
1
e78566595089 initial import
mandel
parents:
diff changeset
63 static QString strip_template_args(const QString &name)
e78566595089 initial import
mandel
parents:
diff changeset
64 {
e78566595089 initial import
mandel
parents:
diff changeset
65 int pos = name.indexOf('<');
e78566595089 initial import
mandel
parents:
diff changeset
66 return pos < 0 ? name : name.left(pos);
e78566595089 initial import
mandel
parents:
diff changeset
67 }
e78566595089 initial import
mandel
parents:
diff changeset
68
e78566595089 initial import
mandel
parents:
diff changeset
69 static QHash<QString, QString> *operator_names;
e78566595089 initial import
mandel
parents:
diff changeset
70 QString rename_operator(const QString &oper)
e78566595089 initial import
mandel
parents:
diff changeset
71 {
e78566595089 initial import
mandel
parents:
diff changeset
72 QString op = oper.trimmed();
e78566595089 initial import
mandel
parents:
diff changeset
73 if (!operator_names) {
e78566595089 initial import
mandel
parents:
diff changeset
74 operator_names = new QHash<QString, QString>;
e78566595089 initial import
mandel
parents:
diff changeset
75
e78566595089 initial import
mandel
parents:
diff changeset
76 operator_names->insert("+", "add");
e78566595089 initial import
mandel
parents:
diff changeset
77 operator_names->insert("-", "subtract");
e78566595089 initial import
mandel
parents:
diff changeset
78 operator_names->insert("*", "multiply");
e78566595089 initial import
mandel
parents:
diff changeset
79 operator_names->insert("/", "divide");
e78566595089 initial import
mandel
parents:
diff changeset
80 operator_names->insert("%", "modulo");
e78566595089 initial import
mandel
parents:
diff changeset
81 operator_names->insert("&", "and");
e78566595089 initial import
mandel
parents:
diff changeset
82 operator_names->insert("|", "or");
e78566595089 initial import
mandel
parents:
diff changeset
83 operator_names->insert("^", "xor");
e78566595089 initial import
mandel
parents:
diff changeset
84 operator_names->insert("~", "negate");
e78566595089 initial import
mandel
parents:
diff changeset
85 operator_names->insert("<<", "shift_left");
e78566595089 initial import
mandel
parents:
diff changeset
86 operator_names->insert(">>", "shift_right");
e78566595089 initial import
mandel
parents:
diff changeset
87
e78566595089 initial import
mandel
parents:
diff changeset
88 // assigments
e78566595089 initial import
mandel
parents:
diff changeset
89 operator_names->insert("=", "assign");
e78566595089 initial import
mandel
parents:
diff changeset
90 operator_names->insert("+=", "add_assign");
e78566595089 initial import
mandel
parents:
diff changeset
91 operator_names->insert("-=", "subtract_assign");
e78566595089 initial import
mandel
parents:
diff changeset
92 operator_names->insert("*=", "multiply_assign");
e78566595089 initial import
mandel
parents:
diff changeset
93 operator_names->insert("/=", "divide_assign");
e78566595089 initial import
mandel
parents:
diff changeset
94 operator_names->insert("%=", "modulo_assign");
e78566595089 initial import
mandel
parents:
diff changeset
95 operator_names->insert("&=", "and_assign");
e78566595089 initial import
mandel
parents:
diff changeset
96 operator_names->insert("|=", "or_assign");
e78566595089 initial import
mandel
parents:
diff changeset
97 operator_names->insert("^=", "xor_assign");
e78566595089 initial import
mandel
parents:
diff changeset
98 operator_names->insert("<<=", "shift_left_assign");
e78566595089 initial import
mandel
parents:
diff changeset
99 operator_names->insert(">>=", "shift_right_assign");
e78566595089 initial import
mandel
parents:
diff changeset
100
e78566595089 initial import
mandel
parents:
diff changeset
101 // Logical
e78566595089 initial import
mandel
parents:
diff changeset
102 operator_names->insert("&&", "logical_and");
e78566595089 initial import
mandel
parents:
diff changeset
103 operator_names->insert("||", "logical_or");
e78566595089 initial import
mandel
parents:
diff changeset
104 operator_names->insert("!", "not");
e78566595089 initial import
mandel
parents:
diff changeset
105
e78566595089 initial import
mandel
parents:
diff changeset
106 // incr/decr
e78566595089 initial import
mandel
parents:
diff changeset
107 operator_names->insert("++", "increment");
e78566595089 initial import
mandel
parents:
diff changeset
108 operator_names->insert("--", "decrement");
e78566595089 initial import
mandel
parents:
diff changeset
109
e78566595089 initial import
mandel
parents:
diff changeset
110 // compare
e78566595089 initial import
mandel
parents:
diff changeset
111 operator_names->insert("<", "less");
e78566595089 initial import
mandel
parents:
diff changeset
112 operator_names->insert(">", "greater");
e78566595089 initial import
mandel
parents:
diff changeset
113 operator_names->insert("<=", "less_or_equal");
e78566595089 initial import
mandel
parents:
diff changeset
114 operator_names->insert(">=", "greater_or_equal");
e78566595089 initial import
mandel
parents:
diff changeset
115 operator_names->insert("!=", "not_equal");
e78566595089 initial import
mandel
parents:
diff changeset
116 operator_names->insert("==", "equal");
e78566595089 initial import
mandel
parents:
diff changeset
117
e78566595089 initial import
mandel
parents:
diff changeset
118 // other
e78566595089 initial import
mandel
parents:
diff changeset
119 operator_names->insert("[]", "subscript");
e78566595089 initial import
mandel
parents:
diff changeset
120 operator_names->insert("->", "pointer");
e78566595089 initial import
mandel
parents:
diff changeset
121 }
e78566595089 initial import
mandel
parents:
diff changeset
122
e78566595089 initial import
mandel
parents:
diff changeset
123 if (!operator_names->contains(op)) {
e78566595089 initial import
mandel
parents:
diff changeset
124 TypeDatabase *tb = TypeDatabase::instance();
e78566595089 initial import
mandel
parents:
diff changeset
125
e78566595089 initial import
mandel
parents:
diff changeset
126 TypeParser::Info typeInfo = TypeParser::parse(op);
e78566595089 initial import
mandel
parents:
diff changeset
127 QString cast_to_name = typeInfo.qualified_name.join("::");
e78566595089 initial import
mandel
parents:
diff changeset
128 TypeEntry *te = tb->findType(cast_to_name);
e78566595089 initial import
mandel
parents:
diff changeset
129 if ((te && te->codeGeneration() == TypeEntry::GenerateNothing)
e78566595089 initial import
mandel
parents:
diff changeset
130 || tb->isClassRejected(cast_to_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
131 return QString();
e78566595089 initial import
mandel
parents:
diff changeset
132 } else if (te) {
e78566595089 initial import
mandel
parents:
diff changeset
133 return "operator_cast_" + typeInfo.qualified_name.join("_");
e78566595089 initial import
mandel
parents:
diff changeset
134 } else {
e78566595089 initial import
mandel
parents:
diff changeset
135 ReportHandler::warning(QString("unknown operator '%1'").arg(op));
e78566595089 initial import
mandel
parents:
diff changeset
136 return "operator " + op;
e78566595089 initial import
mandel
parents:
diff changeset
137 }
e78566595089 initial import
mandel
parents:
diff changeset
138 }
e78566595089 initial import
mandel
parents:
diff changeset
139
e78566595089 initial import
mandel
parents:
diff changeset
140 return "operator_" + operator_names->value(op);
e78566595089 initial import
mandel
parents:
diff changeset
141 }
e78566595089 initial import
mandel
parents:
diff changeset
142
e78566595089 initial import
mandel
parents:
diff changeset
143 AbstractMetaBuilder::AbstractMetaBuilder()
e78566595089 initial import
mandel
parents:
diff changeset
144 : m_current_class(0)
e78566595089 initial import
mandel
parents:
diff changeset
145 {
e78566595089 initial import
mandel
parents:
diff changeset
146 }
e78566595089 initial import
mandel
parents:
diff changeset
147
e78566595089 initial import
mandel
parents:
diff changeset
148 void AbstractMetaBuilder::checkFunctionModifications()
e78566595089 initial import
mandel
parents:
diff changeset
149 {
e78566595089 initial import
mandel
parents:
diff changeset
150 TypeDatabase *types = TypeDatabase::instance();
e78566595089 initial import
mandel
parents:
diff changeset
151 SingleTypeEntryHash entryHash = types->entries();
e78566595089 initial import
mandel
parents:
diff changeset
152 QList<TypeEntry *> entries = entryHash.values();
e78566595089 initial import
mandel
parents:
diff changeset
153 foreach (TypeEntry *entry, entries) {
e78566595089 initial import
mandel
parents:
diff changeset
154 if (entry == 0)
e78566595089 initial import
mandel
parents:
diff changeset
155 continue;
e78566595089 initial import
mandel
parents:
diff changeset
156 if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing)
e78566595089 initial import
mandel
parents:
diff changeset
157 continue;
e78566595089 initial import
mandel
parents:
diff changeset
158
e78566595089 initial import
mandel
parents:
diff changeset
159 ComplexTypeEntry *centry = static_cast<ComplexTypeEntry *>(entry);
e78566595089 initial import
mandel
parents:
diff changeset
160 FunctionModificationList modifications = centry->functionModifications();
e78566595089 initial import
mandel
parents:
diff changeset
161
e78566595089 initial import
mandel
parents:
diff changeset
162 foreach (FunctionModification modification, modifications) {
e78566595089 initial import
mandel
parents:
diff changeset
163 QString signature = modification.signature;
e78566595089 initial import
mandel
parents:
diff changeset
164
e78566595089 initial import
mandel
parents:
diff changeset
165 QString name = signature.trimmed();
e78566595089 initial import
mandel
parents:
diff changeset
166 name = name.mid(0, signature.indexOf("("));
e78566595089 initial import
mandel
parents:
diff changeset
167
e78566595089 initial import
mandel
parents:
diff changeset
168 AbstractMetaClass *clazz = m_meta_classes.findClass(centry->qualifiedCppName());
e78566595089 initial import
mandel
parents:
diff changeset
169 if (clazz == 0)
e78566595089 initial import
mandel
parents:
diff changeset
170 continue;
e78566595089 initial import
mandel
parents:
diff changeset
171
e78566595089 initial import
mandel
parents:
diff changeset
172 AbstractMetaFunctionList functions = clazz->functions();
e78566595089 initial import
mandel
parents:
diff changeset
173 bool found = false;
e78566595089 initial import
mandel
parents:
diff changeset
174 QStringList possibleSignatures;
e78566595089 initial import
mandel
parents:
diff changeset
175 foreach (AbstractMetaFunction *function, functions) {
e78566595089 initial import
mandel
parents:
diff changeset
176 if (function->minimalSignature() == signature && function->implementingClass() == clazz) {
e78566595089 initial import
mandel
parents:
diff changeset
177 found = true;
e78566595089 initial import
mandel
parents:
diff changeset
178 break;
e78566595089 initial import
mandel
parents:
diff changeset
179 }
e78566595089 initial import
mandel
parents:
diff changeset
180
e78566595089 initial import
mandel
parents:
diff changeset
181 if (function->originalName() == name)
e78566595089 initial import
mandel
parents:
diff changeset
182 possibleSignatures.append(function->minimalSignature() + " in " + function->implementingClass()->name());
e78566595089 initial import
mandel
parents:
diff changeset
183 }
e78566595089 initial import
mandel
parents:
diff changeset
184
e78566595089 initial import
mandel
parents:
diff changeset
185 if (!found) {
e78566595089 initial import
mandel
parents:
diff changeset
186 QString warning
e78566595089 initial import
mandel
parents:
diff changeset
187 = QString("signature '%1' for function modification in '%2' not found. Possible candidates: %3")
e78566595089 initial import
mandel
parents:
diff changeset
188 .arg(signature)
e78566595089 initial import
mandel
parents:
diff changeset
189 .arg(clazz->qualifiedCppName())
e78566595089 initial import
mandel
parents:
diff changeset
190 .arg(possibleSignatures.join(", "));
e78566595089 initial import
mandel
parents:
diff changeset
191
e78566595089 initial import
mandel
parents:
diff changeset
192 ReportHandler::warning(warning);
e78566595089 initial import
mandel
parents:
diff changeset
193 }
e78566595089 initial import
mandel
parents:
diff changeset
194 }
e78566595089 initial import
mandel
parents:
diff changeset
195 }
e78566595089 initial import
mandel
parents:
diff changeset
196 }
e78566595089 initial import
mandel
parents:
diff changeset
197
e78566595089 initial import
mandel
parents:
diff changeset
198 AbstractMetaClass *AbstractMetaBuilder::argumentToClass(ArgumentModelItem argument)
e78566595089 initial import
mandel
parents:
diff changeset
199 {
e78566595089 initial import
mandel
parents:
diff changeset
200 AbstractMetaClass *returned = 0;
e78566595089 initial import
mandel
parents:
diff changeset
201 bool ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
202 AbstractMetaType *type = translateType(argument->type(), &ok);
e78566595089 initial import
mandel
parents:
diff changeset
203 if (ok && type != 0 && type->typeEntry() != 0 && type->typeEntry()->isComplex()) {
e78566595089 initial import
mandel
parents:
diff changeset
204 const TypeEntry *entry = type->typeEntry();
e78566595089 initial import
mandel
parents:
diff changeset
205 returned = m_meta_classes.findClass(entry->name());
e78566595089 initial import
mandel
parents:
diff changeset
206 }
e78566595089 initial import
mandel
parents:
diff changeset
207 delete type;
e78566595089 initial import
mandel
parents:
diff changeset
208 return returned;
e78566595089 initial import
mandel
parents:
diff changeset
209 }
e78566595089 initial import
mandel
parents:
diff changeset
210
e78566595089 initial import
mandel
parents:
diff changeset
211 /**
e78566595089 initial import
mandel
parents:
diff changeset
212 * Checks the argument of a hash function and flags the type if it is a complex type
e78566595089 initial import
mandel
parents:
diff changeset
213 */
e78566595089 initial import
mandel
parents:
diff changeset
214 void AbstractMetaBuilder::registerHashFunction(FunctionModelItem function_item)
e78566595089 initial import
mandel
parents:
diff changeset
215 {
e78566595089 initial import
mandel
parents:
diff changeset
216 ArgumentList arguments = function_item->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
217 if (arguments.size() == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
218 if (AbstractMetaClass *cls = argumentToClass(arguments.at(0)))
e78566595089 initial import
mandel
parents:
diff changeset
219 cls->setHasHashFunction(true);
e78566595089 initial import
mandel
parents:
diff changeset
220 }
e78566595089 initial import
mandel
parents:
diff changeset
221 }
e78566595089 initial import
mandel
parents:
diff changeset
222
e78566595089 initial import
mandel
parents:
diff changeset
223 /**
e78566595089 initial import
mandel
parents:
diff changeset
224 * Check if a class has a debug stream operator that can be used as toString
e78566595089 initial import
mandel
parents:
diff changeset
225 */
e78566595089 initial import
mandel
parents:
diff changeset
226
e78566595089 initial import
mandel
parents:
diff changeset
227 void AbstractMetaBuilder::registerToStringCapability(FunctionModelItem function_item)
e78566595089 initial import
mandel
parents:
diff changeset
228 {
e78566595089 initial import
mandel
parents:
diff changeset
229 ArgumentList arguments = function_item->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
230 if (arguments.size() == 2) {
e78566595089 initial import
mandel
parents:
diff changeset
231 if (arguments.at(0)->type().toString() == "QDebug"){
e78566595089 initial import
mandel
parents:
diff changeset
232 ArgumentModelItem arg = arguments.at(1);
e78566595089 initial import
mandel
parents:
diff changeset
233 if (AbstractMetaClass *cls = argumentToClass(arg)) {
e78566595089 initial import
mandel
parents:
diff changeset
234 if (arg->type().indirections() < 2) {
e78566595089 initial import
mandel
parents:
diff changeset
235 cls->setToStringCapability(function_item);
e78566595089 initial import
mandel
parents:
diff changeset
236 }
e78566595089 initial import
mandel
parents:
diff changeset
237 }
e78566595089 initial import
mandel
parents:
diff changeset
238 }
e78566595089 initial import
mandel
parents:
diff changeset
239 }
e78566595089 initial import
mandel
parents:
diff changeset
240 }
e78566595089 initial import
mandel
parents:
diff changeset
241
e78566595089 initial import
mandel
parents:
diff changeset
242 void AbstractMetaBuilder::traverseCompareOperator(FunctionModelItem item) {
e78566595089 initial import
mandel
parents:
diff changeset
243 ArgumentList arguments = item->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
244 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
e78566595089 initial import
mandel
parents:
diff changeset
245 AbstractMetaClass *comparer_class = argumentToClass(arguments.at(0));
e78566595089 initial import
mandel
parents:
diff changeset
246 AbstractMetaClass *compared_class = argumentToClass(arguments.at(1));
e78566595089 initial import
mandel
parents:
diff changeset
247 if (comparer_class != 0 && compared_class != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
248 AbstractMetaClass *old_current_class = m_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
249 m_current_class = comparer_class;
e78566595089 initial import
mandel
parents:
diff changeset
250
e78566595089 initial import
mandel
parents:
diff changeset
251 AbstractMetaFunction *meta_function = traverseFunction(item);
e78566595089 initial import
mandel
parents:
diff changeset
252 if (meta_function != 0 && !meta_function->isInvalid()) {
e78566595089 initial import
mandel
parents:
diff changeset
253 // Strip away first argument, since that is the containing object
e78566595089 initial import
mandel
parents:
diff changeset
254 AbstractMetaArgumentList arguments = meta_function->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
255 arguments.pop_front();
e78566595089 initial import
mandel
parents:
diff changeset
256 meta_function->setArguments(arguments);
e78566595089 initial import
mandel
parents:
diff changeset
257
e78566595089 initial import
mandel
parents:
diff changeset
258 meta_function->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
e78566595089 initial import
mandel
parents:
diff changeset
259
e78566595089 initial import
mandel
parents:
diff changeset
260 meta_function->setOriginalAttributes(meta_function->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
261 setupFunctionDefaults(meta_function, comparer_class);
e78566595089 initial import
mandel
parents:
diff changeset
262
e78566595089 initial import
mandel
parents:
diff changeset
263 comparer_class->addFunction(meta_function);
e78566595089 initial import
mandel
parents:
diff changeset
264 } else if (meta_function != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
265 delete meta_function;
e78566595089 initial import
mandel
parents:
diff changeset
266 }
e78566595089 initial import
mandel
parents:
diff changeset
267
e78566595089 initial import
mandel
parents:
diff changeset
268 m_current_class = old_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
269 }
e78566595089 initial import
mandel
parents:
diff changeset
270 }
e78566595089 initial import
mandel
parents:
diff changeset
271 }
e78566595089 initial import
mandel
parents:
diff changeset
272
e78566595089 initial import
mandel
parents:
diff changeset
273 void AbstractMetaBuilder::traverseStreamOperator(FunctionModelItem item)
e78566595089 initial import
mandel
parents:
diff changeset
274 {
e78566595089 initial import
mandel
parents:
diff changeset
275 ArgumentList arguments = item->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
276 if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) {
e78566595089 initial import
mandel
parents:
diff changeset
277 AbstractMetaClass *streamClass = argumentToClass(arguments.at(0));
e78566595089 initial import
mandel
parents:
diff changeset
278 AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1));
e78566595089 initial import
mandel
parents:
diff changeset
279
e78566595089 initial import
mandel
parents:
diff changeset
280 if (streamClass != 0 && streamedClass != 0
e78566595089 initial import
mandel
parents:
diff changeset
281 && (streamClass->name() == "QDataStream" || streamClass->name() == "QTextStream")) {
e78566595089 initial import
mandel
parents:
diff changeset
282 AbstractMetaClass *old_current_class = m_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
283 m_current_class = streamedClass;
e78566595089 initial import
mandel
parents:
diff changeset
284 AbstractMetaFunction *streamFunction = traverseFunction(item);
e78566595089 initial import
mandel
parents:
diff changeset
285
e78566595089 initial import
mandel
parents:
diff changeset
286 if (streamFunction != 0 && !streamFunction->isInvalid()) {
e78566595089 initial import
mandel
parents:
diff changeset
287 QString name = item->name();
e78566595089 initial import
mandel
parents:
diff changeset
288 streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction);
e78566595089 initial import
mandel
parents:
diff changeset
289
e78566595089 initial import
mandel
parents:
diff changeset
290 if (name.endsWith("<<"))
e78566595089 initial import
mandel
parents:
diff changeset
291 streamFunction->setName("writeTo");
e78566595089 initial import
mandel
parents:
diff changeset
292 else
e78566595089 initial import
mandel
parents:
diff changeset
293 streamFunction->setName("readFrom");
e78566595089 initial import
mandel
parents:
diff changeset
294
e78566595089 initial import
mandel
parents:
diff changeset
295 // Strip away last argument, since that is the containing object
e78566595089 initial import
mandel
parents:
diff changeset
296 AbstractMetaArgumentList arguments = streamFunction->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
297 arguments.pop_back();
e78566595089 initial import
mandel
parents:
diff changeset
298 streamFunction->setArguments(arguments);
e78566595089 initial import
mandel
parents:
diff changeset
299
e78566595089 initial import
mandel
parents:
diff changeset
300 *streamFunction += AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
301 *streamFunction += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
302 streamFunction->setOriginalAttributes(streamFunction->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
303
e78566595089 initial import
mandel
parents:
diff changeset
304 streamFunction->setType(0);
e78566595089 initial import
mandel
parents:
diff changeset
305
e78566595089 initial import
mandel
parents:
diff changeset
306 setupFunctionDefaults(streamFunction, streamedClass);
e78566595089 initial import
mandel
parents:
diff changeset
307
e78566595089 initial import
mandel
parents:
diff changeset
308 streamedClass->addFunction(streamFunction);
e78566595089 initial import
mandel
parents:
diff changeset
309 streamedClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
e78566595089 initial import
mandel
parents:
diff changeset
310
e78566595089 initial import
mandel
parents:
diff changeset
311 m_current_class = old_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
312 }
e78566595089 initial import
mandel
parents:
diff changeset
313 }
e78566595089 initial import
mandel
parents:
diff changeset
314 }
e78566595089 initial import
mandel
parents:
diff changeset
315 }
e78566595089 initial import
mandel
parents:
diff changeset
316
e78566595089 initial import
mandel
parents:
diff changeset
317 void AbstractMetaBuilder::fixQObjectForScope(TypeDatabase *types,
e78566595089 initial import
mandel
parents:
diff changeset
318 NamespaceModelItem scope)
e78566595089 initial import
mandel
parents:
diff changeset
319 {
e78566595089 initial import
mandel
parents:
diff changeset
320 foreach (ClassModelItem item, scope->classes()) {
e78566595089 initial import
mandel
parents:
diff changeset
321 QString qualified_name = item->qualifiedName().join("::");
e78566595089 initial import
mandel
parents:
diff changeset
322 TypeEntry *entry = types->findType(qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
323 if (entry) {
e78566595089 initial import
mandel
parents:
diff changeset
324 if (isQObject(qualified_name) && entry->isComplex()) {
e78566595089 initial import
mandel
parents:
diff changeset
325 ((ComplexTypeEntry *) entry)->setQObject(true);
e78566595089 initial import
mandel
parents:
diff changeset
326 }
e78566595089 initial import
mandel
parents:
diff changeset
327 }
e78566595089 initial import
mandel
parents:
diff changeset
328 }
e78566595089 initial import
mandel
parents:
diff changeset
329
e78566595089 initial import
mandel
parents:
diff changeset
330 foreach (NamespaceModelItem item, scope->namespaceMap().values()) {
e78566595089 initial import
mandel
parents:
diff changeset
331 if (scope != item)
e78566595089 initial import
mandel
parents:
diff changeset
332 fixQObjectForScope(types, item);
e78566595089 initial import
mandel
parents:
diff changeset
333 }
e78566595089 initial import
mandel
parents:
diff changeset
334 }
e78566595089 initial import
mandel
parents:
diff changeset
335
e78566595089 initial import
mandel
parents:
diff changeset
336 static bool class_less_than(AbstractMetaClass *a, AbstractMetaClass *b)
e78566595089 initial import
mandel
parents:
diff changeset
337 {
e78566595089 initial import
mandel
parents:
diff changeset
338 return a->name() < b->name();
e78566595089 initial import
mandel
parents:
diff changeset
339 }
e78566595089 initial import
mandel
parents:
diff changeset
340
e78566595089 initial import
mandel
parents:
diff changeset
341
e78566595089 initial import
mandel
parents:
diff changeset
342 void AbstractMetaBuilder::sortLists()
e78566595089 initial import
mandel
parents:
diff changeset
343 {
e78566595089 initial import
mandel
parents:
diff changeset
344 qSort(m_meta_classes.begin(), m_meta_classes.end(), class_less_than);
e78566595089 initial import
mandel
parents:
diff changeset
345 foreach (AbstractMetaClass *cls, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
346 cls->sortFunctions();
e78566595089 initial import
mandel
parents:
diff changeset
347 }
e78566595089 initial import
mandel
parents:
diff changeset
348 }
e78566595089 initial import
mandel
parents:
diff changeset
349
e78566595089 initial import
mandel
parents:
diff changeset
350 bool AbstractMetaBuilder::build()
e78566595089 initial import
mandel
parents:
diff changeset
351 {
e78566595089 initial import
mandel
parents:
diff changeset
352 Q_ASSERT(!m_file_name.isEmpty());
e78566595089 initial import
mandel
parents:
diff changeset
353 ReportHandler::setContext("Parser");
e78566595089 initial import
mandel
parents:
diff changeset
354
e78566595089 initial import
mandel
parents:
diff changeset
355 QFile file(m_file_name);
e78566595089 initial import
mandel
parents:
diff changeset
356
e78566595089 initial import
mandel
parents:
diff changeset
357 if (!file.open(QFile::ReadOnly))
e78566595089 initial import
mandel
parents:
diff changeset
358 return false;
e78566595089 initial import
mandel
parents:
diff changeset
359
e78566595089 initial import
mandel
parents:
diff changeset
360 QTextStream stream(&file);
e78566595089 initial import
mandel
parents:
diff changeset
361 stream.setCodec(QTextCodec::codecForName("UTF-8"));
e78566595089 initial import
mandel
parents:
diff changeset
362 QByteArray contents = stream.readAll().toUtf8();
e78566595089 initial import
mandel
parents:
diff changeset
363 file.close();
e78566595089 initial import
mandel
parents:
diff changeset
364
e78566595089 initial import
mandel
parents:
diff changeset
365 Control control;
e78566595089 initial import
mandel
parents:
diff changeset
366 Parser p(&control);
e78566595089 initial import
mandel
parents:
diff changeset
367 pool __pool;
e78566595089 initial import
mandel
parents:
diff changeset
368
e78566595089 initial import
mandel
parents:
diff changeset
369 TranslationUnitAST *ast = p.parse(contents, contents.size(), &__pool);
e78566595089 initial import
mandel
parents:
diff changeset
370
e78566595089 initial import
mandel
parents:
diff changeset
371 CodeModel model;
e78566595089 initial import
mandel
parents:
diff changeset
372 Binder binder(&model, p.location());
e78566595089 initial import
mandel
parents:
diff changeset
373 m_dom = binder.run(ast);
e78566595089 initial import
mandel
parents:
diff changeset
374
e78566595089 initial import
mandel
parents:
diff changeset
375
e78566595089 initial import
mandel
parents:
diff changeset
376 ReportHandler::setContext("MetaJavaBuilder");
e78566595089 initial import
mandel
parents:
diff changeset
377
e78566595089 initial import
mandel
parents:
diff changeset
378
e78566595089 initial import
mandel
parents:
diff changeset
379 pushScope(model_dynamic_cast<ScopeModelItem>(m_dom));
e78566595089 initial import
mandel
parents:
diff changeset
380
e78566595089 initial import
mandel
parents:
diff changeset
381 QHash<QString, ClassModelItem> typeMap = m_dom->classMap();
e78566595089 initial import
mandel
parents:
diff changeset
382
e78566595089 initial import
mandel
parents:
diff changeset
383
e78566595089 initial import
mandel
parents:
diff changeset
384 // fix up QObject's in the type system..
e78566595089 initial import
mandel
parents:
diff changeset
385 TypeDatabase *types = TypeDatabase::instance();
e78566595089 initial import
mandel
parents:
diff changeset
386 fixQObjectForScope(types, model_dynamic_cast<NamespaceModelItem>(m_dom));
e78566595089 initial import
mandel
parents:
diff changeset
387
e78566595089 initial import
mandel
parents:
diff changeset
388
e78566595089 initial import
mandel
parents:
diff changeset
389 // Start the generation...
e78566595089 initial import
mandel
parents:
diff changeset
390 foreach (ClassModelItem item, typeMap.values()) {
e78566595089 initial import
mandel
parents:
diff changeset
391 AbstractMetaClass *cls = traverseClass(item);
e78566595089 initial import
mandel
parents:
diff changeset
392 addAbstractMetaClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
393 }
e78566595089 initial import
mandel
parents:
diff changeset
394
e78566595089 initial import
mandel
parents:
diff changeset
395
e78566595089 initial import
mandel
parents:
diff changeset
396 QHash<QString, NamespaceModelItem> namespaceMap = m_dom->namespaceMap();
e78566595089 initial import
mandel
parents:
diff changeset
397 foreach (NamespaceModelItem item, namespaceMap.values()) {
e78566595089 initial import
mandel
parents:
diff changeset
398 AbstractMetaClass *meta_class = traverseNamespace(item);
e78566595089 initial import
mandel
parents:
diff changeset
399 if (meta_class)
e78566595089 initial import
mandel
parents:
diff changeset
400 m_meta_classes << meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
401 }
e78566595089 initial import
mandel
parents:
diff changeset
402
e78566595089 initial import
mandel
parents:
diff changeset
403
e78566595089 initial import
mandel
parents:
diff changeset
404 // Some trickery to support global-namespace enums...
e78566595089 initial import
mandel
parents:
diff changeset
405 QHash<QString, EnumModelItem> enumMap = m_dom->enumMap();
e78566595089 initial import
mandel
parents:
diff changeset
406 m_current_class = 0;
e78566595089 initial import
mandel
parents:
diff changeset
407 foreach (EnumModelItem item, enumMap) {
e78566595089 initial import
mandel
parents:
diff changeset
408 AbstractMetaEnum *meta_enum = traverseEnum(item, 0, QSet<QString>());
e78566595089 initial import
mandel
parents:
diff changeset
409
e78566595089 initial import
mandel
parents:
diff changeset
410 if (meta_enum) {
e78566595089 initial import
mandel
parents:
diff changeset
411 QString package = meta_enum->typeEntry()->javaPackage();
e78566595089 initial import
mandel
parents:
diff changeset
412 QString globalName = TypeDatabase::globalNamespaceClassName(meta_enum->typeEntry());
e78566595089 initial import
mandel
parents:
diff changeset
413
e78566595089 initial import
mandel
parents:
diff changeset
414 AbstractMetaClass *global = m_meta_classes.findClass(package + "." + globalName);
e78566595089 initial import
mandel
parents:
diff changeset
415 if (!global) {
e78566595089 initial import
mandel
parents:
diff changeset
416 ComplexTypeEntry *gte = new ObjectTypeEntry(globalName);
e78566595089 initial import
mandel
parents:
diff changeset
417 gte->setTargetLangPackage(meta_enum->typeEntry()->javaPackage());
e78566595089 initial import
mandel
parents:
diff changeset
418 gte->setCodeGeneration(meta_enum->typeEntry()->codeGeneration());
e78566595089 initial import
mandel
parents:
diff changeset
419 global = createMetaClass();
e78566595089 initial import
mandel
parents:
diff changeset
420 global->setTypeEntry(gte);
e78566595089 initial import
mandel
parents:
diff changeset
421 *global += AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
422 *global += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
423 *global += AbstractMetaAttributes::Fake;
e78566595089 initial import
mandel
parents:
diff changeset
424
e78566595089 initial import
mandel
parents:
diff changeset
425 m_meta_classes << global;
e78566595089 initial import
mandel
parents:
diff changeset
426 }
e78566595089 initial import
mandel
parents:
diff changeset
427
e78566595089 initial import
mandel
parents:
diff changeset
428 global->addEnum(meta_enum);
e78566595089 initial import
mandel
parents:
diff changeset
429 meta_enum->setEnclosingClass(global);
e78566595089 initial import
mandel
parents:
diff changeset
430 meta_enum->typeEntry()->setQualifier(globalName);
e78566595089 initial import
mandel
parents:
diff changeset
431 }
e78566595089 initial import
mandel
parents:
diff changeset
432
e78566595089 initial import
mandel
parents:
diff changeset
433
e78566595089 initial import
mandel
parents:
diff changeset
434 }
e78566595089 initial import
mandel
parents:
diff changeset
435
e78566595089 initial import
mandel
parents:
diff changeset
436
e78566595089 initial import
mandel
parents:
diff changeset
437 // Go through all typedefs to see if we have defined any
e78566595089 initial import
mandel
parents:
diff changeset
438 // specific typedefs to be used as classes.
e78566595089 initial import
mandel
parents:
diff changeset
439 TypeAliasList typeAliases = m_dom->typeAliases();
e78566595089 initial import
mandel
parents:
diff changeset
440 foreach (TypeAliasModelItem typeAlias, typeAliases) {
e78566595089 initial import
mandel
parents:
diff changeset
441 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
e78566595089 initial import
mandel
parents:
diff changeset
442 addAbstractMetaClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
443 }
e78566595089 initial import
mandel
parents:
diff changeset
444
e78566595089 initial import
mandel
parents:
diff changeset
445
e78566595089 initial import
mandel
parents:
diff changeset
446
e78566595089 initial import
mandel
parents:
diff changeset
447
e78566595089 initial import
mandel
parents:
diff changeset
448 foreach (AbstractMetaClass *cls, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
449 if (!cls->isInterface() && !cls->isNamespace()) {
e78566595089 initial import
mandel
parents:
diff changeset
450 setupInheritance(cls);
e78566595089 initial import
mandel
parents:
diff changeset
451 }
e78566595089 initial import
mandel
parents:
diff changeset
452 }
e78566595089 initial import
mandel
parents:
diff changeset
453
e78566595089 initial import
mandel
parents:
diff changeset
454
e78566595089 initial import
mandel
parents:
diff changeset
455 foreach (AbstractMetaClass *cls, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
456 cls->fixFunctions();
e78566595089 initial import
mandel
parents:
diff changeset
457
e78566595089 initial import
mandel
parents:
diff changeset
458 if (cls->typeEntry() == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
459 ReportHandler::warning(QString("class '%1' does not have an entry in the type system")
e78566595089 initial import
mandel
parents:
diff changeset
460 .arg(cls->name()));
e78566595089 initial import
mandel
parents:
diff changeset
461 } else {
e78566595089 initial import
mandel
parents:
diff changeset
462 if (!cls->hasConstructors() && !cls->isFinalInCpp() && !cls->isInterface() && !cls->isNamespace())
e78566595089 initial import
mandel
parents:
diff changeset
463 cls->addDefaultConstructor();
e78566595089 initial import
mandel
parents:
diff changeset
464 }
e78566595089 initial import
mandel
parents:
diff changeset
465
e78566595089 initial import
mandel
parents:
diff changeset
466 if (cls->isAbstract() && !cls->isInterface()) {
e78566595089 initial import
mandel
parents:
diff changeset
467 cls->typeEntry()->setLookupName(cls->typeEntry()->targetLangName() + "_ConcreteWrapper");
e78566595089 initial import
mandel
parents:
diff changeset
468 }
e78566595089 initial import
mandel
parents:
diff changeset
469 }
e78566595089 initial import
mandel
parents:
diff changeset
470
e78566595089 initial import
mandel
parents:
diff changeset
471 QList<TypeEntry *> entries = TypeDatabase::instance()->entries().values();
e78566595089 initial import
mandel
parents:
diff changeset
472 foreach (const TypeEntry *entry, entries) {
e78566595089 initial import
mandel
parents:
diff changeset
473 if (entry->isPrimitive())
e78566595089 initial import
mandel
parents:
diff changeset
474 continue;
e78566595089 initial import
mandel
parents:
diff changeset
475
e78566595089 initial import
mandel
parents:
diff changeset
476 if ((entry->isValue() || entry->isObject())
e78566595089 initial import
mandel
parents:
diff changeset
477 && !entry->isString()
e78566595089 initial import
mandel
parents:
diff changeset
478 && !entry->isChar()
e78566595089 initial import
mandel
parents:
diff changeset
479 && !entry->isContainer()
e78566595089 initial import
mandel
parents:
diff changeset
480 && !entry->isCustom()
e78566595089 initial import
mandel
parents:
diff changeset
481 && !entry->isVariant()
e78566595089 initial import
mandel
parents:
diff changeset
482 && !m_meta_classes.findClass(entry->qualifiedCppName())) {
e78566595089 initial import
mandel
parents:
diff changeset
483 ReportHandler::warning(QString("type '%1' is specified in typesystem, but not defined. This could potentially lead to compilation errors.")
e78566595089 initial import
mandel
parents:
diff changeset
484 .arg(entry->qualifiedCppName()));
e78566595089 initial import
mandel
parents:
diff changeset
485 }
e78566595089 initial import
mandel
parents:
diff changeset
486
e78566595089 initial import
mandel
parents:
diff changeset
487 if (entry->isEnum()) {
e78566595089 initial import
mandel
parents:
diff changeset
488 QString pkg = entry->javaPackage();
e78566595089 initial import
mandel
parents:
diff changeset
489 QString name = (pkg.isEmpty() ? QString() : pkg + ".")
e78566595089 initial import
mandel
parents:
diff changeset
490 + ((EnumTypeEntry *) entry)->javaQualifier();
e78566595089 initial import
mandel
parents:
diff changeset
491 AbstractMetaClass *cls = m_meta_classes.findClass(name);
e78566595089 initial import
mandel
parents:
diff changeset
492
e78566595089 initial import
mandel
parents:
diff changeset
493 if (!cls) {
e78566595089 initial import
mandel
parents:
diff changeset
494 ReportHandler::warning(QString("namespace '%1' for enum '%2' is not declared")
e78566595089 initial import
mandel
parents:
diff changeset
495 .arg(name).arg(entry->targetLangName()));
e78566595089 initial import
mandel
parents:
diff changeset
496 } else {
e78566595089 initial import
mandel
parents:
diff changeset
497 AbstractMetaEnum *e = cls->findEnum(entry->targetLangName());
e78566595089 initial import
mandel
parents:
diff changeset
498 if (!e)
e78566595089 initial import
mandel
parents:
diff changeset
499 ReportHandler::warning(QString("enum '%1' is specified in typesystem, "
e78566595089 initial import
mandel
parents:
diff changeset
500 "but not declared")
e78566595089 initial import
mandel
parents:
diff changeset
501 .arg(entry->qualifiedCppName()));
e78566595089 initial import
mandel
parents:
diff changeset
502 }
e78566595089 initial import
mandel
parents:
diff changeset
503 }
e78566595089 initial import
mandel
parents:
diff changeset
504 }
e78566595089 initial import
mandel
parents:
diff changeset
505
e78566595089 initial import
mandel
parents:
diff changeset
506 {
e78566595089 initial import
mandel
parents:
diff changeset
507 FunctionList hash_functions = m_dom->findFunctions("qHash");
e78566595089 initial import
mandel
parents:
diff changeset
508 foreach (FunctionModelItem item, hash_functions) {
e78566595089 initial import
mandel
parents:
diff changeset
509 registerHashFunction(item);
e78566595089 initial import
mandel
parents:
diff changeset
510 }
e78566595089 initial import
mandel
parents:
diff changeset
511 }
e78566595089 initial import
mandel
parents:
diff changeset
512
e78566595089 initial import
mandel
parents:
diff changeset
513 {
e78566595089 initial import
mandel
parents:
diff changeset
514 FunctionList hash_functions = m_dom->findFunctions("operator<<");
e78566595089 initial import
mandel
parents:
diff changeset
515 foreach (FunctionModelItem item, hash_functions) {
e78566595089 initial import
mandel
parents:
diff changeset
516 registerToStringCapability(item);
e78566595089 initial import
mandel
parents:
diff changeset
517 }
e78566595089 initial import
mandel
parents:
diff changeset
518 }
e78566595089 initial import
mandel
parents:
diff changeset
519
e78566595089 initial import
mandel
parents:
diff changeset
520 {
e78566595089 initial import
mandel
parents:
diff changeset
521 FunctionList compare_operators = m_dom->findFunctions("operator==")
e78566595089 initial import
mandel
parents:
diff changeset
522 + m_dom->findFunctions("operator<=")
e78566595089 initial import
mandel
parents:
diff changeset
523 + m_dom->findFunctions("operator>=")
e78566595089 initial import
mandel
parents:
diff changeset
524 + m_dom->findFunctions("operator<")
e78566595089 initial import
mandel
parents:
diff changeset
525 + m_dom->findFunctions("operator>");
e78566595089 initial import
mandel
parents:
diff changeset
526 foreach (FunctionModelItem item, compare_operators) {
e78566595089 initial import
mandel
parents:
diff changeset
527 traverseCompareOperator(item);
e78566595089 initial import
mandel
parents:
diff changeset
528 }
e78566595089 initial import
mandel
parents:
diff changeset
529 }
e78566595089 initial import
mandel
parents:
diff changeset
530
e78566595089 initial import
mandel
parents:
diff changeset
531 {
e78566595089 initial import
mandel
parents:
diff changeset
532 FunctionList stream_operators = m_dom->findFunctions("operator<<") + m_dom->findFunctions("operator>>");
e78566595089 initial import
mandel
parents:
diff changeset
533 foreach (FunctionModelItem item, stream_operators) {
e78566595089 initial import
mandel
parents:
diff changeset
534 traverseStreamOperator(item);
e78566595089 initial import
mandel
parents:
diff changeset
535 }
e78566595089 initial import
mandel
parents:
diff changeset
536 }
e78566595089 initial import
mandel
parents:
diff changeset
537
e78566595089 initial import
mandel
parents:
diff changeset
538 figureOutEnumValues();
e78566595089 initial import
mandel
parents:
diff changeset
539 figureOutDefaultEnumArguments();
e78566595089 initial import
mandel
parents:
diff changeset
540 checkFunctionModifications();
e78566595089 initial import
mandel
parents:
diff changeset
541
e78566595089 initial import
mandel
parents:
diff changeset
542 foreach (AbstractMetaClass *cls, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
543 setupEquals(cls);
e78566595089 initial import
mandel
parents:
diff changeset
544 setupComparable(cls);
e78566595089 initial import
mandel
parents:
diff changeset
545 setupClonable(cls);
e78566595089 initial import
mandel
parents:
diff changeset
546 }
e78566595089 initial import
mandel
parents:
diff changeset
547
e78566595089 initial import
mandel
parents:
diff changeset
548 dumpLog();
e78566595089 initial import
mandel
parents:
diff changeset
549
e78566595089 initial import
mandel
parents:
diff changeset
550 sortLists();
e78566595089 initial import
mandel
parents:
diff changeset
551
e78566595089 initial import
mandel
parents:
diff changeset
552 return true;
e78566595089 initial import
mandel
parents:
diff changeset
553 }
e78566595089 initial import
mandel
parents:
diff changeset
554
e78566595089 initial import
mandel
parents:
diff changeset
555
e78566595089 initial import
mandel
parents:
diff changeset
556 void AbstractMetaBuilder::addAbstractMetaClass(AbstractMetaClass *cls)
e78566595089 initial import
mandel
parents:
diff changeset
557 {
e78566595089 initial import
mandel
parents:
diff changeset
558 if (!cls)
e78566595089 initial import
mandel
parents:
diff changeset
559 return;
e78566595089 initial import
mandel
parents:
diff changeset
560
e78566595089 initial import
mandel
parents:
diff changeset
561 cls->setOriginalAttributes(cls->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
562 if (cls->typeEntry()->isContainer()) {
e78566595089 initial import
mandel
parents:
diff changeset
563 m_templates << cls;
e78566595089 initial import
mandel
parents:
diff changeset
564 } else {
e78566595089 initial import
mandel
parents:
diff changeset
565 m_meta_classes << cls;
e78566595089 initial import
mandel
parents:
diff changeset
566 if (cls->typeEntry()->designatedInterface()) {
e78566595089 initial import
mandel
parents:
diff changeset
567 AbstractMetaClass *interface = cls->extractInterface();
e78566595089 initial import
mandel
parents:
diff changeset
568 m_meta_classes << interface;
e78566595089 initial import
mandel
parents:
diff changeset
569 ReportHandler::debugSparse(QString(" -> interface '%1'").arg(interface->name()));
e78566595089 initial import
mandel
parents:
diff changeset
570 }
e78566595089 initial import
mandel
parents:
diff changeset
571 }
e78566595089 initial import
mandel
parents:
diff changeset
572 }
e78566595089 initial import
mandel
parents:
diff changeset
573
e78566595089 initial import
mandel
parents:
diff changeset
574
e78566595089 initial import
mandel
parents:
diff changeset
575 AbstractMetaClass *AbstractMetaBuilder::traverseNamespace(NamespaceModelItem namespace_item)
e78566595089 initial import
mandel
parents:
diff changeset
576 {
e78566595089 initial import
mandel
parents:
diff changeset
577 QString namespace_name = (!m_namespace_prefix.isEmpty() ? m_namespace_prefix + "::" : QString()) + namespace_item->name();
e78566595089 initial import
mandel
parents:
diff changeset
578 NamespaceTypeEntry *type = TypeDatabase::instance()->findNamespaceType(namespace_name);
e78566595089 initial import
mandel
parents:
diff changeset
579
e78566595089 initial import
mandel
parents:
diff changeset
580 if (TypeDatabase::instance()->isClassRejected(namespace_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
581 m_rejected_classes.insert(namespace_name, GenerationDisabled);
e78566595089 initial import
mandel
parents:
diff changeset
582 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
583 }
e78566595089 initial import
mandel
parents:
diff changeset
584
e78566595089 initial import
mandel
parents:
diff changeset
585 if (!type) {
e78566595089 initial import
mandel
parents:
diff changeset
586 ReportHandler::warning(QString("namespace '%1' does not have a type entry")
e78566595089 initial import
mandel
parents:
diff changeset
587 .arg(namespace_name));
e78566595089 initial import
mandel
parents:
diff changeset
588 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
589 }
e78566595089 initial import
mandel
parents:
diff changeset
590
e78566595089 initial import
mandel
parents:
diff changeset
591 AbstractMetaClass *meta_class = createMetaClass();
e78566595089 initial import
mandel
parents:
diff changeset
592 meta_class->setTypeEntry(type);
e78566595089 initial import
mandel
parents:
diff changeset
593
e78566595089 initial import
mandel
parents:
diff changeset
594 *meta_class += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
595
e78566595089 initial import
mandel
parents:
diff changeset
596 m_current_class = meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
597
e78566595089 initial import
mandel
parents:
diff changeset
598 ReportHandler::debugSparse(QString("namespace '%1.%2'")
e78566595089 initial import
mandel
parents:
diff changeset
599 .arg(meta_class->package())
e78566595089 initial import
mandel
parents:
diff changeset
600 .arg(namespace_item->name()));
e78566595089 initial import
mandel
parents:
diff changeset
601
e78566595089 initial import
mandel
parents:
diff changeset
602 traverseEnums(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class, namespace_item->enumsDeclarations());
e78566595089 initial import
mandel
parents:
diff changeset
603 traverseFunctions(model_dynamic_cast<ScopeModelItem>(namespace_item), meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
604 // traverseClasses(model_dynamic_cast<ScopeModelItem>(namespace_item));
e78566595089 initial import
mandel
parents:
diff changeset
605
e78566595089 initial import
mandel
parents:
diff changeset
606 pushScope(model_dynamic_cast<ScopeModelItem>(namespace_item));
e78566595089 initial import
mandel
parents:
diff changeset
607 m_namespace_prefix = currentScope()->qualifiedName().join("::");
e78566595089 initial import
mandel
parents:
diff changeset
608
e78566595089 initial import
mandel
parents:
diff changeset
609
e78566595089 initial import
mandel
parents:
diff changeset
610 ClassList classes = namespace_item->classes();
e78566595089 initial import
mandel
parents:
diff changeset
611 foreach (ClassModelItem cls, classes) {
e78566595089 initial import
mandel
parents:
diff changeset
612 AbstractMetaClass *mjc = traverseClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
613 addAbstractMetaClass(mjc);
e78566595089 initial import
mandel
parents:
diff changeset
614 }
e78566595089 initial import
mandel
parents:
diff changeset
615
e78566595089 initial import
mandel
parents:
diff changeset
616 // Go through all typedefs to see if we have defined any
e78566595089 initial import
mandel
parents:
diff changeset
617 // specific typedefs to be used as classes.
e78566595089 initial import
mandel
parents:
diff changeset
618 TypeAliasList typeAliases = namespace_item->typeAliases();
e78566595089 initial import
mandel
parents:
diff changeset
619 foreach (TypeAliasModelItem typeAlias, typeAliases) {
e78566595089 initial import
mandel
parents:
diff changeset
620 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
e78566595089 initial import
mandel
parents:
diff changeset
621 addAbstractMetaClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
622 }
e78566595089 initial import
mandel
parents:
diff changeset
623
e78566595089 initial import
mandel
parents:
diff changeset
624
e78566595089 initial import
mandel
parents:
diff changeset
625
e78566595089 initial import
mandel
parents:
diff changeset
626 // Traverse namespaces recursively
e78566595089 initial import
mandel
parents:
diff changeset
627 QList<NamespaceModelItem> inner_namespaces = namespace_item->namespaceMap().values();
e78566595089 initial import
mandel
parents:
diff changeset
628 foreach (const NamespaceModelItem &ni, inner_namespaces) {
e78566595089 initial import
mandel
parents:
diff changeset
629 AbstractMetaClass *mjc = traverseNamespace(ni);
e78566595089 initial import
mandel
parents:
diff changeset
630 addAbstractMetaClass(mjc);
e78566595089 initial import
mandel
parents:
diff changeset
631 }
e78566595089 initial import
mandel
parents:
diff changeset
632
e78566595089 initial import
mandel
parents:
diff changeset
633 m_current_class = 0;
e78566595089 initial import
mandel
parents:
diff changeset
634
e78566595089 initial import
mandel
parents:
diff changeset
635
e78566595089 initial import
mandel
parents:
diff changeset
636 popScope();
e78566595089 initial import
mandel
parents:
diff changeset
637 m_namespace_prefix = currentScope()->qualifiedName().join("::");
e78566595089 initial import
mandel
parents:
diff changeset
638
e78566595089 initial import
mandel
parents:
diff changeset
639 if (!type->include().isValid()) {
e78566595089 initial import
mandel
parents:
diff changeset
640 QFileInfo info(namespace_item->fileName());
e78566595089 initial import
mandel
parents:
diff changeset
641 type->setInclude(Include(Include::IncludePath, info.fileName()));
e78566595089 initial import
mandel
parents:
diff changeset
642 }
e78566595089 initial import
mandel
parents:
diff changeset
643
e78566595089 initial import
mandel
parents:
diff changeset
644 return meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
645 }
e78566595089 initial import
mandel
parents:
diff changeset
646
e78566595089 initial import
mandel
parents:
diff changeset
647 struct Operator
e78566595089 initial import
mandel
parents:
diff changeset
648 {
e78566595089 initial import
mandel
parents:
diff changeset
649 enum Type { Plus, ShiftLeft, None };
e78566595089 initial import
mandel
parents:
diff changeset
650
e78566595089 initial import
mandel
parents:
diff changeset
651 Operator() : type(None) { }
e78566595089 initial import
mandel
parents:
diff changeset
652
e78566595089 initial import
mandel
parents:
diff changeset
653 int calculate(int x) {
e78566595089 initial import
mandel
parents:
diff changeset
654 switch (type) {
e78566595089 initial import
mandel
parents:
diff changeset
655 case Plus: return x + value;
e78566595089 initial import
mandel
parents:
diff changeset
656 case ShiftLeft: return x << value;
e78566595089 initial import
mandel
parents:
diff changeset
657 case None: return x;
e78566595089 initial import
mandel
parents:
diff changeset
658 }
e78566595089 initial import
mandel
parents:
diff changeset
659 return x;
e78566595089 initial import
mandel
parents:
diff changeset
660 }
e78566595089 initial import
mandel
parents:
diff changeset
661
e78566595089 initial import
mandel
parents:
diff changeset
662 Type type;
e78566595089 initial import
mandel
parents:
diff changeset
663 int value;
e78566595089 initial import
mandel
parents:
diff changeset
664 };
e78566595089 initial import
mandel
parents:
diff changeset
665
e78566595089 initial import
mandel
parents:
diff changeset
666
e78566595089 initial import
mandel
parents:
diff changeset
667
e78566595089 initial import
mandel
parents:
diff changeset
668 Operator findOperator(QString *s) {
e78566595089 initial import
mandel
parents:
diff changeset
669 const char *names[] = {
e78566595089 initial import
mandel
parents:
diff changeset
670 "+",
e78566595089 initial import
mandel
parents:
diff changeset
671 "<<"
e78566595089 initial import
mandel
parents:
diff changeset
672 };
e78566595089 initial import
mandel
parents:
diff changeset
673
e78566595089 initial import
mandel
parents:
diff changeset
674 for (int i=0; i<Operator::None; ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
675 QString name = QLatin1String(names[i]);
e78566595089 initial import
mandel
parents:
diff changeset
676 QString str = *s;
e78566595089 initial import
mandel
parents:
diff changeset
677 int splitPoint = str.indexOf(name);
e78566595089 initial import
mandel
parents:
diff changeset
678 if (splitPoint > 0) {
e78566595089 initial import
mandel
parents:
diff changeset
679 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
680 QString right = str.mid(splitPoint + name.length());
e78566595089 initial import
mandel
parents:
diff changeset
681 Operator op;
e78566595089 initial import
mandel
parents:
diff changeset
682 op.value = right.toInt(&ok);
e78566595089 initial import
mandel
parents:
diff changeset
683 if (ok) {
e78566595089 initial import
mandel
parents:
diff changeset
684 op.type = Operator::Type(i);
e78566595089 initial import
mandel
parents:
diff changeset
685 *s = str.left(splitPoint).trimmed();
e78566595089 initial import
mandel
parents:
diff changeset
686 return op;
e78566595089 initial import
mandel
parents:
diff changeset
687 }
e78566595089 initial import
mandel
parents:
diff changeset
688 }
e78566595089 initial import
mandel
parents:
diff changeset
689 }
e78566595089 initial import
mandel
parents:
diff changeset
690 return Operator();
e78566595089 initial import
mandel
parents:
diff changeset
691 }
e78566595089 initial import
mandel
parents:
diff changeset
692
e78566595089 initial import
mandel
parents:
diff changeset
693 int AbstractMetaBuilder::figureOutEnumValue(const QString &stringValue,
e78566595089 initial import
mandel
parents:
diff changeset
694 int oldValuevalue,
e78566595089 initial import
mandel
parents:
diff changeset
695 AbstractMetaEnum *meta_enum,
e78566595089 initial import
mandel
parents:
diff changeset
696 AbstractMetaFunction *meta_function)
e78566595089 initial import
mandel
parents:
diff changeset
697 {
e78566595089 initial import
mandel
parents:
diff changeset
698 if (stringValue.isEmpty())
e78566595089 initial import
mandel
parents:
diff changeset
699 return oldValuevalue;
e78566595089 initial import
mandel
parents:
diff changeset
700
e78566595089 initial import
mandel
parents:
diff changeset
701 QStringList stringValues = stringValue.split("|");
e78566595089 initial import
mandel
parents:
diff changeset
702
e78566595089 initial import
mandel
parents:
diff changeset
703 int returnValue = 0;
e78566595089 initial import
mandel
parents:
diff changeset
704
e78566595089 initial import
mandel
parents:
diff changeset
705 bool matched = false;
e78566595089 initial import
mandel
parents:
diff changeset
706
e78566595089 initial import
mandel
parents:
diff changeset
707 for (int i=0; i<stringValues.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
708 QString s = stringValues.at(i).trimmed();
e78566595089 initial import
mandel
parents:
diff changeset
709
e78566595089 initial import
mandel
parents:
diff changeset
710 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
711 int v;
e78566595089 initial import
mandel
parents:
diff changeset
712
e78566595089 initial import
mandel
parents:
diff changeset
713 Operator op = findOperator(&s);
e78566595089 initial import
mandel
parents:
diff changeset
714
e78566595089 initial import
mandel
parents:
diff changeset
715 if (s.length() > 0 && s.at(0) == QLatin1Char('0'))
e78566595089 initial import
mandel
parents:
diff changeset
716 v = s.toUInt(&ok, 0);
e78566595089 initial import
mandel
parents:
diff changeset
717 else
e78566595089 initial import
mandel
parents:
diff changeset
718 v = s.toInt(&ok);
e78566595089 initial import
mandel
parents:
diff changeset
719
e78566595089 initial import
mandel
parents:
diff changeset
720 if (ok) {
e78566595089 initial import
mandel
parents:
diff changeset
721 matched = true;
e78566595089 initial import
mandel
parents:
diff changeset
722
e78566595089 initial import
mandel
parents:
diff changeset
723 } else if (m_enum_values.contains(s)) {
e78566595089 initial import
mandel
parents:
diff changeset
724 v = m_enum_values[s]->value();
e78566595089 initial import
mandel
parents:
diff changeset
725 matched = true;
e78566595089 initial import
mandel
parents:
diff changeset
726
e78566595089 initial import
mandel
parents:
diff changeset
727 } else {
e78566595089 initial import
mandel
parents:
diff changeset
728 AbstractMetaEnumValue *ev = 0;
e78566595089 initial import
mandel
parents:
diff changeset
729
e78566595089 initial import
mandel
parents:
diff changeset
730 if (meta_enum && (ev = meta_enum->values().find(s))) {
e78566595089 initial import
mandel
parents:
diff changeset
731 v = ev->value();
e78566595089 initial import
mandel
parents:
diff changeset
732 matched = true;
e78566595089 initial import
mandel
parents:
diff changeset
733
e78566595089 initial import
mandel
parents:
diff changeset
734 } else if (meta_enum && (ev = meta_enum->enclosingClass()->findEnumValue(s, meta_enum))) {
e78566595089 initial import
mandel
parents:
diff changeset
735 v = ev->value();
e78566595089 initial import
mandel
parents:
diff changeset
736 matched = true;
e78566595089 initial import
mandel
parents:
diff changeset
737
e78566595089 initial import
mandel
parents:
diff changeset
738 } else {
e78566595089 initial import
mandel
parents:
diff changeset
739 if (meta_enum)
e78566595089 initial import
mandel
parents:
diff changeset
740 ReportHandler::warning("unhandled enum value: " + s + " in "
e78566595089 initial import
mandel
parents:
diff changeset
741 + meta_enum->enclosingClass()->name() + "::"
e78566595089 initial import
mandel
parents:
diff changeset
742 + meta_enum->name());
e78566595089 initial import
mandel
parents:
diff changeset
743 else
e78566595089 initial import
mandel
parents:
diff changeset
744 ReportHandler::warning("unhandled enum value: Unknown enum");
e78566595089 initial import
mandel
parents:
diff changeset
745 }
e78566595089 initial import
mandel
parents:
diff changeset
746 }
e78566595089 initial import
mandel
parents:
diff changeset
747
e78566595089 initial import
mandel
parents:
diff changeset
748 if (matched)
e78566595089 initial import
mandel
parents:
diff changeset
749 returnValue |= op.calculate(v);
e78566595089 initial import
mandel
parents:
diff changeset
750 }
e78566595089 initial import
mandel
parents:
diff changeset
751
e78566595089 initial import
mandel
parents:
diff changeset
752 if (!matched) {
e78566595089 initial import
mandel
parents:
diff changeset
753 QString warn = QString("unmatched enum %1").arg(stringValue);
e78566595089 initial import
mandel
parents:
diff changeset
754
e78566595089 initial import
mandel
parents:
diff changeset
755 if (meta_function != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
756 warn += QString(" when parsing default value of '%1' in class '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
757 .arg(meta_function->name())
e78566595089 initial import
mandel
parents:
diff changeset
758 .arg(meta_function->implementingClass()->name());
e78566595089 initial import
mandel
parents:
diff changeset
759 }
e78566595089 initial import
mandel
parents:
diff changeset
760
e78566595089 initial import
mandel
parents:
diff changeset
761 ReportHandler::warning(warn);
e78566595089 initial import
mandel
parents:
diff changeset
762 returnValue = oldValuevalue;
e78566595089 initial import
mandel
parents:
diff changeset
763 }
e78566595089 initial import
mandel
parents:
diff changeset
764
e78566595089 initial import
mandel
parents:
diff changeset
765 return returnValue;
e78566595089 initial import
mandel
parents:
diff changeset
766 }
e78566595089 initial import
mandel
parents:
diff changeset
767
e78566595089 initial import
mandel
parents:
diff changeset
768 void AbstractMetaBuilder::figureOutEnumValuesForClass(AbstractMetaClass *meta_class,
e78566595089 initial import
mandel
parents:
diff changeset
769 QSet<AbstractMetaClass *> *classes)
e78566595089 initial import
mandel
parents:
diff changeset
770 {
e78566595089 initial import
mandel
parents:
diff changeset
771 AbstractMetaClass *base = meta_class->baseClass();
e78566595089 initial import
mandel
parents:
diff changeset
772
e78566595089 initial import
mandel
parents:
diff changeset
773 if (base != 0 && !classes->contains(base))
e78566595089 initial import
mandel
parents:
diff changeset
774 figureOutEnumValuesForClass(base, classes);
e78566595089 initial import
mandel
parents:
diff changeset
775
e78566595089 initial import
mandel
parents:
diff changeset
776 if (classes->contains(meta_class))
e78566595089 initial import
mandel
parents:
diff changeset
777 return;
e78566595089 initial import
mandel
parents:
diff changeset
778
e78566595089 initial import
mandel
parents:
diff changeset
779 AbstractMetaEnumList enums = meta_class->enums();
e78566595089 initial import
mandel
parents:
diff changeset
780 foreach (AbstractMetaEnum *e, enums) {
e78566595089 initial import
mandel
parents:
diff changeset
781 if (!e)
e78566595089 initial import
mandel
parents:
diff changeset
782 ReportHandler::warning("bad enum in class " + meta_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
783 AbstractMetaEnumValueList lst = e->values();
e78566595089 initial import
mandel
parents:
diff changeset
784 int value = 0;
e78566595089 initial import
mandel
parents:
diff changeset
785 for (int i=0; i<lst.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
786 value = figureOutEnumValue(lst.at(i)->stringValue(), value, e);
e78566595089 initial import
mandel
parents:
diff changeset
787 lst.at(i)->setValue(value);
e78566595089 initial import
mandel
parents:
diff changeset
788 value++;
e78566595089 initial import
mandel
parents:
diff changeset
789 }
e78566595089 initial import
mandel
parents:
diff changeset
790
e78566595089 initial import
mandel
parents:
diff changeset
791 // Check for duplicate values...
e78566595089 initial import
mandel
parents:
diff changeset
792 EnumTypeEntry *ete = e->typeEntry();
e78566595089 initial import
mandel
parents:
diff changeset
793 if (!ete->forceInteger()) {
e78566595089 initial import
mandel
parents:
diff changeset
794 QHash<int, AbstractMetaEnumValue *> entries;
e78566595089 initial import
mandel
parents:
diff changeset
795 foreach (AbstractMetaEnumValue *v, lst) {
e78566595089 initial import
mandel
parents:
diff changeset
796
e78566595089 initial import
mandel
parents:
diff changeset
797 bool vRejected = ete->isEnumValueRejected(v->name());
e78566595089 initial import
mandel
parents:
diff changeset
798
e78566595089 initial import
mandel
parents:
diff changeset
799 AbstractMetaEnumValue *current = entries.value(v->value());
e78566595089 initial import
mandel
parents:
diff changeset
800 if (current) {
e78566595089 initial import
mandel
parents:
diff changeset
801 bool currentRejected = ete->isEnumValueRejected(current->name());
e78566595089 initial import
mandel
parents:
diff changeset
802 if (!currentRejected && !vRejected) {
e78566595089 initial import
mandel
parents:
diff changeset
803 ReportHandler::warning(
e78566595089 initial import
mandel
parents:
diff changeset
804 QString("duplicate enum values: %1::%2, %3 and %4 are %5, already rejected: (%6)")
e78566595089 initial import
mandel
parents:
diff changeset
805 .arg(meta_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
806 .arg(e->name())
e78566595089 initial import
mandel
parents:
diff changeset
807 .arg(v->name())
e78566595089 initial import
mandel
parents:
diff changeset
808 .arg(entries[v->value()]->name())
e78566595089 initial import
mandel
parents:
diff changeset
809 .arg(v->value())
e78566595089 initial import
mandel
parents:
diff changeset
810 .arg(ete->enumValueRejections().join(", ")));
e78566595089 initial import
mandel
parents:
diff changeset
811 continue;
e78566595089 initial import
mandel
parents:
diff changeset
812 }
e78566595089 initial import
mandel
parents:
diff changeset
813 }
e78566595089 initial import
mandel
parents:
diff changeset
814
e78566595089 initial import
mandel
parents:
diff changeset
815 if (!vRejected)
e78566595089 initial import
mandel
parents:
diff changeset
816 entries[v->value()] = v;
e78566595089 initial import
mandel
parents:
diff changeset
817 }
e78566595089 initial import
mandel
parents:
diff changeset
818
e78566595089 initial import
mandel
parents:
diff changeset
819 // Entries now contain all the original entries, no
e78566595089 initial import
mandel
parents:
diff changeset
820 // rejected ones... Use this to generate the enumValueRedirection table.
e78566595089 initial import
mandel
parents:
diff changeset
821 foreach (AbstractMetaEnumValue *reject, lst) {
e78566595089 initial import
mandel
parents:
diff changeset
822 if (!ete->isEnumValueRejected(reject->name()))
e78566595089 initial import
mandel
parents:
diff changeset
823 continue;
e78566595089 initial import
mandel
parents:
diff changeset
824
e78566595089 initial import
mandel
parents:
diff changeset
825 AbstractMetaEnumValue *used = entries.value(reject->value());
e78566595089 initial import
mandel
parents:
diff changeset
826 if (!used) {
e78566595089 initial import
mandel
parents:
diff changeset
827 ReportHandler::warning(
e78566595089 initial import
mandel
parents:
diff changeset
828 QString::fromLatin1("Rejected enum has no alternative...: %1::%2\n")
e78566595089 initial import
mandel
parents:
diff changeset
829 .arg(meta_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
830 .arg(reject->name()));
e78566595089 initial import
mandel
parents:
diff changeset
831 continue;
e78566595089 initial import
mandel
parents:
diff changeset
832 }
e78566595089 initial import
mandel
parents:
diff changeset
833 ete->addEnumValueRedirection(reject->name(), used->name());
e78566595089 initial import
mandel
parents:
diff changeset
834 }
e78566595089 initial import
mandel
parents:
diff changeset
835
e78566595089 initial import
mandel
parents:
diff changeset
836 }
e78566595089 initial import
mandel
parents:
diff changeset
837 }
e78566595089 initial import
mandel
parents:
diff changeset
838
e78566595089 initial import
mandel
parents:
diff changeset
839
e78566595089 initial import
mandel
parents:
diff changeset
840
e78566595089 initial import
mandel
parents:
diff changeset
841 *classes += meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
842 }
e78566595089 initial import
mandel
parents:
diff changeset
843
e78566595089 initial import
mandel
parents:
diff changeset
844
e78566595089 initial import
mandel
parents:
diff changeset
845 void AbstractMetaBuilder::figureOutEnumValues()
e78566595089 initial import
mandel
parents:
diff changeset
846 {
e78566595089 initial import
mandel
parents:
diff changeset
847 // Keep a set of classes that we already traversed. We use this to
e78566595089 initial import
mandel
parents:
diff changeset
848 // enforce that we traverse base classes prior to subclasses.
e78566595089 initial import
mandel
parents:
diff changeset
849 QSet<AbstractMetaClass *> classes;
e78566595089 initial import
mandel
parents:
diff changeset
850 foreach (AbstractMetaClass *c, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
851 figureOutEnumValuesForClass(c, &classes);
e78566595089 initial import
mandel
parents:
diff changeset
852 }
e78566595089 initial import
mandel
parents:
diff changeset
853 }
e78566595089 initial import
mandel
parents:
diff changeset
854
e78566595089 initial import
mandel
parents:
diff changeset
855 void AbstractMetaBuilder::figureOutDefaultEnumArguments()
e78566595089 initial import
mandel
parents:
diff changeset
856 {
e78566595089 initial import
mandel
parents:
diff changeset
857 foreach (AbstractMetaClass *meta_class, m_meta_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
858 foreach (AbstractMetaFunction *meta_function, meta_class->functions()) {
e78566595089 initial import
mandel
parents:
diff changeset
859 foreach (AbstractMetaArgument *arg, meta_function->arguments()) {
e78566595089 initial import
mandel
parents:
diff changeset
860
e78566595089 initial import
mandel
parents:
diff changeset
861 QString expr = arg->defaultValueExpression();
e78566595089 initial import
mandel
parents:
diff changeset
862 if (expr.isEmpty())
e78566595089 initial import
mandel
parents:
diff changeset
863 continue;
e78566595089 initial import
mandel
parents:
diff changeset
864
e78566595089 initial import
mandel
parents:
diff changeset
865 if (!meta_function->replacedDefaultExpression(meta_function->implementingClass(),
e78566595089 initial import
mandel
parents:
diff changeset
866 arg->argumentIndex()+1).isEmpty()) {
e78566595089 initial import
mandel
parents:
diff changeset
867 continue;
e78566595089 initial import
mandel
parents:
diff changeset
868 }
e78566595089 initial import
mandel
parents:
diff changeset
869
e78566595089 initial import
mandel
parents:
diff changeset
870 QString new_expr = expr;
e78566595089 initial import
mandel
parents:
diff changeset
871 if (arg->type()->isEnum()) {
e78566595089 initial import
mandel
parents:
diff changeset
872 QStringList lst = expr.split(QLatin1String("::"));
e78566595089 initial import
mandel
parents:
diff changeset
873 if (lst.size() == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
874 QVector<AbstractMetaClass *> classes(1, meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
875 AbstractMetaEnum *e = 0;
e78566595089 initial import
mandel
parents:
diff changeset
876 while (!classes.isEmpty() && e == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
877 if (classes.front() != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
878 classes << classes.front()->baseClass();
e78566595089 initial import
mandel
parents:
diff changeset
879
e78566595089 initial import
mandel
parents:
diff changeset
880 AbstractMetaClassList interfaces = classes.front()->interfaces();
e78566595089 initial import
mandel
parents:
diff changeset
881 foreach (AbstractMetaClass *interface, interfaces)
e78566595089 initial import
mandel
parents:
diff changeset
882 classes << interface->primaryInterfaceImplementor();
e78566595089 initial import
mandel
parents:
diff changeset
883
e78566595089 initial import
mandel
parents:
diff changeset
884 e = classes.front()->findEnumForValue(expr);
e78566595089 initial import
mandel
parents:
diff changeset
885 }
e78566595089 initial import
mandel
parents:
diff changeset
886
e78566595089 initial import
mandel
parents:
diff changeset
887 classes.pop_front();
e78566595089 initial import
mandel
parents:
diff changeset
888 }
e78566595089 initial import
mandel
parents:
diff changeset
889
e78566595089 initial import
mandel
parents:
diff changeset
890 if (e != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
891 /* qtd new_expr = QString("%1.%2")
e78566595089 initial import
mandel
parents:
diff changeset
892 .arg(e->typeEntry()->qualifiedTargetLangName())
e78566595089 initial import
mandel
parents:
diff changeset
893 .arg(expr);
e78566595089 initial import
mandel
parents:
diff changeset
894 */
e78566595089 initial import
mandel
parents:
diff changeset
895 // new_expr = arg->type()->typeEntry()->targetLangName() + "." + expr;
e78566595089 initial import
mandel
parents:
diff changeset
896 new_expr = arg->type()->typeEntry()->qualifiedTargetLangName() + "." + expr;
e78566595089 initial import
mandel
parents:
diff changeset
897 } else {
e78566595089 initial import
mandel
parents:
diff changeset
898 ReportHandler::warning("Cannot find enum constant for value '" + expr + "' in '" + meta_class->name() + "' or any of its super classes");
e78566595089 initial import
mandel
parents:
diff changeset
899 }
e78566595089 initial import
mandel
parents:
diff changeset
900 } else if (lst.size() == 2) {
e78566595089 initial import
mandel
parents:
diff changeset
901 AbstractMetaClass *cl = m_meta_classes.findClass(lst.at(0));
e78566595089 initial import
mandel
parents:
diff changeset
902 if (!cl) {
e78566595089 initial import
mandel
parents:
diff changeset
903 ReportHandler::warning("missing required class for enums: " + lst.at(0));
e78566595089 initial import
mandel
parents:
diff changeset
904 continue;
e78566595089 initial import
mandel
parents:
diff changeset
905 }
e78566595089 initial import
mandel
parents:
diff changeset
906 /* qtd new_expr = QString("%1.%2.%3")
e78566595089 initial import
mandel
parents:
diff changeset
907 .arg(cl->typeEntry()->qualifiedTargetLangName())
e78566595089 initial import
mandel
parents:
diff changeset
908 .arg(arg->type()->name())
e78566595089 initial import
mandel
parents:
diff changeset
909 .arg(lst.at(1));
e78566595089 initial import
mandel
parents:
diff changeset
910 */
e78566595089 initial import
mandel
parents:
diff changeset
911 // new_expr = arg->type()->typeEntry()->targetLangName() + "." + lst.at(1);
e78566595089 initial import
mandel
parents:
diff changeset
912 new_expr = arg->type()->typeEntry()->qualifiedTargetLangName() + "." + lst.at(1);
e78566595089 initial import
mandel
parents:
diff changeset
913 } else {
e78566595089 initial import
mandel
parents:
diff changeset
914 ReportHandler::warning("bad default value passed to enum " + expr);
e78566595089 initial import
mandel
parents:
diff changeset
915 }
e78566595089 initial import
mandel
parents:
diff changeset
916
e78566595089 initial import
mandel
parents:
diff changeset
917 } else if(arg->type()->isFlags()) {
e78566595089 initial import
mandel
parents:
diff changeset
918 const FlagsTypeEntry *flagsEntry =
e78566595089 initial import
mandel
parents:
diff changeset
919 static_cast<const FlagsTypeEntry *>(arg->type()->typeEntry());
e78566595089 initial import
mandel
parents:
diff changeset
920 EnumTypeEntry *enumEntry = flagsEntry->originator();
e78566595089 initial import
mandel
parents:
diff changeset
921 AbstractMetaEnum *meta_enum = m_meta_classes.findEnum(enumEntry);
e78566595089 initial import
mandel
parents:
diff changeset
922 if (!meta_enum) {
e78566595089 initial import
mandel
parents:
diff changeset
923 ReportHandler::warning("unknown required enum " + enumEntry->qualifiedCppName());
e78566595089 initial import
mandel
parents:
diff changeset
924 continue;
e78566595089 initial import
mandel
parents:
diff changeset
925 }
e78566595089 initial import
mandel
parents:
diff changeset
926
e78566595089 initial import
mandel
parents:
diff changeset
927 int value = figureOutEnumValue(expr, 0, meta_enum, meta_function);
e78566595089 initial import
mandel
parents:
diff changeset
928 new_expr = QString::number(value);
e78566595089 initial import
mandel
parents:
diff changeset
929
e78566595089 initial import
mandel
parents:
diff changeset
930 } else if (arg->type()->isPrimitive()) {
e78566595089 initial import
mandel
parents:
diff changeset
931 AbstractMetaEnumValue *value = 0;
e78566595089 initial import
mandel
parents:
diff changeset
932 if (expr.contains("::"))
e78566595089 initial import
mandel
parents:
diff changeset
933 value = m_meta_classes.findEnumValue(expr);
e78566595089 initial import
mandel
parents:
diff changeset
934 if (!value)
e78566595089 initial import
mandel
parents:
diff changeset
935 value = meta_class->findEnumValue(expr, 0);
e78566595089 initial import
mandel
parents:
diff changeset
936
e78566595089 initial import
mandel
parents:
diff changeset
937 if (value) {
e78566595089 initial import
mandel
parents:
diff changeset
938 new_expr = QString::number(value->value());
e78566595089 initial import
mandel
parents:
diff changeset
939 } else if (expr.contains(QLatin1Char('+'))) {
e78566595089 initial import
mandel
parents:
diff changeset
940 new_expr = QString::number(figureOutEnumValue(expr, 0, 0));
e78566595089 initial import
mandel
parents:
diff changeset
941
e78566595089 initial import
mandel
parents:
diff changeset
942 }
e78566595089 initial import
mandel
parents:
diff changeset
943
e78566595089 initial import
mandel
parents:
diff changeset
944
e78566595089 initial import
mandel
parents:
diff changeset
945
e78566595089 initial import
mandel
parents:
diff changeset
946 }
e78566595089 initial import
mandel
parents:
diff changeset
947
e78566595089 initial import
mandel
parents:
diff changeset
948 arg->setDefaultValueExpression(new_expr);
e78566595089 initial import
mandel
parents:
diff changeset
949 }
e78566595089 initial import
mandel
parents:
diff changeset
950 }
e78566595089 initial import
mandel
parents:
diff changeset
951 }
e78566595089 initial import
mandel
parents:
diff changeset
952 }
e78566595089 initial import
mandel
parents:
diff changeset
953
e78566595089 initial import
mandel
parents:
diff changeset
954
e78566595089 initial import
mandel
parents:
diff changeset
955 AbstractMetaEnum *AbstractMetaBuilder::traverseEnum(EnumModelItem enum_item, AbstractMetaClass *enclosing, const QSet<QString> &enumsDeclarations)
e78566595089 initial import
mandel
parents:
diff changeset
956 {
e78566595089 initial import
mandel
parents:
diff changeset
957 // Skipping private enums.
e78566595089 initial import
mandel
parents:
diff changeset
958 if (enum_item->accessPolicy() == CodeModel::Private) {
e78566595089 initial import
mandel
parents:
diff changeset
959 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
960 }
e78566595089 initial import
mandel
parents:
diff changeset
961
e78566595089 initial import
mandel
parents:
diff changeset
962 QString qualified_name = enum_item->qualifiedName().join("::");
e78566595089 initial import
mandel
parents:
diff changeset
963
e78566595089 initial import
mandel
parents:
diff changeset
964 TypeEntry *type_entry = TypeDatabase::instance()->findType(qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
965 QString enum_name = enum_item->name();
e78566595089 initial import
mandel
parents:
diff changeset
966
e78566595089 initial import
mandel
parents:
diff changeset
967 QString class_name;
e78566595089 initial import
mandel
parents:
diff changeset
968 if (m_current_class)
e78566595089 initial import
mandel
parents:
diff changeset
969 class_name = m_current_class->typeEntry()->qualifiedCppName();
e78566595089 initial import
mandel
parents:
diff changeset
970
e78566595089 initial import
mandel
parents:
diff changeset
971 if (TypeDatabase::instance()->isEnumRejected(class_name, enum_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
972 m_rejected_enums.insert(qualified_name, GenerationDisabled);
e78566595089 initial import
mandel
parents:
diff changeset
973 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
974 }
e78566595089 initial import
mandel
parents:
diff changeset
975
e78566595089 initial import
mandel
parents:
diff changeset
976 if (!type_entry || !type_entry->isEnum()) {
e78566595089 initial import
mandel
parents:
diff changeset
977 QString context = m_current_class ? m_current_class->name() : QLatin1String("");
e78566595089 initial import
mandel
parents:
diff changeset
978 ReportHandler::warning(QString("enum '%1' does not have a type entry or is not an enum")
e78566595089 initial import
mandel
parents:
diff changeset
979 .arg(qualified_name));
e78566595089 initial import
mandel
parents:
diff changeset
980 m_rejected_enums.insert(qualified_name, NotInTypeSystem);
e78566595089 initial import
mandel
parents:
diff changeset
981 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
982 }
e78566595089 initial import
mandel
parents:
diff changeset
983
e78566595089 initial import
mandel
parents:
diff changeset
984 AbstractMetaEnum *meta_enum = createMetaEnum();
e78566595089 initial import
mandel
parents:
diff changeset
985 if ( enumsDeclarations.contains(qualified_name)
e78566595089 initial import
mandel
parents:
diff changeset
986 || enumsDeclarations.contains(enum_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
987 meta_enum->setHasQEnumsDeclaration(true);
e78566595089 initial import
mandel
parents:
diff changeset
988 }
e78566595089 initial import
mandel
parents:
diff changeset
989
e78566595089 initial import
mandel
parents:
diff changeset
990 meta_enum->setTypeEntry((EnumTypeEntry *) type_entry);
e78566595089 initial import
mandel
parents:
diff changeset
991 switch (enum_item->accessPolicy()) {
e78566595089 initial import
mandel
parents:
diff changeset
992 case CodeModel::Public: *meta_enum += AbstractMetaAttributes::Public; break;
e78566595089 initial import
mandel
parents:
diff changeset
993 case CodeModel::Protected: *meta_enum += AbstractMetaAttributes::Protected; break;
e78566595089 initial import
mandel
parents:
diff changeset
994 // case CodeModel::Private: *meta_enum += AbstractMetaAttributes::Private; break;
e78566595089 initial import
mandel
parents:
diff changeset
995 default: break;
e78566595089 initial import
mandel
parents:
diff changeset
996 }
e78566595089 initial import
mandel
parents:
diff changeset
997
e78566595089 initial import
mandel
parents:
diff changeset
998 ReportHandler::debugMedium(QString(" - traversing enum %1").arg(meta_enum->fullName()));
e78566595089 initial import
mandel
parents:
diff changeset
999
e78566595089 initial import
mandel
parents:
diff changeset
1000 foreach (EnumeratorModelItem value, enum_item->enumerators()) {
e78566595089 initial import
mandel
parents:
diff changeset
1001
e78566595089 initial import
mandel
parents:
diff changeset
1002 AbstractMetaEnumValue *meta_enum_value = createMetaEnumValue();
e78566595089 initial import
mandel
parents:
diff changeset
1003 meta_enum_value->setName(value->name());
e78566595089 initial import
mandel
parents:
diff changeset
1004 // Deciding the enum value...
e78566595089 initial import
mandel
parents:
diff changeset
1005
e78566595089 initial import
mandel
parents:
diff changeset
1006 meta_enum_value->setStringValue(value->value());
e78566595089 initial import
mandel
parents:
diff changeset
1007 meta_enum->addEnumValue(meta_enum_value);
e78566595089 initial import
mandel
parents:
diff changeset
1008
e78566595089 initial import
mandel
parents:
diff changeset
1009 ReportHandler::debugFull(" - " + meta_enum_value->name() + " = "
e78566595089 initial import
mandel
parents:
diff changeset
1010 + meta_enum_value->value());
e78566595089 initial import
mandel
parents:
diff changeset
1011
e78566595089 initial import
mandel
parents:
diff changeset
1012 // Add into global register...
e78566595089 initial import
mandel
parents:
diff changeset
1013 if (enclosing)
e78566595089 initial import
mandel
parents:
diff changeset
1014 m_enum_values[enclosing->name() + "::" + meta_enum_value->name()] = meta_enum_value;
e78566595089 initial import
mandel
parents:
diff changeset
1015 else
e78566595089 initial import
mandel
parents:
diff changeset
1016 m_enum_values[meta_enum_value->name()] = meta_enum_value;
e78566595089 initial import
mandel
parents:
diff changeset
1017 }
e78566595089 initial import
mandel
parents:
diff changeset
1018
e78566595089 initial import
mandel
parents:
diff changeset
1019 m_enums << meta_enum;
e78566595089 initial import
mandel
parents:
diff changeset
1020
e78566595089 initial import
mandel
parents:
diff changeset
1021 return meta_enum;
e78566595089 initial import
mandel
parents:
diff changeset
1022 }
e78566595089 initial import
mandel
parents:
diff changeset
1023
e78566595089 initial import
mandel
parents:
diff changeset
1024 AbstractMetaClass *AbstractMetaBuilder::traverseTypeAlias(TypeAliasModelItem typeAlias)
e78566595089 initial import
mandel
parents:
diff changeset
1025 {
e78566595089 initial import
mandel
parents:
diff changeset
1026 QString class_name = strip_template_args(typeAlias->name());
e78566595089 initial import
mandel
parents:
diff changeset
1027
e78566595089 initial import
mandel
parents:
diff changeset
1028 QString full_class_name = class_name;
e78566595089 initial import
mandel
parents:
diff changeset
1029 // we have an inner class
e78566595089 initial import
mandel
parents:
diff changeset
1030 if (m_current_class) {
e78566595089 initial import
mandel
parents:
diff changeset
1031 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
e78566595089 initial import
mandel
parents:
diff changeset
1032 + "::" + full_class_name;
e78566595089 initial import
mandel
parents:
diff changeset
1033 }
e78566595089 initial import
mandel
parents:
diff changeset
1034
e78566595089 initial import
mandel
parents:
diff changeset
1035 // If we haven't specified anything for the typedef, then we don't care
e78566595089 initial import
mandel
parents:
diff changeset
1036 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
e78566595089 initial import
mandel
parents:
diff changeset
1037 if (type == 0)
e78566595089 initial import
mandel
parents:
diff changeset
1038 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1039
e78566595089 initial import
mandel
parents:
diff changeset
1040 if (type->isObject())
e78566595089 initial import
mandel
parents:
diff changeset
1041 static_cast<ObjectTypeEntry *>(type)->setQObject(isQObject(strip_template_args(typeAlias->type().qualifiedName().join("::"))));
e78566595089 initial import
mandel
parents:
diff changeset
1042
e78566595089 initial import
mandel
parents:
diff changeset
1043 AbstractMetaClass *meta_class = createMetaClass();
e78566595089 initial import
mandel
parents:
diff changeset
1044 meta_class->setTypeAlias(true);
e78566595089 initial import
mandel
parents:
diff changeset
1045 meta_class->setTypeEntry(type);
e78566595089 initial import
mandel
parents:
diff changeset
1046 meta_class->setBaseClassNames(QStringList() << typeAlias->type().qualifiedName().join("::"));
e78566595089 initial import
mandel
parents:
diff changeset
1047 *meta_class += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
1048
e78566595089 initial import
mandel
parents:
diff changeset
1049 // Set the default include file name
e78566595089 initial import
mandel
parents:
diff changeset
1050 if (!type->include().isValid()) {
e78566595089 initial import
mandel
parents:
diff changeset
1051 QFileInfo info(typeAlias->fileName());
e78566595089 initial import
mandel
parents:
diff changeset
1052 type->setInclude(Include(Include::IncludePath, info.fileName()));
e78566595089 initial import
mandel
parents:
diff changeset
1053 }
e78566595089 initial import
mandel
parents:
diff changeset
1054
e78566595089 initial import
mandel
parents:
diff changeset
1055 return meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
1056 }
e78566595089 initial import
mandel
parents:
diff changeset
1057
e78566595089 initial import
mandel
parents:
diff changeset
1058 AbstractMetaClass *AbstractMetaBuilder::traverseClass(ClassModelItem class_item)
e78566595089 initial import
mandel
parents:
diff changeset
1059 {
e78566595089 initial import
mandel
parents:
diff changeset
1060 QString class_name = strip_template_args(class_item->name());
e78566595089 initial import
mandel
parents:
diff changeset
1061 QString full_class_name = class_name;
e78566595089 initial import
mandel
parents:
diff changeset
1062
e78566595089 initial import
mandel
parents:
diff changeset
1063 // we have inner an class
e78566595089 initial import
mandel
parents:
diff changeset
1064 if (m_current_class) {
e78566595089 initial import
mandel
parents:
diff changeset
1065 full_class_name = strip_template_args(m_current_class->typeEntry()->qualifiedCppName())
e78566595089 initial import
mandel
parents:
diff changeset
1066 + "::" + full_class_name;
e78566595089 initial import
mandel
parents:
diff changeset
1067 }
e78566595089 initial import
mandel
parents:
diff changeset
1068
e78566595089 initial import
mandel
parents:
diff changeset
1069 ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(full_class_name);
e78566595089 initial import
mandel
parents:
diff changeset
1070 RejectReason reason = NoReason;
e78566595089 initial import
mandel
parents:
diff changeset
1071
e78566595089 initial import
mandel
parents:
diff changeset
1072
e78566595089 initial import
mandel
parents:
diff changeset
1073 if (TypeDatabase::instance()->isClassRejected(full_class_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
1074 reason = GenerationDisabled;
e78566595089 initial import
mandel
parents:
diff changeset
1075 } else if (!type) {
e78566595089 initial import
mandel
parents:
diff changeset
1076 TypeEntry *te = TypeDatabase::instance()->findType(full_class_name);
e78566595089 initial import
mandel
parents:
diff changeset
1077 if (te && !te->isComplex())
e78566595089 initial import
mandel
parents:
diff changeset
1078 reason = RedefinedToNotClass;
e78566595089 initial import
mandel
parents:
diff changeset
1079 else
e78566595089 initial import
mandel
parents:
diff changeset
1080 reason = NotInTypeSystem;
e78566595089 initial import
mandel
parents:
diff changeset
1081 } else if (type->codeGeneration() == TypeEntry::GenerateNothing) {
e78566595089 initial import
mandel
parents:
diff changeset
1082 reason = GenerationDisabled;
e78566595089 initial import
mandel
parents:
diff changeset
1083 }
e78566595089 initial import
mandel
parents:
diff changeset
1084
e78566595089 initial import
mandel
parents:
diff changeset
1085 if (reason != NoReason) {
e78566595089 initial import
mandel
parents:
diff changeset
1086 m_rejected_classes.insert(full_class_name, reason);
e78566595089 initial import
mandel
parents:
diff changeset
1087 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1088 }
e78566595089 initial import
mandel
parents:
diff changeset
1089
e78566595089 initial import
mandel
parents:
diff changeset
1090 if (type->isObject()) {
e78566595089 initial import
mandel
parents:
diff changeset
1091 ((ObjectTypeEntry *)type)->setQObject(isQObject(full_class_name));
e78566595089 initial import
mandel
parents:
diff changeset
1092 }
e78566595089 initial import
mandel
parents:
diff changeset
1093
e78566595089 initial import
mandel
parents:
diff changeset
1094 AbstractMetaClass *meta_class = createMetaClass();
e78566595089 initial import
mandel
parents:
diff changeset
1095 meta_class->setTypeEntry(type);
e78566595089 initial import
mandel
parents:
diff changeset
1096 meta_class->setBaseClassNames(class_item->baseClasses());
e78566595089 initial import
mandel
parents:
diff changeset
1097 *meta_class += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
1098
e78566595089 initial import
mandel
parents:
diff changeset
1099 AbstractMetaClass *old_current_class = m_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
1100 m_current_class = meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
1101
e78566595089 initial import
mandel
parents:
diff changeset
1102 if (type->isContainer()) {
e78566595089 initial import
mandel
parents:
diff changeset
1103 ReportHandler::debugSparse(QString("container: '%1'").arg(full_class_name));
e78566595089 initial import
mandel
parents:
diff changeset
1104 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1105 ReportHandler::debugSparse(QString("class: '%1'").arg(meta_class->fullName()));
e78566595089 initial import
mandel
parents:
diff changeset
1106 }
e78566595089 initial import
mandel
parents:
diff changeset
1107
e78566595089 initial import
mandel
parents:
diff changeset
1108 TemplateParameterList template_parameters = class_item->templateParameters();
e78566595089 initial import
mandel
parents:
diff changeset
1109 QList<TypeEntry *> template_args;
e78566595089 initial import
mandel
parents:
diff changeset
1110 template_args.clear();
e78566595089 initial import
mandel
parents:
diff changeset
1111 for (int i=0; i<template_parameters.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
1112 const TemplateParameterModelItem &param = template_parameters.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
1113 TemplateArgumentEntry *param_type = new TemplateArgumentEntry(param->name());
e78566595089 initial import
mandel
parents:
diff changeset
1114 param_type->setOrdinal(i);
e78566595089 initial import
mandel
parents:
diff changeset
1115 template_args.append(param_type);
e78566595089 initial import
mandel
parents:
diff changeset
1116 }
e78566595089 initial import
mandel
parents:
diff changeset
1117 meta_class->setTemplateArguments(template_args);
e78566595089 initial import
mandel
parents:
diff changeset
1118
e78566595089 initial import
mandel
parents:
diff changeset
1119 parseQ_Property(meta_class, class_item->propertyDeclarations());
e78566595089 initial import
mandel
parents:
diff changeset
1120
e78566595089 initial import
mandel
parents:
diff changeset
1121 traverseFunctions(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1122 traverseEnums(model_dynamic_cast<ScopeModelItem>(class_item), meta_class, class_item->enumsDeclarations());
e78566595089 initial import
mandel
parents:
diff changeset
1123 traverseFields(model_dynamic_cast<ScopeModelItem>(class_item), meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1124
e78566595089 initial import
mandel
parents:
diff changeset
1125 // Inner classes
e78566595089 initial import
mandel
parents:
diff changeset
1126 {
e78566595089 initial import
mandel
parents:
diff changeset
1127 QList<ClassModelItem> inner_classes = class_item->classMap().values();
e78566595089 initial import
mandel
parents:
diff changeset
1128 foreach (const ClassModelItem &ci, inner_classes) {
e78566595089 initial import
mandel
parents:
diff changeset
1129 AbstractMetaClass *cl = traverseClass(ci);
e78566595089 initial import
mandel
parents:
diff changeset
1130 if (cl) {
e78566595089 initial import
mandel
parents:
diff changeset
1131 cl->setEnclosingClass(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1132 m_meta_classes << cl;
e78566595089 initial import
mandel
parents:
diff changeset
1133 }
e78566595089 initial import
mandel
parents:
diff changeset
1134 }
e78566595089 initial import
mandel
parents:
diff changeset
1135
e78566595089 initial import
mandel
parents:
diff changeset
1136 }
e78566595089 initial import
mandel
parents:
diff changeset
1137
e78566595089 initial import
mandel
parents:
diff changeset
1138 // Go through all typedefs to see if we have defined any
e78566595089 initial import
mandel
parents:
diff changeset
1139 // specific typedefs to be used as classes.
e78566595089 initial import
mandel
parents:
diff changeset
1140 TypeAliasList typeAliases = class_item->typeAliases();
e78566595089 initial import
mandel
parents:
diff changeset
1141 foreach (TypeAliasModelItem typeAlias, typeAliases) {
e78566595089 initial import
mandel
parents:
diff changeset
1142 AbstractMetaClass *cls = traverseTypeAlias(typeAlias);
e78566595089 initial import
mandel
parents:
diff changeset
1143 if (cls != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1144 cls->setEnclosingClass(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1145 addAbstractMetaClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
1146 }
e78566595089 initial import
mandel
parents:
diff changeset
1147 }
e78566595089 initial import
mandel
parents:
diff changeset
1148
e78566595089 initial import
mandel
parents:
diff changeset
1149
e78566595089 initial import
mandel
parents:
diff changeset
1150 m_current_class = old_current_class;
e78566595089 initial import
mandel
parents:
diff changeset
1151
e78566595089 initial import
mandel
parents:
diff changeset
1152 // Set the default include file name
e78566595089 initial import
mandel
parents:
diff changeset
1153 if (!type->include().isValid()) {
e78566595089 initial import
mandel
parents:
diff changeset
1154 QFileInfo info(class_item->fileName());
e78566595089 initial import
mandel
parents:
diff changeset
1155 type->setInclude(Include(Include::IncludePath, info.fileName()));
e78566595089 initial import
mandel
parents:
diff changeset
1156 }
e78566595089 initial import
mandel
parents:
diff changeset
1157
e78566595089 initial import
mandel
parents:
diff changeset
1158 return meta_class;
e78566595089 initial import
mandel
parents:
diff changeset
1159 }
e78566595089 initial import
mandel
parents:
diff changeset
1160
e78566595089 initial import
mandel
parents:
diff changeset
1161 AbstractMetaField *AbstractMetaBuilder::traverseField(VariableModelItem field, const AbstractMetaClass *cls)
e78566595089 initial import
mandel
parents:
diff changeset
1162 {
e78566595089 initial import
mandel
parents:
diff changeset
1163 QString field_name = field->name();
e78566595089 initial import
mandel
parents:
diff changeset
1164 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
e78566595089 initial import
mandel
parents:
diff changeset
1165
e78566595089 initial import
mandel
parents:
diff changeset
1166 // Ignore friend decl.
e78566595089 initial import
mandel
parents:
diff changeset
1167 if (field->isFriend())
e78566595089 initial import
mandel
parents:
diff changeset
1168 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1169
e78566595089 initial import
mandel
parents:
diff changeset
1170 if (field->accessPolicy() == CodeModel::Private)
e78566595089 initial import
mandel
parents:
diff changeset
1171 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1172
e78566595089 initial import
mandel
parents:
diff changeset
1173 if (TypeDatabase::instance()->isFieldRejected(class_name, field_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
1174 m_rejected_fields.insert(class_name + "::" + field_name, GenerationDisabled);
e78566595089 initial import
mandel
parents:
diff changeset
1175 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1176 }
e78566595089 initial import
mandel
parents:
diff changeset
1177
e78566595089 initial import
mandel
parents:
diff changeset
1178
e78566595089 initial import
mandel
parents:
diff changeset
1179 AbstractMetaField *meta_field = createMetaField();
e78566595089 initial import
mandel
parents:
diff changeset
1180 meta_field->setName(field_name);
e78566595089 initial import
mandel
parents:
diff changeset
1181 meta_field->setEnclosingClass(cls);
e78566595089 initial import
mandel
parents:
diff changeset
1182
e78566595089 initial import
mandel
parents:
diff changeset
1183 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1184 TypeInfo field_type = field->type();
e78566595089 initial import
mandel
parents:
diff changeset
1185 AbstractMetaType *meta_type = translateType(field_type, &ok);
e78566595089 initial import
mandel
parents:
diff changeset
1186
e78566595089 initial import
mandel
parents:
diff changeset
1187 if (!meta_type || !ok) {
e78566595089 initial import
mandel
parents:
diff changeset
1188 ReportHandler::warning(QString("skipping field '%1::%2' with unmatched type '%3'")
e78566595089 initial import
mandel
parents:
diff changeset
1189 .arg(m_current_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
1190 .arg(field_name)
e78566595089 initial import
mandel
parents:
diff changeset
1191 .arg(TypeInfo::resolveType(field_type, currentScope()->toItem()).qualifiedName().join("::")));
e78566595089 initial import
mandel
parents:
diff changeset
1192 delete meta_field;
e78566595089 initial import
mandel
parents:
diff changeset
1193 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1194 }
e78566595089 initial import
mandel
parents:
diff changeset
1195
e78566595089 initial import
mandel
parents:
diff changeset
1196 meta_field->setType(meta_type);
e78566595089 initial import
mandel
parents:
diff changeset
1197
e78566595089 initial import
mandel
parents:
diff changeset
1198 uint attr = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1199 if (field->isStatic())
e78566595089 initial import
mandel
parents:
diff changeset
1200 attr |= AbstractMetaAttributes::Static;
e78566595089 initial import
mandel
parents:
diff changeset
1201
e78566595089 initial import
mandel
parents:
diff changeset
1202 CodeModel::AccessPolicy policy = field->accessPolicy();
e78566595089 initial import
mandel
parents:
diff changeset
1203 if (policy == CodeModel::Public)
e78566595089 initial import
mandel
parents:
diff changeset
1204 attr |= AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
1205 else if (policy == CodeModel::Protected)
e78566595089 initial import
mandel
parents:
diff changeset
1206 attr |= AbstractMetaAttributes::Protected;
e78566595089 initial import
mandel
parents:
diff changeset
1207 else
e78566595089 initial import
mandel
parents:
diff changeset
1208 attr |= AbstractMetaAttributes::Private;
e78566595089 initial import
mandel
parents:
diff changeset
1209 meta_field->setAttributes(attr);
e78566595089 initial import
mandel
parents:
diff changeset
1210
e78566595089 initial import
mandel
parents:
diff changeset
1211 return meta_field;
e78566595089 initial import
mandel
parents:
diff changeset
1212 }
e78566595089 initial import
mandel
parents:
diff changeset
1213
e78566595089 initial import
mandel
parents:
diff changeset
1214 void AbstractMetaBuilder::traverseFields(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
e78566595089 initial import
mandel
parents:
diff changeset
1215 {
e78566595089 initial import
mandel
parents:
diff changeset
1216 foreach (VariableModelItem field, scope_item->variables()) {
e78566595089 initial import
mandel
parents:
diff changeset
1217 AbstractMetaField *meta_field = traverseField(field, meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1218
e78566595089 initial import
mandel
parents:
diff changeset
1219 if (meta_field) {
e78566595089 initial import
mandel
parents:
diff changeset
1220 meta_field->setOriginalAttributes(meta_field->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
1221 meta_class->addField(meta_field);
e78566595089 initial import
mandel
parents:
diff changeset
1222 }
e78566595089 initial import
mandel
parents:
diff changeset
1223 }
e78566595089 initial import
mandel
parents:
diff changeset
1224 }
e78566595089 initial import
mandel
parents:
diff changeset
1225
e78566595089 initial import
mandel
parents:
diff changeset
1226 void AbstractMetaBuilder::setupFunctionDefaults(AbstractMetaFunction *meta_function, AbstractMetaClass *meta_class)
e78566595089 initial import
mandel
parents:
diff changeset
1227 {
e78566595089 initial import
mandel
parents:
diff changeset
1228 // Set the default value of the declaring class. This may be changed
e78566595089 initial import
mandel
parents:
diff changeset
1229 // in fixFunctions later on
e78566595089 initial import
mandel
parents:
diff changeset
1230 meta_function->setDeclaringClass(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1231
e78566595089 initial import
mandel
parents:
diff changeset
1232 // Some of the queries below depend on the implementing class being set
e78566595089 initial import
mandel
parents:
diff changeset
1233 // to function properly. Such as function modifications
e78566595089 initial import
mandel
parents:
diff changeset
1234 meta_function->setImplementingClass(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1235
e78566595089 initial import
mandel
parents:
diff changeset
1236 if (meta_function->name() == "operator_equal")
e78566595089 initial import
mandel
parents:
diff changeset
1237 meta_class->setHasEqualsOperator(true);
e78566595089 initial import
mandel
parents:
diff changeset
1238
e78566595089 initial import
mandel
parents:
diff changeset
1239 if (!meta_function->isFinalInTargetLang()
e78566595089 initial import
mandel
parents:
diff changeset
1240 && meta_function->isRemovedFrom(meta_class, TypeSystem::TargetLangCode)) {
e78566595089 initial import
mandel
parents:
diff changeset
1241 *meta_function += AbstractMetaAttributes::FinalInCpp;
e78566595089 initial import
mandel
parents:
diff changeset
1242 }
e78566595089 initial import
mandel
parents:
diff changeset
1243 }
e78566595089 initial import
mandel
parents:
diff changeset
1244
e78566595089 initial import
mandel
parents:
diff changeset
1245 void AbstractMetaBuilder::traverseFunctions(ScopeModelItem scope_item, AbstractMetaClass *meta_class)
e78566595089 initial import
mandel
parents:
diff changeset
1246 {
e78566595089 initial import
mandel
parents:
diff changeset
1247 foreach (FunctionModelItem function, scope_item->functions()) {
e78566595089 initial import
mandel
parents:
diff changeset
1248 AbstractMetaFunction *meta_function = traverseFunction(function);
e78566595089 initial import
mandel
parents:
diff changeset
1249
e78566595089 initial import
mandel
parents:
diff changeset
1250 if (meta_function) {
148
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1251
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1252 QList<FunctionModification> mods = meta_function->modifications(meta_class);
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1253 for (int i=0; i<mods.size(); ++i) {
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1254 if (mods.at(i).isPrivateSignal()) {
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1255 meta_function->setFunctionType(AbstractMetaFunction::SignalFunction);
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1256 }
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1257 }
ae34188ddd84 private signals of QAbstractItemModel are now accessible
eldar
parents: 1
diff changeset
1258
1
e78566595089 initial import
mandel
parents:
diff changeset
1259 meta_function->setOriginalAttributes(meta_function->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
1260 if (meta_class->isNamespace())
e78566595089 initial import
mandel
parents:
diff changeset
1261 *meta_function += AbstractMetaAttributes::Static;
e78566595089 initial import
mandel
parents:
diff changeset
1262
e78566595089 initial import
mandel
parents:
diff changeset
1263 if (!meta_function->isInvalid()) {
e78566595089 initial import
mandel
parents:
diff changeset
1264 if (QPropertySpec *read = meta_class->propertySpecForRead(meta_function->name())) {
e78566595089 initial import
mandel
parents:
diff changeset
1265 if (read->type() == meta_function->type()->typeEntry()) {
e78566595089 initial import
mandel
parents:
diff changeset
1266 *meta_function += AbstractMetaAttributes::PropertyReader;
e78566595089 initial import
mandel
parents:
diff changeset
1267 meta_function->setPropertySpec(read);
e78566595089 initial import
mandel
parents:
diff changeset
1268 // printf("%s is reader for %s\n",
e78566595089 initial import
mandel
parents:
diff changeset
1269 // qPrintable(meta_function->name()),
e78566595089 initial import
mandel
parents:
diff changeset
1270 // qPrintable(read->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1271 }
e78566595089 initial import
mandel
parents:
diff changeset
1272 } else if (QPropertySpec *write =
e78566595089 initial import
mandel
parents:
diff changeset
1273 meta_class->propertySpecForWrite(meta_function->name())) {
e78566595089 initial import
mandel
parents:
diff changeset
1274 if (write->type() == meta_function->arguments().at(0)->type()->typeEntry()) {
e78566595089 initial import
mandel
parents:
diff changeset
1275 *meta_function += AbstractMetaAttributes::PropertyWriter;
e78566595089 initial import
mandel
parents:
diff changeset
1276 meta_function->setPropertySpec(write);
e78566595089 initial import
mandel
parents:
diff changeset
1277 /*
e78566595089 initial import
mandel
parents:
diff changeset
1278 // qtd D properties syntax, rename setter from setPropertyName to just propertyName
e78566595089 initial import
mandel
parents:
diff changeset
1279 AbstractMetaFunction *f_copy = new AbstractMetaFunction();
e78566595089 initial import
mandel
parents:
diff changeset
1280 *f_copy = *meta_function;
e78566595089 initial import
mandel
parents:
diff changeset
1281
e78566595089 initial import
mandel
parents:
diff changeset
1282 QString f_name = meta_function->name();
e78566595089 initial import
mandel
parents:
diff changeset
1283 QString new_name = f_name.midRef(3, 1).toString().toLower() + f_name.right(f_name.length() - 4);
e78566595089 initial import
mandel
parents:
diff changeset
1284 meta_function->setName(new_name);
e78566595089 initial import
mandel
parents:
diff changeset
1285 // f_copy->setOwnerClass(meta_function->ownerClass());
e78566595089 initial import
mandel
parents:
diff changeset
1286 ((AbstractMetaClass*)(meta_function->ownerClass()))->addFunction(f_copy); // hack qtd2
e78566595089 initial import
mandel
parents:
diff changeset
1287 //
e78566595089 initial import
mandel
parents:
diff changeset
1288 */
e78566595089 initial import
mandel
parents:
diff changeset
1289 // printf("%s is writer for %s\n",
e78566595089 initial import
mandel
parents:
diff changeset
1290 // qPrintable(meta_function->name()),
e78566595089 initial import
mandel
parents:
diff changeset
1291 // qPrintable(write->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1292 }
e78566595089 initial import
mandel
parents:
diff changeset
1293 } else if (QPropertySpec *reset =
e78566595089 initial import
mandel
parents:
diff changeset
1294 meta_class->propertySpecForReset(meta_function->name())) {
e78566595089 initial import
mandel
parents:
diff changeset
1295 *meta_function += AbstractMetaAttributes::PropertyResetter;
e78566595089 initial import
mandel
parents:
diff changeset
1296 meta_function->setPropertySpec(reset);
e78566595089 initial import
mandel
parents:
diff changeset
1297 // printf("%s is resetter for %s\n",
e78566595089 initial import
mandel
parents:
diff changeset
1298 // qPrintable(meta_function->name()),
e78566595089 initial import
mandel
parents:
diff changeset
1299 // qPrintable(reset->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1300 }
e78566595089 initial import
mandel
parents:
diff changeset
1301 }
e78566595089 initial import
mandel
parents:
diff changeset
1302
e78566595089 initial import
mandel
parents:
diff changeset
1303
e78566595089 initial import
mandel
parents:
diff changeset
1304 bool isInvalidDestructor = meta_function->isDestructor() && meta_function->isPrivate();
e78566595089 initial import
mandel
parents:
diff changeset
1305 bool isInvalidConstructor = meta_function->isConstructor()
e78566595089 initial import
mandel
parents:
diff changeset
1306 && (meta_function->isPrivate() || meta_function->isInvalid());
e78566595089 initial import
mandel
parents:
diff changeset
1307 if ((isInvalidDestructor || isInvalidConstructor)
e78566595089 initial import
mandel
parents:
diff changeset
1308 && !meta_class->hasNonPrivateConstructor()) {
e78566595089 initial import
mandel
parents:
diff changeset
1309 *meta_class += AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
1310 } else if (meta_function->isConstructor() && !meta_function->isPrivate()) {
e78566595089 initial import
mandel
parents:
diff changeset
1311 *meta_class -= AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
1312 meta_class->setHasNonPrivateConstructor(true);
e78566595089 initial import
mandel
parents:
diff changeset
1313 }
e78566595089 initial import
mandel
parents:
diff changeset
1314
259
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1315 if (meta_function->isDestructor())
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1316 {
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1317 if (meta_class->name() == "QFSFileEngine")
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1318 {
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1319 std::cout << meta_function->isFinal() << std::endl;
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1320 std::cout << qPrintable(meta_function->name()) << std::endl;
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1321 qFatal("Gop");
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1322 }
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1323
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1324 if (!meta_function->isFinal())
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1325 meta_class->setHasVirtualDestructor(true);
515d6e1c7b10 another iteration
maxter
parents: 257
diff changeset
1326 }
1
e78566595089 initial import
mandel
parents:
diff changeset
1327
e78566595089 initial import
mandel
parents:
diff changeset
1328 if (!meta_function->isDestructor()
e78566595089 initial import
mandel
parents:
diff changeset
1329 && !meta_function->isInvalid()
e78566595089 initial import
mandel
parents:
diff changeset
1330 && (!meta_function->isConstructor() || !meta_function->isPrivate())) {
e78566595089 initial import
mandel
parents:
diff changeset
1331
e78566595089 initial import
mandel
parents:
diff changeset
1332 if (meta_class->typeEntry()->designatedInterface() && !meta_function->isPublic()
e78566595089 initial import
mandel
parents:
diff changeset
1333 && !meta_function->isPrivate()) {
e78566595089 initial import
mandel
parents:
diff changeset
1334 QString warn = QString("non-public function '%1' in interface '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
1335 .arg(meta_function->name()).arg(meta_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
1336 ReportHandler::warning(warn);
e78566595089 initial import
mandel
parents:
diff changeset
1337
e78566595089 initial import
mandel
parents:
diff changeset
1338 meta_function->setVisibility(AbstractMetaClass::Public);
e78566595089 initial import
mandel
parents:
diff changeset
1339 }
e78566595089 initial import
mandel
parents:
diff changeset
1340
e78566595089 initial import
mandel
parents:
diff changeset
1341 setupFunctionDefaults(meta_function, meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1342
e78566595089 initial import
mandel
parents:
diff changeset
1343 if (meta_function->isSignal() && meta_class->hasSignal(meta_function)) {
e78566595089 initial import
mandel
parents:
diff changeset
1344 QString warn = QString("signal '%1' in class '%2' is overloaded.")
e78566595089 initial import
mandel
parents:
diff changeset
1345 .arg(meta_function->name()).arg(meta_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
1346 ReportHandler::warning(warn);
e78566595089 initial import
mandel
parents:
diff changeset
1347 }
e78566595089 initial import
mandel
parents:
diff changeset
1348
e78566595089 initial import
mandel
parents:
diff changeset
1349 if (meta_function->isSignal() && !meta_class->isQObject()) {
e78566595089 initial import
mandel
parents:
diff changeset
1350 QString warn = QString("signal '%1' in non-QObject class '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
1351 .arg(meta_function->name()).arg(meta_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
1352 ReportHandler::warning(warn);
e78566595089 initial import
mandel
parents:
diff changeset
1353 }
e78566595089 initial import
mandel
parents:
diff changeset
1354
e78566595089 initial import
mandel
parents:
diff changeset
1355 meta_class->addFunction(meta_function);
e78566595089 initial import
mandel
parents:
diff changeset
1356 } else if (meta_function->isDestructor() && !meta_function->isPublic()) {
e78566595089 initial import
mandel
parents:
diff changeset
1357 meta_class->setHasPublicDestructor(false);
e78566595089 initial import
mandel
parents:
diff changeset
1358 }
e78566595089 initial import
mandel
parents:
diff changeset
1359 }
e78566595089 initial import
mandel
parents:
diff changeset
1360 }
e78566595089 initial import
mandel
parents:
diff changeset
1361 }
e78566595089 initial import
mandel
parents:
diff changeset
1362
e78566595089 initial import
mandel
parents:
diff changeset
1363 bool AbstractMetaBuilder::setupInheritance(AbstractMetaClass *meta_class)
e78566595089 initial import
mandel
parents:
diff changeset
1364 {
e78566595089 initial import
mandel
parents:
diff changeset
1365 Q_ASSERT(!meta_class->isInterface());
e78566595089 initial import
mandel
parents:
diff changeset
1366
e78566595089 initial import
mandel
parents:
diff changeset
1367 if (m_setup_inheritance_done.contains(meta_class))
e78566595089 initial import
mandel
parents:
diff changeset
1368 return true;
e78566595089 initial import
mandel
parents:
diff changeset
1369 m_setup_inheritance_done.insert(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1370
e78566595089 initial import
mandel
parents:
diff changeset
1371 QStringList base_classes = meta_class->baseClassNames();
e78566595089 initial import
mandel
parents:
diff changeset
1372
e78566595089 initial import
mandel
parents:
diff changeset
1373 TypeDatabase *types = TypeDatabase::instance();
e78566595089 initial import
mandel
parents:
diff changeset
1374
e78566595089 initial import
mandel
parents:
diff changeset
1375 // we only support our own containers and ONLY if there is only one baseclass
e78566595089 initial import
mandel
parents:
diff changeset
1376 if (base_classes.size() == 1 && base_classes.first().count('<') == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
1377 QStringList scope = meta_class->typeEntry()->qualifiedCppName().split("::");
e78566595089 initial import
mandel
parents:
diff changeset
1378 scope.removeLast();
e78566595089 initial import
mandel
parents:
diff changeset
1379 for (int i=scope.size(); i>=0; --i) {
e78566595089 initial import
mandel
parents:
diff changeset
1380 QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join("::") + "::" : QString();
e78566595089 initial import
mandel
parents:
diff changeset
1381 QString complete_name = prefix + base_classes.first();
e78566595089 initial import
mandel
parents:
diff changeset
1382 TypeParser::Info info = TypeParser::parse(complete_name);
e78566595089 initial import
mandel
parents:
diff changeset
1383 QString base_name = info.qualified_name.join("::");
e78566595089 initial import
mandel
parents:
diff changeset
1384
e78566595089 initial import
mandel
parents:
diff changeset
1385 AbstractMetaClass *templ = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1386 foreach (AbstractMetaClass *c, m_templates) {
e78566595089 initial import
mandel
parents:
diff changeset
1387 if (c->typeEntry()->name() == base_name) {
e78566595089 initial import
mandel
parents:
diff changeset
1388 templ = c;
e78566595089 initial import
mandel
parents:
diff changeset
1389 break;
e78566595089 initial import
mandel
parents:
diff changeset
1390 }
e78566595089 initial import
mandel
parents:
diff changeset
1391 }
e78566595089 initial import
mandel
parents:
diff changeset
1392
e78566595089 initial import
mandel
parents:
diff changeset
1393 if (templ == 0)
e78566595089 initial import
mandel
parents:
diff changeset
1394 templ = m_meta_classes.findClass(base_name);
e78566595089 initial import
mandel
parents:
diff changeset
1395
e78566595089 initial import
mandel
parents:
diff changeset
1396 if (templ) {
e78566595089 initial import
mandel
parents:
diff changeset
1397 setupInheritance(templ);
e78566595089 initial import
mandel
parents:
diff changeset
1398 inheritTemplate(meta_class, templ, info);
e78566595089 initial import
mandel
parents:
diff changeset
1399 return true;
e78566595089 initial import
mandel
parents:
diff changeset
1400 }
e78566595089 initial import
mandel
parents:
diff changeset
1401 }
e78566595089 initial import
mandel
parents:
diff changeset
1402
e78566595089 initial import
mandel
parents:
diff changeset
1403 ReportHandler::warning(QString("template baseclass '%1' of '%2' is not known")
e78566595089 initial import
mandel
parents:
diff changeset
1404 .arg(base_classes.first())
e78566595089 initial import
mandel
parents:
diff changeset
1405 .arg(meta_class->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1406 return false;
e78566595089 initial import
mandel
parents:
diff changeset
1407 }
e78566595089 initial import
mandel
parents:
diff changeset
1408
e78566595089 initial import
mandel
parents:
diff changeset
1409 int primary = -1;
e78566595089 initial import
mandel
parents:
diff changeset
1410 int primaries = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1411 for (int i=0; i<base_classes.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
1412
e78566595089 initial import
mandel
parents:
diff changeset
1413 if (types->isClassRejected(base_classes.at(i)))
e78566595089 initial import
mandel
parents:
diff changeset
1414 continue;
e78566595089 initial import
mandel
parents:
diff changeset
1415
e78566595089 initial import
mandel
parents:
diff changeset
1416 TypeEntry *base_class_entry = types->findType(base_classes.at(i));
e78566595089 initial import
mandel
parents:
diff changeset
1417 if (!base_class_entry) {
e78566595089 initial import
mandel
parents:
diff changeset
1418 ReportHandler::warning(QString("class '%1' inherits from unknown base class '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
1419 .arg(meta_class->name()).arg(base_classes.at(i)));
e78566595089 initial import
mandel
parents:
diff changeset
1420 }
e78566595089 initial import
mandel
parents:
diff changeset
1421
e78566595089 initial import
mandel
parents:
diff changeset
1422 // true for primary base class
e78566595089 initial import
mandel
parents:
diff changeset
1423 else if (!base_class_entry->designatedInterface()) {
e78566595089 initial import
mandel
parents:
diff changeset
1424 if (primaries > 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1425 ReportHandler::warning(QString("class '%1' has multiple primary base classes"
e78566595089 initial import
mandel
parents:
diff changeset
1426 " '%2' and '%3'")
e78566595089 initial import
mandel
parents:
diff changeset
1427 .arg(meta_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
1428 .arg(base_classes.at(primary))
e78566595089 initial import
mandel
parents:
diff changeset
1429 .arg(base_class_entry->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1430 return false;
e78566595089 initial import
mandel
parents:
diff changeset
1431 }
e78566595089 initial import
mandel
parents:
diff changeset
1432 primaries++;
e78566595089 initial import
mandel
parents:
diff changeset
1433 primary = i;
e78566595089 initial import
mandel
parents:
diff changeset
1434 }
e78566595089 initial import
mandel
parents:
diff changeset
1435 }
e78566595089 initial import
mandel
parents:
diff changeset
1436
e78566595089 initial import
mandel
parents:
diff changeset
1437 if (primary >= 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1438 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(primary));
e78566595089 initial import
mandel
parents:
diff changeset
1439 if (!base_class) {
e78566595089 initial import
mandel
parents:
diff changeset
1440 ReportHandler::warning(QString("unknown baseclass for '%1': '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
1441 .arg(meta_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
1442 .arg(base_classes.at(primary)));
e78566595089 initial import
mandel
parents:
diff changeset
1443 return false;
e78566595089 initial import
mandel
parents:
diff changeset
1444 }
e78566595089 initial import
mandel
parents:
diff changeset
1445 meta_class->setBaseClass(base_class);
e78566595089 initial import
mandel
parents:
diff changeset
1446
e78566595089 initial import
mandel
parents:
diff changeset
1447 if (meta_class->typeEntry()->designatedInterface() != 0 && meta_class->isQObject()) {
e78566595089 initial import
mandel
parents:
diff changeset
1448 ReportHandler::warning(QString("QObject extended by interface type '%1'. This is not supported and the generated Java code will not compile.")
e78566595089 initial import
mandel
parents:
diff changeset
1449 .arg(meta_class->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1450 } else if (meta_class->typeEntry()->designatedInterface() != 0 && base_class != 0 && !base_class->isInterface()) {
e78566595089 initial import
mandel
parents:
diff changeset
1451 ReportHandler::warning(QString("object type '%1' extended by interface type '%2'. The resulting API will be less expressive than the original.")
e78566595089 initial import
mandel
parents:
diff changeset
1452 .arg(base_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
1453 .arg(meta_class->name()));
e78566595089 initial import
mandel
parents:
diff changeset
1454 }
e78566595089 initial import
mandel
parents:
diff changeset
1455
e78566595089 initial import
mandel
parents:
diff changeset
1456 }
e78566595089 initial import
mandel
parents:
diff changeset
1457
e78566595089 initial import
mandel
parents:
diff changeset
1458 for (int i=0; i<base_classes.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
1459 if (types->isClassRejected(base_classes.at(i)))
e78566595089 initial import
mandel
parents:
diff changeset
1460 continue;
e78566595089 initial import
mandel
parents:
diff changeset
1461
e78566595089 initial import
mandel
parents:
diff changeset
1462 if (i != primary) {
e78566595089 initial import
mandel
parents:
diff changeset
1463 AbstractMetaClass *base_class = m_meta_classes.findClass(base_classes.at(i));
e78566595089 initial import
mandel
parents:
diff changeset
1464 if (base_class == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1465 ReportHandler::warning(QString("class not found for setup inheritance '%1'").arg(base_classes.at(i)));
e78566595089 initial import
mandel
parents:
diff changeset
1466 return false;
e78566595089 initial import
mandel
parents:
diff changeset
1467 }
e78566595089 initial import
mandel
parents:
diff changeset
1468
e78566595089 initial import
mandel
parents:
diff changeset
1469 setupInheritance(base_class);
e78566595089 initial import
mandel
parents:
diff changeset
1470
e78566595089 initial import
mandel
parents:
diff changeset
1471 QString interface_name = InterfaceTypeEntry::interfaceName(base_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
1472 AbstractMetaClass *iface = m_meta_classes.findClass(interface_name);
e78566595089 initial import
mandel
parents:
diff changeset
1473 if (!iface) {
e78566595089 initial import
mandel
parents:
diff changeset
1474 ReportHandler::warning(QString("unknown interface for '%1': '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
1475 .arg(meta_class->name())
e78566595089 initial import
mandel
parents:
diff changeset
1476 .arg(interface_name));
e78566595089 initial import
mandel
parents:
diff changeset
1477 return false;
e78566595089 initial import
mandel
parents:
diff changeset
1478 }
e78566595089 initial import
mandel
parents:
diff changeset
1479 meta_class->addInterface(iface);
e78566595089 initial import
mandel
parents:
diff changeset
1480
e78566595089 initial import
mandel
parents:
diff changeset
1481 AbstractMetaClassList interfaces = iface->interfaces();
e78566595089 initial import
mandel
parents:
diff changeset
1482 foreach (AbstractMetaClass *iface, interfaces)
e78566595089 initial import
mandel
parents:
diff changeset
1483 meta_class->addInterface(iface);
e78566595089 initial import
mandel
parents:
diff changeset
1484 }
e78566595089 initial import
mandel
parents:
diff changeset
1485 }
e78566595089 initial import
mandel
parents:
diff changeset
1486
e78566595089 initial import
mandel
parents:
diff changeset
1487 return true;
e78566595089 initial import
mandel
parents:
diff changeset
1488 }
e78566595089 initial import
mandel
parents:
diff changeset
1489
e78566595089 initial import
mandel
parents:
diff changeset
1490 void AbstractMetaBuilder::traverseEnums(ScopeModelItem scope_item, AbstractMetaClass *meta_class, const QStringList &enumsDeclarations)
e78566595089 initial import
mandel
parents:
diff changeset
1491 {
e78566595089 initial import
mandel
parents:
diff changeset
1492 EnumList enums = scope_item->enums();
e78566595089 initial import
mandel
parents:
diff changeset
1493 foreach (EnumModelItem enum_item, enums) {
e78566595089 initial import
mandel
parents:
diff changeset
1494 AbstractMetaEnum *meta_enum = traverseEnum(enum_item, meta_class, QSet<QString>::fromList(enumsDeclarations));
e78566595089 initial import
mandel
parents:
diff changeset
1495 if (meta_enum) {
e78566595089 initial import
mandel
parents:
diff changeset
1496 meta_enum->setOriginalAttributes(meta_enum->attributes());
e78566595089 initial import
mandel
parents:
diff changeset
1497 meta_class->addEnum(meta_enum);
e78566595089 initial import
mandel
parents:
diff changeset
1498 meta_enum->setEnclosingClass(meta_class);
e78566595089 initial import
mandel
parents:
diff changeset
1499 }
e78566595089 initial import
mandel
parents:
diff changeset
1500 }
e78566595089 initial import
mandel
parents:
diff changeset
1501 }
e78566595089 initial import
mandel
parents:
diff changeset
1502
e78566595089 initial import
mandel
parents:
diff changeset
1503 AbstractMetaFunction *AbstractMetaBuilder::traverseFunction(FunctionModelItem function_item)
e78566595089 initial import
mandel
parents:
diff changeset
1504 {
e78566595089 initial import
mandel
parents:
diff changeset
1505 QString function_name = function_item->name();
e78566595089 initial import
mandel
parents:
diff changeset
1506 QString class_name = m_current_class->typeEntry()->qualifiedCppName();
e78566595089 initial import
mandel
parents:
diff changeset
1507
e78566595089 initial import
mandel
parents:
diff changeset
1508 if (TypeDatabase::instance()->isFunctionRejected(class_name, function_name)) {
e78566595089 initial import
mandel
parents:
diff changeset
1509 m_rejected_functions.insert(class_name + "::" + function_name, GenerationDisabled);
e78566595089 initial import
mandel
parents:
diff changeset
1510 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1511 }
e78566595089 initial import
mandel
parents:
diff changeset
1512
e78566595089 initial import
mandel
parents:
diff changeset
1513
e78566595089 initial import
mandel
parents:
diff changeset
1514 Q_ASSERT(function_item->functionType() == CodeModel::Normal
e78566595089 initial import
mandel
parents:
diff changeset
1515 || function_item->functionType() == CodeModel::Signal
e78566595089 initial import
mandel
parents:
diff changeset
1516 || function_item->functionType() == CodeModel::Slot);
e78566595089 initial import
mandel
parents:
diff changeset
1517
e78566595089 initial import
mandel
parents:
diff changeset
1518 if (function_item->isFriend())
e78566595089 initial import
mandel
parents:
diff changeset
1519 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1520
e78566595089 initial import
mandel
parents:
diff changeset
1521
e78566595089 initial import
mandel
parents:
diff changeset
1522 QString cast_type;
e78566595089 initial import
mandel
parents:
diff changeset
1523
e78566595089 initial import
mandel
parents:
diff changeset
1524 if (function_name.startsWith("operator")) {
e78566595089 initial import
mandel
parents:
diff changeset
1525 function_name = rename_operator(function_name.mid(8));
e78566595089 initial import
mandel
parents:
diff changeset
1526 if (function_name.isEmpty()) {
e78566595089 initial import
mandel
parents:
diff changeset
1527 m_rejected_functions.insert(class_name + "::" + function_name,
e78566595089 initial import
mandel
parents:
diff changeset
1528 GenerationDisabled);
e78566595089 initial import
mandel
parents:
diff changeset
1529 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1530 }
e78566595089 initial import
mandel
parents:
diff changeset
1531 if (function_name.contains("_cast_"))
e78566595089 initial import
mandel
parents:
diff changeset
1532 cast_type = function_name.mid(14).trimmed();
e78566595089 initial import
mandel
parents:
diff changeset
1533 }
e78566595089 initial import
mandel
parents:
diff changeset
1534
e78566595089 initial import
mandel
parents:
diff changeset
1535 AbstractMetaFunction *meta_function = createMetaFunction();
e78566595089 initial import
mandel
parents:
diff changeset
1536 meta_function->setConstant(function_item->isConstant());
e78566595089 initial import
mandel
parents:
diff changeset
1537
e78566595089 initial import
mandel
parents:
diff changeset
1538 ReportHandler::debugMedium(QString(" - %2()").arg(function_name));
e78566595089 initial import
mandel
parents:
diff changeset
1539
e78566595089 initial import
mandel
parents:
diff changeset
1540 meta_function->setName(function_name);
e78566595089 initial import
mandel
parents:
diff changeset
1541 meta_function->setOriginalName(function_item->name());
e78566595089 initial import
mandel
parents:
diff changeset
1542
e78566595089 initial import
mandel
parents:
diff changeset
1543 if (function_item->isAbstract())
e78566595089 initial import
mandel
parents:
diff changeset
1544 *meta_function += AbstractMetaAttributes::Abstract;
e78566595089 initial import
mandel
parents:
diff changeset
1545
e78566595089 initial import
mandel
parents:
diff changeset
1546 if (!meta_function->isAbstract())
e78566595089 initial import
mandel
parents:
diff changeset
1547 *meta_function += AbstractMetaAttributes::Native;
e78566595089 initial import
mandel
parents:
diff changeset
1548
e78566595089 initial import
mandel
parents:
diff changeset
1549 if (!function_item->isVirtual())
e78566595089 initial import
mandel
parents:
diff changeset
1550 *meta_function += AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
1551
e78566595089 initial import
mandel
parents:
diff changeset
1552 if (function_item->isInvokable())
e78566595089 initial import
mandel
parents:
diff changeset
1553 *meta_function += AbstractMetaAttributes::Invokable;
e78566595089 initial import
mandel
parents:
diff changeset
1554
e78566595089 initial import
mandel
parents:
diff changeset
1555 if (function_item->isStatic()) {
e78566595089 initial import
mandel
parents:
diff changeset
1556 *meta_function += AbstractMetaAttributes::Static;
e78566595089 initial import
mandel
parents:
diff changeset
1557 *meta_function += AbstractMetaAttributes::Final;
e78566595089 initial import
mandel
parents:
diff changeset
1558 }
e78566595089 initial import
mandel
parents:
diff changeset
1559
e78566595089 initial import
mandel
parents:
diff changeset
1560 // Access rights
e78566595089 initial import
mandel
parents:
diff changeset
1561 if (function_item->accessPolicy() == CodeModel::Public)
e78566595089 initial import
mandel
parents:
diff changeset
1562 *meta_function += AbstractMetaAttributes::Public;
e78566595089 initial import
mandel
parents:
diff changeset
1563 else if (function_item->accessPolicy() == CodeModel::Private)
e78566595089 initial import
mandel
parents:
diff changeset
1564 *meta_function += AbstractMetaAttributes::Private;
e78566595089 initial import
mandel
parents:
diff changeset
1565 else
e78566595089 initial import
mandel
parents:
diff changeset
1566 *meta_function += AbstractMetaAttributes::Protected;
e78566595089 initial import
mandel
parents:
diff changeset
1567
e78566595089 initial import
mandel
parents:
diff changeset
1568
e78566595089 initial import
mandel
parents:
diff changeset
1569 QString stripped_class_name = class_name;
e78566595089 initial import
mandel
parents:
diff changeset
1570 int cc_pos = stripped_class_name.lastIndexOf("::");
e78566595089 initial import
mandel
parents:
diff changeset
1571 if (cc_pos > 0)
e78566595089 initial import
mandel
parents:
diff changeset
1572 stripped_class_name = stripped_class_name.mid(cc_pos + 2);
e78566595089 initial import
mandel
parents:
diff changeset
1573
e78566595089 initial import
mandel
parents:
diff changeset
1574 TypeInfo function_type = function_item->type();
e78566595089 initial import
mandel
parents:
diff changeset
1575 if (function_name.startsWith('~')) {
257
maxter
parents: 148
diff changeset
1576 meta_function->setFunctionType(AbstractMetaFunction::DestructorFunction);
maxter
parents: 148
diff changeset
1577 //meta_function->setInvalid(true);
1
e78566595089 initial import
mandel
parents:
diff changeset
1578 } else if (strip_template_args(function_name) == stripped_class_name) {
e78566595089 initial import
mandel
parents:
diff changeset
1579 meta_function->setFunctionType(AbstractMetaFunction::ConstructorFunction);
e78566595089 initial import
mandel
parents:
diff changeset
1580 meta_function->setName(m_current_class->name());
e78566595089 initial import
mandel
parents:
diff changeset
1581 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1582 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1583 AbstractMetaType *type = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1584
e78566595089 initial import
mandel
parents:
diff changeset
1585 if (!cast_type.isEmpty()) {
e78566595089 initial import
mandel
parents:
diff changeset
1586 TypeInfo info;
e78566595089 initial import
mandel
parents:
diff changeset
1587 info.setQualifiedName(QStringList(cast_type));
e78566595089 initial import
mandel
parents:
diff changeset
1588 type = translateType(info, &ok);
e78566595089 initial import
mandel
parents:
diff changeset
1589 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1590 type = translateType(function_type, &ok);
e78566595089 initial import
mandel
parents:
diff changeset
1591 }
e78566595089 initial import
mandel
parents:
diff changeset
1592
e78566595089 initial import
mandel
parents:
diff changeset
1593 if (!ok) {
e78566595089 initial import
mandel
parents:
diff changeset
1594 ReportHandler::warning(QString("skipping function '%1::%2', unmatched return type '%3'")
e78566595089 initial import
mandel
parents:
diff changeset
1595 .arg(class_name)
e78566595089 initial import
mandel
parents:
diff changeset
1596 .arg(function_item->name())
e78566595089 initial import
mandel
parents:
diff changeset
1597 .arg(function_item->type().toString()));
e78566595089 initial import
mandel
parents:
diff changeset
1598 m_rejected_functions[class_name + "::" + function_name] =
e78566595089 initial import
mandel
parents:
diff changeset
1599 UnmatchedReturnType;
e78566595089 initial import
mandel
parents:
diff changeset
1600 meta_function->setInvalid(true);
e78566595089 initial import
mandel
parents:
diff changeset
1601 return meta_function;
e78566595089 initial import
mandel
parents:
diff changeset
1602 }
e78566595089 initial import
mandel
parents:
diff changeset
1603 meta_function->setType(type);
e78566595089 initial import
mandel
parents:
diff changeset
1604
e78566595089 initial import
mandel
parents:
diff changeset
1605 if (function_item->functionType() == CodeModel::Signal)
e78566595089 initial import
mandel
parents:
diff changeset
1606 meta_function->setFunctionType(AbstractMetaFunction::SignalFunction);
e78566595089 initial import
mandel
parents:
diff changeset
1607 else if (function_item->functionType() == CodeModel::Slot)
e78566595089 initial import
mandel
parents:
diff changeset
1608 meta_function->setFunctionType(AbstractMetaFunction::SlotFunction);
e78566595089 initial import
mandel
parents:
diff changeset
1609 }
e78566595089 initial import
mandel
parents:
diff changeset
1610
e78566595089 initial import
mandel
parents:
diff changeset
1611 ArgumentList arguments = function_item->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
1612 AbstractMetaArgumentList meta_arguments;
e78566595089 initial import
mandel
parents:
diff changeset
1613
e78566595089 initial import
mandel
parents:
diff changeset
1614 int first_default_argument = 0;
e78566595089 initial import
mandel
parents:
diff changeset
1615 for (int i=0; i<arguments.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
1616 ArgumentModelItem arg = arguments.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
1617
e78566595089 initial import
mandel
parents:
diff changeset
1618 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1619 AbstractMetaType *meta_type = translateType(arg->type(), &ok);
e78566595089 initial import
mandel
parents:
diff changeset
1620 if (!meta_type || !ok) {
e78566595089 initial import
mandel
parents:
diff changeset
1621 ReportHandler::warning(QString("skipping function '%1::%2', "
e78566595089 initial import
mandel
parents:
diff changeset
1622 "unmatched parameter type '%3'")
e78566595089 initial import
mandel
parents:
diff changeset
1623 .arg(class_name)
e78566595089 initial import
mandel
parents:
diff changeset
1624 .arg(function_item->name())
e78566595089 initial import
mandel
parents:
diff changeset
1625 .arg(arg->type().toString()));
e78566595089 initial import
mandel
parents:
diff changeset
1626 m_rejected_functions[class_name + "::" + function_name] =
e78566595089 initial import
mandel
parents:
diff changeset
1627 UnmatchedArgumentType;
e78566595089 initial import
mandel
parents:
diff changeset
1628 meta_function->setInvalid(true);
e78566595089 initial import
mandel
parents:
diff changeset
1629 return meta_function;
e78566595089 initial import
mandel
parents:
diff changeset
1630 }
e78566595089 initial import
mandel
parents:
diff changeset
1631 AbstractMetaArgument *meta_argument = createMetaArgument();
e78566595089 initial import
mandel
parents:
diff changeset
1632 meta_argument->setType(meta_type);
e78566595089 initial import
mandel
parents:
diff changeset
1633 meta_argument->setName(arg->name());
e78566595089 initial import
mandel
parents:
diff changeset
1634 meta_argument->setArgumentIndex(i);
e78566595089 initial import
mandel
parents:
diff changeset
1635 meta_arguments << meta_argument;
e78566595089 initial import
mandel
parents:
diff changeset
1636 }
e78566595089 initial import
mandel
parents:
diff changeset
1637
e78566595089 initial import
mandel
parents:
diff changeset
1638 meta_function->setArguments(meta_arguments);
e78566595089 initial import
mandel
parents:
diff changeset
1639
e78566595089 initial import
mandel
parents:
diff changeset
1640 // Find the correct default values
e78566595089 initial import
mandel
parents:
diff changeset
1641 for (int i=0; i<arguments.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
1642 ArgumentModelItem arg = arguments.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
1643 AbstractMetaArgument *meta_arg = meta_arguments.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
1644 if (arg->defaultValue()) {
e78566595089 initial import
mandel
parents:
diff changeset
1645 QString expr = arg->defaultValueExpression();
e78566595089 initial import
mandel
parents:
diff changeset
1646 if (!expr.isEmpty())
e78566595089 initial import
mandel
parents:
diff changeset
1647 meta_arg->setOriginalDefaultValueExpression(expr);
e78566595089 initial import
mandel
parents:
diff changeset
1648
e78566595089 initial import
mandel
parents:
diff changeset
1649 expr = translateDefaultValue(arg, meta_arg->type(), meta_function, m_current_class, i);
e78566595089 initial import
mandel
parents:
diff changeset
1650 if (expr.isEmpty()) {
e78566595089 initial import
mandel
parents:
diff changeset
1651 first_default_argument = i;
e78566595089 initial import
mandel
parents:
diff changeset
1652 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1653 meta_arg->setDefaultValueExpression(expr);
e78566595089 initial import
mandel
parents:
diff changeset
1654 }
e78566595089 initial import
mandel
parents:
diff changeset
1655
e78566595089 initial import
mandel
parents:
diff changeset
1656 if (meta_arg->type()->isEnum() || meta_arg->type()->isFlags()) {
e78566595089 initial import
mandel
parents:
diff changeset
1657 m_enum_default_arguments
e78566595089 initial import
mandel
parents:
diff changeset
1658 << QPair<AbstractMetaArgument *, AbstractMetaFunction *>(meta_arg, meta_function);
e78566595089 initial import
mandel
parents:
diff changeset
1659 }
e78566595089 initial import
mandel
parents:
diff changeset
1660
e78566595089 initial import
mandel
parents:
diff changeset
1661 }
e78566595089 initial import
mandel
parents:
diff changeset
1662 }
e78566595089 initial import
mandel
parents:
diff changeset
1663
e78566595089 initial import
mandel
parents:
diff changeset
1664 // If we where not able to translate the default argument make it
e78566595089 initial import
mandel
parents:
diff changeset
1665 // reset all default arguments before this one too.
e78566595089 initial import
mandel
parents:
diff changeset
1666 for (int i=0; i<first_default_argument; ++i)
e78566595089 initial import
mandel
parents:
diff changeset
1667 meta_arguments[i]->setDefaultValueExpression(QString());
e78566595089 initial import
mandel
parents:
diff changeset
1668
e78566595089 initial import
mandel
parents:
diff changeset
1669 if (ReportHandler::debugLevel() == ReportHandler::FullDebug)
e78566595089 initial import
mandel
parents:
diff changeset
1670 foreach(AbstractMetaArgument *arg, meta_arguments)
e78566595089 initial import
mandel
parents:
diff changeset
1671 ReportHandler::debugFull(" - " + arg->toString());
e78566595089 initial import
mandel
parents:
diff changeset
1672
e78566595089 initial import
mandel
parents:
diff changeset
1673 return meta_function;
e78566595089 initial import
mandel
parents:
diff changeset
1674 }
e78566595089 initial import
mandel
parents:
diff changeset
1675
e78566595089 initial import
mandel
parents:
diff changeset
1676
e78566595089 initial import
mandel
parents:
diff changeset
1677 AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, bool *ok, bool resolveType, bool resolveScope)
e78566595089 initial import
mandel
parents:
diff changeset
1678 {
e78566595089 initial import
mandel
parents:
diff changeset
1679 Q_ASSERT(ok);
e78566595089 initial import
mandel
parents:
diff changeset
1680 *ok = true;
e78566595089 initial import
mandel
parents:
diff changeset
1681
e78566595089 initial import
mandel
parents:
diff changeset
1682 // 1. Test the type info without resolving typedefs in case this is present in the
e78566595089 initial import
mandel
parents:
diff changeset
1683 // type system
e78566595089 initial import
mandel
parents:
diff changeset
1684 TypeInfo typei;
e78566595089 initial import
mandel
parents:
diff changeset
1685 if (resolveType) {
e78566595089 initial import
mandel
parents:
diff changeset
1686 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1687 AbstractMetaType *t = translateType(_typei, &ok, false, resolveScope);
e78566595089 initial import
mandel
parents:
diff changeset
1688 if (t != 0 && ok)
e78566595089 initial import
mandel
parents:
diff changeset
1689 return t;
e78566595089 initial import
mandel
parents:
diff changeset
1690 }
e78566595089 initial import
mandel
parents:
diff changeset
1691
e78566595089 initial import
mandel
parents:
diff changeset
1692 if (!resolveType)
e78566595089 initial import
mandel
parents:
diff changeset
1693 typei = _typei;
e78566595089 initial import
mandel
parents:
diff changeset
1694 else {
e78566595089 initial import
mandel
parents:
diff changeset
1695 // Go through all parts of the current scope (including global namespace)
e78566595089 initial import
mandel
parents:
diff changeset
1696 // to resolve typedefs. The parser does not properly resolve typedefs in
e78566595089 initial import
mandel
parents:
diff changeset
1697 // the global scope when they are referenced from inside a namespace.
e78566595089 initial import
mandel
parents:
diff changeset
1698 // This is a work around to fix this bug since fixing it in resolveType
e78566595089 initial import
mandel
parents:
diff changeset
1699 // seemed non-trivial
e78566595089 initial import
mandel
parents:
diff changeset
1700 int i = m_scopes.size() - 1;
e78566595089 initial import
mandel
parents:
diff changeset
1701 while (i >= 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1702 typei = TypeInfo::resolveType(_typei, m_scopes.at(i--)->toItem());
e78566595089 initial import
mandel
parents:
diff changeset
1703 if (typei.qualifiedName().join("::") != _typei.qualifiedName().join("::"))
e78566595089 initial import
mandel
parents:
diff changeset
1704 break;
e78566595089 initial import
mandel
parents:
diff changeset
1705 }
e78566595089 initial import
mandel
parents:
diff changeset
1706
e78566595089 initial import
mandel
parents:
diff changeset
1707 }
e78566595089 initial import
mandel
parents:
diff changeset
1708
e78566595089 initial import
mandel
parents:
diff changeset
1709 if (typei.isFunctionPointer()) {
e78566595089 initial import
mandel
parents:
diff changeset
1710 *ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
1711 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1712 }
e78566595089 initial import
mandel
parents:
diff changeset
1713
e78566595089 initial import
mandel
parents:
diff changeset
1714 TypeParser::Info typeInfo = TypeParser::parse(typei.toString());
e78566595089 initial import
mandel
parents:
diff changeset
1715 if (typeInfo.is_busted) {
e78566595089 initial import
mandel
parents:
diff changeset
1716 *ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
1717 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1718 }
e78566595089 initial import
mandel
parents:
diff changeset
1719
e78566595089 initial import
mandel
parents:
diff changeset
1720 // 2. Handle pointers specified as arrays with unspecified size
e78566595089 initial import
mandel
parents:
diff changeset
1721 bool array_of_unspecified_size = false;
e78566595089 initial import
mandel
parents:
diff changeset
1722 if (typeInfo.arrays.size() > 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1723 array_of_unspecified_size = true;
e78566595089 initial import
mandel
parents:
diff changeset
1724 for (int i=0; i<typeInfo.arrays.size(); ++i)
e78566595089 initial import
mandel
parents:
diff changeset
1725 array_of_unspecified_size = array_of_unspecified_size && typeInfo.arrays.at(i).isEmpty();
e78566595089 initial import
mandel
parents:
diff changeset
1726
e78566595089 initial import
mandel
parents:
diff changeset
1727 if (!array_of_unspecified_size) {
e78566595089 initial import
mandel
parents:
diff changeset
1728 TypeInfo newInfo;
e78566595089 initial import
mandel
parents:
diff changeset
1729 //newInfo.setArguments(typei.arguments());
e78566595089 initial import
mandel
parents:
diff changeset
1730 newInfo.setIndirections(typei.indirections());
e78566595089 initial import
mandel
parents:
diff changeset
1731 newInfo.setConstant(typei.isConstant());
e78566595089 initial import
mandel
parents:
diff changeset
1732 newInfo.setFunctionPointer(typei.isFunctionPointer());
e78566595089 initial import
mandel
parents:
diff changeset
1733 newInfo.setQualifiedName(typei.qualifiedName());
e78566595089 initial import
mandel
parents:
diff changeset
1734 newInfo.setReference(typei.isReference());
e78566595089 initial import
mandel
parents:
diff changeset
1735 newInfo.setVolatile(typei.isVolatile());
e78566595089 initial import
mandel
parents:
diff changeset
1736
e78566595089 initial import
mandel
parents:
diff changeset
1737 AbstractMetaType *elementType = translateType(newInfo, ok);
e78566595089 initial import
mandel
parents:
diff changeset
1738 if (!ok)
e78566595089 initial import
mandel
parents:
diff changeset
1739 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1740
e78566595089 initial import
mandel
parents:
diff changeset
1741 for (int i=typeInfo.arrays.size()-1; i>=0; --i) {
e78566595089 initial import
mandel
parents:
diff changeset
1742 QString s = typeInfo.arrays.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
1743 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1744
e78566595089 initial import
mandel
parents:
diff changeset
1745 int elems = s.toInt(&ok);
e78566595089 initial import
mandel
parents:
diff changeset
1746 if (!ok)
e78566595089 initial import
mandel
parents:
diff changeset
1747 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1748
e78566595089 initial import
mandel
parents:
diff changeset
1749 AbstractMetaType *arrayType = createMetaType();
e78566595089 initial import
mandel
parents:
diff changeset
1750 arrayType->setArrayElementCount(elems);
e78566595089 initial import
mandel
parents:
diff changeset
1751 arrayType->setArrayElementType(elementType);
e78566595089 initial import
mandel
parents:
diff changeset
1752 arrayType->setTypeEntry(new ArrayTypeEntry(elementType->typeEntry()));
e78566595089 initial import
mandel
parents:
diff changeset
1753 decideUsagePattern(arrayType);
e78566595089 initial import
mandel
parents:
diff changeset
1754
e78566595089 initial import
mandel
parents:
diff changeset
1755 elementType = arrayType;
e78566595089 initial import
mandel
parents:
diff changeset
1756 }
e78566595089 initial import
mandel
parents:
diff changeset
1757
e78566595089 initial import
mandel
parents:
diff changeset
1758 return elementType;
e78566595089 initial import
mandel
parents:
diff changeset
1759 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1760 typeInfo.indirections += typeInfo.arrays.size();
e78566595089 initial import
mandel
parents:
diff changeset
1761 }
e78566595089 initial import
mandel
parents:
diff changeset
1762 }
e78566595089 initial import
mandel
parents:
diff changeset
1763
e78566595089 initial import
mandel
parents:
diff changeset
1764 QStringList qualifier_list = typeInfo.qualified_name;
e78566595089 initial import
mandel
parents:
diff changeset
1765 if (qualifier_list.isEmpty()) {
e78566595089 initial import
mandel
parents:
diff changeset
1766 ReportHandler::warning(QString("horribly broken type '%1'").arg(_typei.toString()));
e78566595089 initial import
mandel
parents:
diff changeset
1767 *ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
1768 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1769 }
e78566595089 initial import
mandel
parents:
diff changeset
1770
e78566595089 initial import
mandel
parents:
diff changeset
1771 QString qualified_name = qualifier_list.join("::");
e78566595089 initial import
mandel
parents:
diff changeset
1772 QString name = qualifier_list.takeLast();
e78566595089 initial import
mandel
parents:
diff changeset
1773
e78566595089 initial import
mandel
parents:
diff changeset
1774 // 3. Special case 'void' type
e78566595089 initial import
mandel
parents:
diff changeset
1775 if (name == "void" && typeInfo.indirections == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1776 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1777 }
e78566595089 initial import
mandel
parents:
diff changeset
1778
e78566595089 initial import
mandel
parents:
diff changeset
1779 // 4. Special case QFlags (include instantiation in name)
e78566595089 initial import
mandel
parents:
diff changeset
1780 if (qualified_name == "QFlags")
e78566595089 initial import
mandel
parents:
diff changeset
1781 qualified_name = typeInfo.toString();
e78566595089 initial import
mandel
parents:
diff changeset
1782
e78566595089 initial import
mandel
parents:
diff changeset
1783 // 5. Try to find the type
e78566595089 initial import
mandel
parents:
diff changeset
1784 const TypeEntry *type = TypeDatabase::instance()->findType(qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
1785
e78566595089 initial import
mandel
parents:
diff changeset
1786 // 6. No? Try looking it up as a flags type
e78566595089 initial import
mandel
parents:
diff changeset
1787 if (!type)
e78566595089 initial import
mandel
parents:
diff changeset
1788 type = TypeDatabase::instance()->findFlagsType(qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
1789
e78566595089 initial import
mandel
parents:
diff changeset
1790 // 7. No? Try looking it up as a container type
e78566595089 initial import
mandel
parents:
diff changeset
1791 if (!type)
e78566595089 initial import
mandel
parents:
diff changeset
1792 type = TypeDatabase::instance()->findContainerType(name);
e78566595089 initial import
mandel
parents:
diff changeset
1793
e78566595089 initial import
mandel
parents:
diff changeset
1794 // 8. No? Check if the current class is a template and this type is one
e78566595089 initial import
mandel
parents:
diff changeset
1795 // of the parameters.
e78566595089 initial import
mandel
parents:
diff changeset
1796 if (type == 0 && m_current_class != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1797 QList<TypeEntry *> template_args = m_current_class->templateArguments();
e78566595089 initial import
mandel
parents:
diff changeset
1798 foreach (TypeEntry *te, template_args) {
e78566595089 initial import
mandel
parents:
diff changeset
1799 if (te->name() == qualified_name)
e78566595089 initial import
mandel
parents:
diff changeset
1800 type = te;
e78566595089 initial import
mandel
parents:
diff changeset
1801 }
e78566595089 initial import
mandel
parents:
diff changeset
1802 }
e78566595089 initial import
mandel
parents:
diff changeset
1803
e78566595089 initial import
mandel
parents:
diff changeset
1804 // 9. Try finding the type by prefixing it with the current
e78566595089 initial import
mandel
parents:
diff changeset
1805 // context and all baseclasses of the current context
e78566595089 initial import
mandel
parents:
diff changeset
1806 if (!type && !TypeDatabase::instance()->isClassRejected(qualified_name) && m_current_class != 0 && resolveScope) {
e78566595089 initial import
mandel
parents:
diff changeset
1807 QStringList contexts;
e78566595089 initial import
mandel
parents:
diff changeset
1808 contexts.append(m_current_class->qualifiedCppName());
e78566595089 initial import
mandel
parents:
diff changeset
1809 contexts.append(currentScope()->qualifiedName().join("::"));
e78566595089 initial import
mandel
parents:
diff changeset
1810
e78566595089 initial import
mandel
parents:
diff changeset
1811
e78566595089 initial import
mandel
parents:
diff changeset
1812 TypeInfo info = typei;
e78566595089 initial import
mandel
parents:
diff changeset
1813 bool subclasses_done = false;
e78566595089 initial import
mandel
parents:
diff changeset
1814 while (!contexts.isEmpty() && type == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1815 //type = TypeDatabase::instance()->findType(contexts.at(0) + "::" + qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
1816
e78566595089 initial import
mandel
parents:
diff changeset
1817 bool ok;
e78566595089 initial import
mandel
parents:
diff changeset
1818 info.setQualifiedName(QStringList() << contexts.at(0) << qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
1819 AbstractMetaType *t = translateType(info, &ok, true, false);
e78566595089 initial import
mandel
parents:
diff changeset
1820 if (t != 0 && ok)
e78566595089 initial import
mandel
parents:
diff changeset
1821 return t;
e78566595089 initial import
mandel
parents:
diff changeset
1822
e78566595089 initial import
mandel
parents:
diff changeset
1823 ClassModelItem item = m_dom->findClass(contexts.at(0));
e78566595089 initial import
mandel
parents:
diff changeset
1824 if (item != 0)
e78566595089 initial import
mandel
parents:
diff changeset
1825 contexts += item->baseClasses();
e78566595089 initial import
mandel
parents:
diff changeset
1826 contexts.pop_front();
e78566595089 initial import
mandel
parents:
diff changeset
1827
e78566595089 initial import
mandel
parents:
diff changeset
1828 // 10. Last resort: Special cased prefix of Qt namespace since the meta object implicitly inherits this, so
e78566595089 initial import
mandel
parents:
diff changeset
1829 // enum types from there may be addressed without any scope resolution in properties.
e78566595089 initial import
mandel
parents:
diff changeset
1830 if (contexts.size() == 0 && !subclasses_done) {
e78566595089 initial import
mandel
parents:
diff changeset
1831 contexts << "Qt";
e78566595089 initial import
mandel
parents:
diff changeset
1832 subclasses_done = true;
e78566595089 initial import
mandel
parents:
diff changeset
1833 }
e78566595089 initial import
mandel
parents:
diff changeset
1834 }
e78566595089 initial import
mandel
parents:
diff changeset
1835
e78566595089 initial import
mandel
parents:
diff changeset
1836 }
e78566595089 initial import
mandel
parents:
diff changeset
1837
e78566595089 initial import
mandel
parents:
diff changeset
1838 if (!type) {
e78566595089 initial import
mandel
parents:
diff changeset
1839 *ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
1840 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1841 }
e78566595089 initial import
mandel
parents:
diff changeset
1842
e78566595089 initial import
mandel
parents:
diff changeset
1843 // Used to for diagnostics later...
e78566595089 initial import
mandel
parents:
diff changeset
1844 m_used_types << type;
e78566595089 initial import
mandel
parents:
diff changeset
1845
e78566595089 initial import
mandel
parents:
diff changeset
1846 // These are only implicit and should not appear in code...
e78566595089 initial import
mandel
parents:
diff changeset
1847 Q_ASSERT(!type->isInterface());
e78566595089 initial import
mandel
parents:
diff changeset
1848
e78566595089 initial import
mandel
parents:
diff changeset
1849 AbstractMetaType *meta_type = createMetaType();
e78566595089 initial import
mandel
parents:
diff changeset
1850 meta_type->setTypeEntry(type);
e78566595089 initial import
mandel
parents:
diff changeset
1851 meta_type->setIndirections(typeInfo.indirections);
e78566595089 initial import
mandel
parents:
diff changeset
1852 meta_type->setReference(typeInfo.is_reference);
e78566595089 initial import
mandel
parents:
diff changeset
1853 meta_type->setConstant(typeInfo.is_constant);
e78566595089 initial import
mandel
parents:
diff changeset
1854 meta_type->setOriginalTypeDescription(_typei.toString());
e78566595089 initial import
mandel
parents:
diff changeset
1855 decideUsagePattern(meta_type);
e78566595089 initial import
mandel
parents:
diff changeset
1856
e78566595089 initial import
mandel
parents:
diff changeset
1857 if (meta_type->typeEntry()->isContainer()) {
e78566595089 initial import
mandel
parents:
diff changeset
1858 ContainerTypeEntry::Type container_type = static_cast<const ContainerTypeEntry *>(type)->type();
e78566595089 initial import
mandel
parents:
diff changeset
1859
e78566595089 initial import
mandel
parents:
diff changeset
1860 if (container_type == ContainerTypeEntry::StringListContainer) {
e78566595089 initial import
mandel
parents:
diff changeset
1861 TypeInfo info;
e78566595089 initial import
mandel
parents:
diff changeset
1862 info.setQualifiedName(QStringList() << "QString");
e78566595089 initial import
mandel
parents:
diff changeset
1863 AbstractMetaType *targ_type = translateType(info, ok);
e78566595089 initial import
mandel
parents:
diff changeset
1864
e78566595089 initial import
mandel
parents:
diff changeset
1865 Q_ASSERT(*ok);
e78566595089 initial import
mandel
parents:
diff changeset
1866 Q_ASSERT(targ_type);
e78566595089 initial import
mandel
parents:
diff changeset
1867
e78566595089 initial import
mandel
parents:
diff changeset
1868 meta_type->addInstantiation(targ_type);
e78566595089 initial import
mandel
parents:
diff changeset
1869 meta_type->setInstantiationInCpp(false);
e78566595089 initial import
mandel
parents:
diff changeset
1870
e78566595089 initial import
mandel
parents:
diff changeset
1871 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1872 foreach (const TypeParser::Info &ta, typeInfo.template_instantiations) {
e78566595089 initial import
mandel
parents:
diff changeset
1873 TypeInfo info;
e78566595089 initial import
mandel
parents:
diff changeset
1874 info.setConstant(ta.is_constant);
e78566595089 initial import
mandel
parents:
diff changeset
1875 info.setReference(ta.is_reference);
e78566595089 initial import
mandel
parents:
diff changeset
1876 info.setIndirections(ta.indirections);
e78566595089 initial import
mandel
parents:
diff changeset
1877
e78566595089 initial import
mandel
parents:
diff changeset
1878 info.setFunctionPointer(false);
e78566595089 initial import
mandel
parents:
diff changeset
1879 info.setQualifiedName(ta.instantiationName().split("::"));
e78566595089 initial import
mandel
parents:
diff changeset
1880
e78566595089 initial import
mandel
parents:
diff changeset
1881 AbstractMetaType *targ_type = translateType(info, ok);
e78566595089 initial import
mandel
parents:
diff changeset
1882 if (!(*ok)) {
e78566595089 initial import
mandel
parents:
diff changeset
1883 delete meta_type;
e78566595089 initial import
mandel
parents:
diff changeset
1884 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
1885 }
e78566595089 initial import
mandel
parents:
diff changeset
1886
e78566595089 initial import
mandel
parents:
diff changeset
1887 meta_type->addInstantiation(targ_type);
e78566595089 initial import
mandel
parents:
diff changeset
1888 }
e78566595089 initial import
mandel
parents:
diff changeset
1889 }
e78566595089 initial import
mandel
parents:
diff changeset
1890
e78566595089 initial import
mandel
parents:
diff changeset
1891 if (container_type == ContainerTypeEntry::ListContainer
e78566595089 initial import
mandel
parents:
diff changeset
1892 || container_type == ContainerTypeEntry::VectorContainer
e78566595089 initial import
mandel
parents:
diff changeset
1893 || container_type == ContainerTypeEntry::StringListContainer) {
e78566595089 initial import
mandel
parents:
diff changeset
1894 Q_ASSERT(meta_type->instantiations().size() == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1895 }
e78566595089 initial import
mandel
parents:
diff changeset
1896 }
e78566595089 initial import
mandel
parents:
diff changeset
1897
e78566595089 initial import
mandel
parents:
diff changeset
1898 return meta_type;
e78566595089 initial import
mandel
parents:
diff changeset
1899 }
e78566595089 initial import
mandel
parents:
diff changeset
1900
e78566595089 initial import
mandel
parents:
diff changeset
1901 void AbstractMetaBuilder::decideUsagePattern(AbstractMetaType *meta_type)
e78566595089 initial import
mandel
parents:
diff changeset
1902 {
e78566595089 initial import
mandel
parents:
diff changeset
1903 const TypeEntry *type = meta_type->typeEntry();
e78566595089 initial import
mandel
parents:
diff changeset
1904
e78566595089 initial import
mandel
parents:
diff changeset
1905 if (type->isPrimitive() && (meta_type->actualIndirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1906 || (meta_type->isConstant() && meta_type->isReference() && meta_type->indirections() == 0))) {
e78566595089 initial import
mandel
parents:
diff changeset
1907 meta_type->setTypeUsagePattern(AbstractMetaType::PrimitivePattern);
e78566595089 initial import
mandel
parents:
diff changeset
1908
e78566595089 initial import
mandel
parents:
diff changeset
1909 } else if (type->isVoid()) {
e78566595089 initial import
mandel
parents:
diff changeset
1910 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1911
e78566595089 initial import
mandel
parents:
diff changeset
1912 } else if (type->isString()
e78566595089 initial import
mandel
parents:
diff changeset
1913 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1914 && (meta_type->isConstant() == meta_type->isReference()
e78566595089 initial import
mandel
parents:
diff changeset
1915 || meta_type->isConstant())) {
e78566595089 initial import
mandel
parents:
diff changeset
1916 meta_type->setTypeUsagePattern(AbstractMetaType::StringPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1917
e78566595089 initial import
mandel
parents:
diff changeset
1918 } else if (type->isChar()
e78566595089 initial import
mandel
parents:
diff changeset
1919 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1920 && meta_type->isConstant() == meta_type->isReference()) {
e78566595089 initial import
mandel
parents:
diff changeset
1921 meta_type->setTypeUsagePattern(AbstractMetaType::CharPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1922
e78566595089 initial import
mandel
parents:
diff changeset
1923 } else if (type->isJObjectWrapper()
e78566595089 initial import
mandel
parents:
diff changeset
1924 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1925 && meta_type->isConstant() == meta_type->isReference()) {
e78566595089 initial import
mandel
parents:
diff changeset
1926 meta_type->setTypeUsagePattern(AbstractMetaType::JObjectWrapperPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1927
e78566595089 initial import
mandel
parents:
diff changeset
1928 } else if (type->isVariant()
e78566595089 initial import
mandel
parents:
diff changeset
1929 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1930 && meta_type->isConstant() == meta_type->isReference()) {
e78566595089 initial import
mandel
parents:
diff changeset
1931 meta_type->setTypeUsagePattern(AbstractMetaType::VariantPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1932
e78566595089 initial import
mandel
parents:
diff changeset
1933 } else if (type->isEnum() && meta_type->actualIndirections() == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1934 meta_type->setTypeUsagePattern(AbstractMetaType::EnumPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1935
e78566595089 initial import
mandel
parents:
diff changeset
1936 } else if (type->isObject()
e78566595089 initial import
mandel
parents:
diff changeset
1937 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1938 && meta_type->isReference()) {
e78566595089 initial import
mandel
parents:
diff changeset
1939 if (((ComplexTypeEntry *) type)->isQObject())
e78566595089 initial import
mandel
parents:
diff changeset
1940 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1941 else
e78566595089 initial import
mandel
parents:
diff changeset
1942 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1943
e78566595089 initial import
mandel
parents:
diff changeset
1944 } else if (type->isObject()
e78566595089 initial import
mandel
parents:
diff changeset
1945 && meta_type->indirections() == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
1946 if (((ComplexTypeEntry *) type)->isQObject())
e78566595089 initial import
mandel
parents:
diff changeset
1947 meta_type->setTypeUsagePattern(AbstractMetaType::QObjectPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1948 else
e78566595089 initial import
mandel
parents:
diff changeset
1949 meta_type->setTypeUsagePattern(AbstractMetaType::ObjectPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1950
e78566595089 initial import
mandel
parents:
diff changeset
1951 // const-references to pointers can be passed as pointers
e78566595089 initial import
mandel
parents:
diff changeset
1952 if (meta_type->isReference() && meta_type->isConstant()) {
e78566595089 initial import
mandel
parents:
diff changeset
1953 meta_type->setReference(false);
e78566595089 initial import
mandel
parents:
diff changeset
1954 meta_type->setConstant(false);
e78566595089 initial import
mandel
parents:
diff changeset
1955 }
e78566595089 initial import
mandel
parents:
diff changeset
1956
e78566595089 initial import
mandel
parents:
diff changeset
1957 } else if (type->isContainer() && meta_type->indirections() == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1958 meta_type->setTypeUsagePattern(AbstractMetaType::ContainerPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1959
e78566595089 initial import
mandel
parents:
diff changeset
1960 } else if (type->isTemplateArgument()) {
e78566595089 initial import
mandel
parents:
diff changeset
1961
e78566595089 initial import
mandel
parents:
diff changeset
1962 } else if (type->isFlags()
e78566595089 initial import
mandel
parents:
diff changeset
1963 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1964 && (meta_type->isConstant() == meta_type->isReference())) {
e78566595089 initial import
mandel
parents:
diff changeset
1965 meta_type->setTypeUsagePattern(AbstractMetaType::FlagsPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1966
e78566595089 initial import
mandel
parents:
diff changeset
1967 } else if (type->isArray()) {
e78566595089 initial import
mandel
parents:
diff changeset
1968 meta_type->setTypeUsagePattern(AbstractMetaType::ArrayPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1969
e78566595089 initial import
mandel
parents:
diff changeset
1970 } else if (type->isThread()) {
e78566595089 initial import
mandel
parents:
diff changeset
1971 Q_ASSERT(meta_type->indirections() == 1);
e78566595089 initial import
mandel
parents:
diff changeset
1972 meta_type->setTypeUsagePattern(AbstractMetaType::ThreadPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1973
e78566595089 initial import
mandel
parents:
diff changeset
1974 } else if (type->isValue()
e78566595089 initial import
mandel
parents:
diff changeset
1975 && meta_type->indirections() == 0
e78566595089 initial import
mandel
parents:
diff changeset
1976 && (meta_type->isConstant() == meta_type->isReference()
e78566595089 initial import
mandel
parents:
diff changeset
1977 || !meta_type->isReference())) {
e78566595089 initial import
mandel
parents:
diff changeset
1978 meta_type->setTypeUsagePattern(AbstractMetaType::ValuePattern);
e78566595089 initial import
mandel
parents:
diff changeset
1979
e78566595089 initial import
mandel
parents:
diff changeset
1980 } else if (type->isObject() && meta_type->actualIndirections() == 0) {
e78566595089 initial import
mandel
parents:
diff changeset
1981
e78566595089 initial import
mandel
parents:
diff changeset
1982 ReportHandler::warning(QString("Object type '%1' passed as value. Resulting code will not compile.")
e78566595089 initial import
mandel
parents:
diff changeset
1983 .arg(meta_type->cppSignature()));
e78566595089 initial import
mandel
parents:
diff changeset
1984 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1985
e78566595089 initial import
mandel
parents:
diff changeset
1986 } else {
e78566595089 initial import
mandel
parents:
diff changeset
1987 meta_type->setTypeUsagePattern(AbstractMetaType::NativePointerPattern);
e78566595089 initial import
mandel
parents:
diff changeset
1988 ReportHandler::debugFull(QString("native pointer pattern for '%1'")
e78566595089 initial import
mandel
parents:
diff changeset
1989 .arg(meta_type->cppSignature()));
e78566595089 initial import
mandel
parents:
diff changeset
1990 }
e78566595089 initial import
mandel
parents:
diff changeset
1991 }
e78566595089 initial import
mandel
parents:
diff changeset
1992
e78566595089 initial import
mandel
parents:
diff changeset
1993 QString AbstractMetaBuilder::translateDefaultValue(ArgumentModelItem item, AbstractMetaType *type,
e78566595089 initial import
mandel
parents:
diff changeset
1994 AbstractMetaFunction *fnc, AbstractMetaClass *implementing_class,
e78566595089 initial import
mandel
parents:
diff changeset
1995 int argument_index)
e78566595089 initial import
mandel
parents:
diff changeset
1996 {
e78566595089 initial import
mandel
parents:
diff changeset
1997 QString function_name = fnc->name();
e78566595089 initial import
mandel
parents:
diff changeset
1998 QString class_name = implementing_class->name();
e78566595089 initial import
mandel
parents:
diff changeset
1999
e78566595089 initial import
mandel
parents:
diff changeset
2000 QString replaced_expression = fnc->replacedDefaultExpression(implementing_class, argument_index + 1);
e78566595089 initial import
mandel
parents:
diff changeset
2001 if (fnc->removedDefaultExpression(implementing_class, argument_index +1))
e78566595089 initial import
mandel
parents:
diff changeset
2002 return "";
e78566595089 initial import
mandel
parents:
diff changeset
2003 if (!replaced_expression.isEmpty())
e78566595089 initial import
mandel
parents:
diff changeset
2004 return replaced_expression;
e78566595089 initial import
mandel
parents:
diff changeset
2005
e78566595089 initial import
mandel
parents:
diff changeset
2006 QString expr = item->defaultValueExpression();
e78566595089 initial import
mandel
parents:
diff changeset
2007 if (type->isPrimitive()) {
e78566595089 initial import
mandel
parents:
diff changeset
2008 if (type->name() == "boolean") {
e78566595089 initial import
mandel
parents:
diff changeset
2009 if (expr == "false" || expr=="true") {
e78566595089 initial import
mandel
parents:
diff changeset
2010 return expr;
e78566595089 initial import
mandel
parents:
diff changeset
2011 } else {
e78566595089 initial import
mandel
parents:
diff changeset
2012 bool ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
2013 int number = expr.toInt(&ok);
e78566595089 initial import
mandel
parents:
diff changeset
2014 if (ok && number)
e78566595089 initial import
mandel
parents:
diff changeset
2015 return "true";
e78566595089 initial import
mandel
parents:
diff changeset
2016 else
e78566595089 initial import
mandel
parents:
diff changeset
2017 return "false";
e78566595089 initial import
mandel
parents:
diff changeset
2018 }
e78566595089 initial import
mandel
parents:
diff changeset
2019 } else if (expr == "ULONG_MAX") {
e78566595089 initial import
mandel
parents:
diff changeset
2020 return "Long.MAX_VALUE";
e78566595089 initial import
mandel
parents:
diff changeset
2021 } else if (expr == "QVariant::Invalid") {
e78566595089 initial import
mandel
parents:
diff changeset
2022 return QString::number(QVariant::Invalid);
e78566595089 initial import
mandel
parents:
diff changeset
2023 } else {
e78566595089 initial import
mandel
parents:
diff changeset
2024 // This can be an enum or flag so I need to delay the
e78566595089 initial import
mandel
parents:
diff changeset
2025 // translation untill all namespaces are completly
e78566595089 initial import
mandel
parents:
diff changeset
2026 // processed. This is done in figureOutEnumValues()
e78566595089 initial import
mandel
parents:
diff changeset
2027 return expr;
e78566595089 initial import
mandel
parents:
diff changeset
2028 }
e78566595089 initial import
mandel
parents:
diff changeset
2029 } else if (type != 0 && (type->isFlags() || type->isEnum())) {
e78566595089 initial import
mandel
parents:
diff changeset
2030 // Same as with enum explanation above...
e78566595089 initial import
mandel
parents:
diff changeset
2031 return expr;
e78566595089 initial import
mandel
parents:
diff changeset
2032
e78566595089 initial import
mandel
parents:
diff changeset
2033 } else {
e78566595089 initial import
mandel
parents:
diff changeset
2034
e78566595089 initial import
mandel
parents:
diff changeset
2035 // constructor or functioncall can be a bit tricky...
e78566595089 initial import
mandel
parents:
diff changeset
2036 if (expr == "QVariant()" /* qtd || expr == "QModelIndex()"*/) {
e78566595089 initial import
mandel
parents:
diff changeset
2037 return "null";
e78566595089 initial import
mandel
parents:
diff changeset
2038 } else if (expr == "QString()") {
e78566595089 initial import
mandel
parents:
diff changeset
2039 return "null";
e78566595089 initial import
mandel
parents:
diff changeset
2040 } else if (expr.endsWith(")") && expr.contains("::")) {
e78566595089 initial import
mandel
parents:
diff changeset
2041 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
e78566595089 initial import
mandel
parents:
diff changeset
2042 if (typeEntry)
e78566595089 initial import
mandel
parents:
diff changeset
2043 return typeEntry->qualifiedTargetLangName() + "." + expr.right(expr.length() - expr.indexOf("::") - 2);
e78566595089 initial import
mandel
parents:
diff changeset
2044 } else if (expr.endsWith(")") && type->isValue()) {
e78566595089 initial import
mandel
parents:
diff changeset
2045 int pos = expr.indexOf("(");
e78566595089 initial import
mandel
parents:
diff changeset
2046
e78566595089 initial import
mandel
parents:
diff changeset
2047 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(pos));
e78566595089 initial import
mandel
parents:
diff changeset
2048 if (typeEntry) { // qtd
e78566595089 initial import
mandel
parents:
diff changeset
2049 if(typeEntry->isStructInD())
e78566595089 initial import
mandel
parents:
diff changeset
2050 return typeEntry->qualifiedCppName() + expr.right(expr.length() - pos);
e78566595089 initial import
mandel
parents:
diff changeset
2051 else
e78566595089 initial import
mandel
parents:
diff changeset
2052 return "new " + typeEntry->qualifiedCppName() + expr.right(expr.length() - pos);
e78566595089 initial import
mandel
parents:
diff changeset
2053 } else
e78566595089 initial import
mandel
parents:
diff changeset
2054 return expr;
e78566595089 initial import
mandel
parents:
diff changeset
2055 } else if (expr == "0") {
e78566595089 initial import
mandel
parents:
diff changeset
2056 return "null";
e78566595089 initial import
mandel
parents:
diff changeset
2057 } else if (type->isObject() || type->isValue() || expr.contains("::")) { // like Qt::black passed to a QColor
e78566595089 initial import
mandel
parents:
diff changeset
2058 TypeEntry *typeEntry = TypeDatabase::instance()->findType(expr.left(expr.indexOf("::")));
e78566595089 initial import
mandel
parents:
diff changeset
2059
e78566595089 initial import
mandel
parents:
diff changeset
2060 expr = expr.right(expr.length() - expr.indexOf("::") - 2);
e78566595089 initial import
mandel
parents:
diff changeset
2061 if (typeEntry) {
e78566595089 initial import
mandel
parents:
diff changeset
2062 return "new " + type->typeEntry()->qualifiedCppName() +
e78566595089 initial import
mandel
parents:
diff changeset
2063 "(" + typeEntry->qualifiedCppName() + "." + expr + ")";
e78566595089 initial import
mandel
parents:
diff changeset
2064 }
e78566595089 initial import
mandel
parents:
diff changeset
2065 }
e78566595089 initial import
mandel
parents:
diff changeset
2066 }
e78566595089 initial import
mandel
parents:
diff changeset
2067
e78566595089 initial import
mandel
parents:
diff changeset
2068 QString warn = QString("unsupported default value '%3' of argument in function '%1', class '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
2069 .arg(function_name).arg(class_name).arg(item->defaultValueExpression());
e78566595089 initial import
mandel
parents:
diff changeset
2070 ReportHandler::warning(warn);
e78566595089 initial import
mandel
parents:
diff changeset
2071
e78566595089 initial import
mandel
parents:
diff changeset
2072 return QString();
e78566595089 initial import
mandel
parents:
diff changeset
2073 }
e78566595089 initial import
mandel
parents:
diff changeset
2074
e78566595089 initial import
mandel
parents:
diff changeset
2075
e78566595089 initial import
mandel
parents:
diff changeset
2076 bool AbstractMetaBuilder::isQObject(const QString &qualified_name)
e78566595089 initial import
mandel
parents:
diff changeset
2077 {
e78566595089 initial import
mandel
parents:
diff changeset
2078 if (qualified_name == "QObject")
e78566595089 initial import
mandel
parents:
diff changeset
2079 return true;
e78566595089 initial import
mandel
parents:
diff changeset
2080
e78566595089 initial import
mandel
parents:
diff changeset
2081 ClassModelItem class_item = m_dom->findClass(qualified_name);
e78566595089 initial import
mandel
parents:
diff changeset
2082
e78566595089 initial import
mandel
parents:
diff changeset
2083 if (!class_item) {
e78566595089 initial import
mandel
parents:
diff changeset
2084 QStringList names = qualified_name.split(QLatin1String("::"));
e78566595089 initial import
mandel
parents:
diff changeset
2085 NamespaceModelItem ns = model_dynamic_cast<NamespaceModelItem>(m_dom);
e78566595089 initial import
mandel
parents:
diff changeset
2086 for (int i=0; i<names.size() - 1 && ns; ++i)
e78566595089 initial import
mandel
parents:
diff changeset
2087 ns = ns->namespaceMap().value(names.at(i));
e78566595089 initial import
mandel
parents:
diff changeset
2088 if (ns && names.size() >= 2)
e78566595089 initial import
mandel
parents:
diff changeset
2089 class_item = ns->findClass(names.at(names.size() - 1));
e78566595089 initial import
mandel
parents:
diff changeset
2090 }
e78566595089 initial import
mandel
parents:
diff changeset
2091
e78566595089 initial import
mandel
parents:
diff changeset
2092 bool isqobject = class_item && class_item->extendsClass("QObject");
e78566595089 initial import
mandel
parents:
diff changeset
2093
e78566595089 initial import
mandel
parents:
diff changeset
2094 if (class_item && !isqobject) {
e78566595089 initial import
mandel
parents:
diff changeset
2095 QStringList baseClasses = class_item->baseClasses();
e78566595089 initial import
mandel
parents:
diff changeset
2096 for (int i=0; i<baseClasses.count(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
2097
e78566595089 initial import
mandel
parents:
diff changeset
2098 isqobject = isQObject(baseClasses.at(i));
e78566595089 initial import
mandel
parents:
diff changeset
2099 if (isqobject)
e78566595089 initial import
mandel
parents:
diff changeset
2100 break;
e78566595089 initial import
mandel
parents:
diff changeset
2101 }
e78566595089 initial import
mandel
parents:
diff changeset
2102 }
e78566595089 initial import
mandel
parents:
diff changeset
2103
e78566595089 initial import
mandel
parents:
diff changeset
2104 return isqobject;
e78566595089 initial import
mandel
parents:
diff changeset
2105 }
e78566595089 initial import
mandel
parents:
diff changeset
2106
e78566595089 initial import
mandel
parents:
diff changeset
2107
e78566595089 initial import
mandel
parents:
diff changeset
2108 bool AbstractMetaBuilder::isEnum(const QStringList &qualified_name)
e78566595089 initial import
mandel
parents:
diff changeset
2109 {
e78566595089 initial import
mandel
parents:
diff changeset
2110 CodeModelItem item = m_dom->model()->findItem(qualified_name, m_dom->toItem());
e78566595089 initial import
mandel
parents:
diff changeset
2111 return item && item->kind() == _EnumModelItem::__node_kind;
e78566595089 initial import
mandel
parents:
diff changeset
2112 }
e78566595089 initial import
mandel
parents:
diff changeset
2113
e78566595089 initial import
mandel
parents:
diff changeset
2114 AbstractMetaType *AbstractMetaBuilder::inheritTemplateType(const QList<AbstractMetaType *> &template_types,
e78566595089 initial import
mandel
parents:
diff changeset
2115 AbstractMetaType *meta_type, bool *ok)
e78566595089 initial import
mandel
parents:
diff changeset
2116 {
e78566595089 initial import
mandel
parents:
diff changeset
2117 if (ok != 0)
e78566595089 initial import
mandel
parents:
diff changeset
2118 *ok = true;
e78566595089 initial import
mandel
parents:
diff changeset
2119 if (!meta_type || (!meta_type->typeEntry()->isTemplateArgument() && !meta_type->hasInstantiations()))
e78566595089 initial import
mandel
parents:
diff changeset
2120 return meta_type ? meta_type->copy() : 0;
e78566595089 initial import
mandel
parents:
diff changeset
2121
e78566595089 initial import
mandel
parents:
diff changeset
2122 AbstractMetaType *returned = meta_type->copy();
e78566595089 initial import
mandel
parents:
diff changeset
2123 returned->setOriginalTemplateType(meta_type->copy());
e78566595089 initial import
mandel
parents:
diff changeset
2124
e78566595089 initial import
mandel
parents:
diff changeset
2125 if (returned->typeEntry()->isTemplateArgument()) {
e78566595089 initial import
mandel
parents:
diff changeset
2126 const TemplateArgumentEntry *tae = static_cast<const TemplateArgumentEntry *>(returned->typeEntry());
e78566595089 initial import
mandel
parents:
diff changeset
2127
e78566595089 initial import
mandel
parents:
diff changeset
2128 // If the template is intantiated with void we special case this as rejecting the functions that use this
e78566595089 initial import
mandel
parents:
diff changeset
2129 // parameter from the instantiation.
e78566595089 initial import
mandel
parents:
diff changeset
2130 if (template_types.size() <= tae->ordinal() || template_types.at(tae->ordinal())->typeEntry()->name() == "void") {
e78566595089 initial import
mandel
parents:
diff changeset
2131 if (ok != 0)
e78566595089 initial import
mandel
parents:
diff changeset
2132 *ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
2133 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
2134 }
e78566595089 initial import
mandel
parents:
diff changeset
2135
e78566595089 initial import
mandel
parents:
diff changeset
2136 AbstractMetaType *t = returned->copy();
e78566595089 initial import
mandel
parents:
diff changeset
2137 t->setTypeEntry(template_types.at(tae->ordinal())->typeEntry());
e78566595089 initial import
mandel
parents:
diff changeset
2138 t->setIndirections(template_types.at(tae->ordinal())->indirections() + t->indirections()
e78566595089 initial import
mandel
parents:
diff changeset
2139 ? 1
e78566595089 initial import
mandel
parents:
diff changeset
2140 : 0);
e78566595089 initial import
mandel
parents:
diff changeset
2141 decideUsagePattern(t);
e78566595089 initial import
mandel
parents:
diff changeset
2142
e78566595089 initial import
mandel
parents:
diff changeset
2143 delete returned;
e78566595089 initial import
mandel
parents:
diff changeset
2144 returned = inheritTemplateType(template_types, t, ok);
e78566595089 initial import
mandel
parents:
diff changeset
2145 if (ok != 0 && !(*ok))
e78566595089 initial import
mandel
parents:
diff changeset
2146 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
2147 }
e78566595089 initial import
mandel
parents:
diff changeset
2148
e78566595089 initial import
mandel
parents:
diff changeset
2149 if (returned->hasInstantiations()) {
e78566595089 initial import
mandel
parents:
diff changeset
2150 QList<AbstractMetaType *> instantiations = returned->instantiations();
e78566595089 initial import
mandel
parents:
diff changeset
2151 for (int i=0; i<instantiations.count(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
2152 instantiations[i] = inheritTemplateType(template_types, instantiations.at(i), ok);
e78566595089 initial import
mandel
parents:
diff changeset
2153 if (ok != 0 && !(*ok))
e78566595089 initial import
mandel
parents:
diff changeset
2154 return 0;
e78566595089 initial import
mandel
parents:
diff changeset
2155 }
e78566595089 initial import
mandel
parents:
diff changeset
2156 returned->setInstantiations(instantiations);
e78566595089 initial import
mandel
parents:
diff changeset
2157 }
e78566595089 initial import
mandel
parents:
diff changeset
2158
e78566595089 initial import
mandel
parents:
diff changeset
2159 return returned;
e78566595089 initial import
mandel
parents:
diff changeset
2160 }
e78566595089 initial import
mandel
parents:
diff changeset
2161
e78566595089 initial import
mandel
parents:
diff changeset
2162 bool AbstractMetaBuilder::inheritTemplate(AbstractMetaClass *subclass,
e78566595089 initial import
mandel
parents:
diff changeset
2163 const AbstractMetaClass *template_class,
e78566595089 initial import
mandel
parents:
diff changeset
2164 const TypeParser::Info &info)
e78566595089 initial import
mandel
parents:
diff changeset
2165 {
e78566595089 initial import
mandel
parents:
diff changeset
2166 QList<TypeParser::Info> targs = info.template_instantiations;
e78566595089 initial import
mandel
parents:
diff changeset
2167
e78566595089 initial import
mandel
parents:
diff changeset
2168 QList<AbstractMetaType *> template_types;
e78566595089 initial import
mandel
parents:
diff changeset
2169 foreach (const TypeParser::Info &i, targs) {
e78566595089 initial import
mandel
parents:
diff changeset
2170 TypeEntry *t = TypeDatabase::instance()->findType(i.qualified_name.join("::"));
e78566595089 initial import
mandel
parents:
diff changeset
2171
e78566595089 initial import
mandel
parents:
diff changeset
2172 if (t != 0) {
e78566595089 initial import
mandel
parents:
diff changeset
2173 AbstractMetaType *temporary_type = createMetaType();
e78566595089 initial import
mandel
parents:
diff changeset
2174 temporary_type->setTypeEntry(t);
e78566595089 initial import
mandel
parents:
diff changeset
2175 temporary_type->setConstant(i.is_constant);
e78566595089 initial import
mandel
parents:
diff changeset
2176 temporary_type->setReference(i.is_reference);
e78566595089 initial import
mandel
parents:
diff changeset
2177 temporary_type->setIndirections(i.indirections);
e78566595089 initial import
mandel
parents:
diff changeset
2178 template_types << temporary_type;
e78566595089 initial import
mandel
parents:
diff changeset
2179 }
e78566595089 initial import
mandel
parents:
diff changeset
2180 }
e78566595089 initial import
mandel
parents:
diff changeset
2181
e78566595089 initial import
mandel
parents:
diff changeset
2182 AbstractMetaFunctionList funcs = subclass->functions();
e78566595089 initial import
mandel
parents:
diff changeset
2183 foreach (const AbstractMetaFunction *function, template_class->functions()) {
e78566595089 initial import
mandel
parents:
diff changeset
2184
e78566595089 initial import
mandel
parents:
diff changeset
2185 if (function->isModifiedRemoved(TypeSystem::All))
e78566595089 initial import
mandel
parents:
diff changeset
2186 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2187
e78566595089 initial import
mandel
parents:
diff changeset
2188 AbstractMetaFunction *f = function->copy();
e78566595089 initial import
mandel
parents:
diff changeset
2189 f->setArguments(AbstractMetaArgumentList());
e78566595089 initial import
mandel
parents:
diff changeset
2190
e78566595089 initial import
mandel
parents:
diff changeset
2191 bool ok = true;
e78566595089 initial import
mandel
parents:
diff changeset
2192 AbstractMetaType *ftype = function->type();
e78566595089 initial import
mandel
parents:
diff changeset
2193 f->setType(inheritTemplateType(template_types, ftype, &ok));
e78566595089 initial import
mandel
parents:
diff changeset
2194 if (!ok) {
e78566595089 initial import
mandel
parents:
diff changeset
2195 delete f;
e78566595089 initial import
mandel
parents:
diff changeset
2196 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2197 }
e78566595089 initial import
mandel
parents:
diff changeset
2198
e78566595089 initial import
mandel
parents:
diff changeset
2199 foreach (AbstractMetaArgument *argument, function->arguments()) {
e78566595089 initial import
mandel
parents:
diff changeset
2200 AbstractMetaType *atype = argument->type();
e78566595089 initial import
mandel
parents:
diff changeset
2201
e78566595089 initial import
mandel
parents:
diff changeset
2202 AbstractMetaArgument *arg = argument->copy();
e78566595089 initial import
mandel
parents:
diff changeset
2203 arg->setType(inheritTemplateType(template_types, atype, &ok));
e78566595089 initial import
mandel
parents:
diff changeset
2204 if (!ok)
e78566595089 initial import
mandel
parents:
diff changeset
2205 break;
e78566595089 initial import
mandel
parents:
diff changeset
2206 f->addArgument(arg);
e78566595089 initial import
mandel
parents:
diff changeset
2207 }
e78566595089 initial import
mandel
parents:
diff changeset
2208
e78566595089 initial import
mandel
parents:
diff changeset
2209 if (!ok) {
e78566595089 initial import
mandel
parents:
diff changeset
2210 delete f;
e78566595089 initial import
mandel
parents:
diff changeset
2211 continue ;
e78566595089 initial import
mandel
parents:
diff changeset
2212 }
e78566595089 initial import
mandel
parents:
diff changeset
2213
e78566595089 initial import
mandel
parents:
diff changeset
2214 // There is no base class in java to inherit from here, so the
e78566595089 initial import
mandel
parents:
diff changeset
2215 // template instantiation is the class that implements the function..
e78566595089 initial import
mandel
parents:
diff changeset
2216 f->setImplementingClass(subclass);
e78566595089 initial import
mandel
parents:
diff changeset
2217
e78566595089 initial import
mandel
parents:
diff changeset
2218 // We also set it as the declaring class, since the superclass is
e78566595089 initial import
mandel
parents:
diff changeset
2219 // supposed to disappear. This allows us to make certain function modifications
e78566595089 initial import
mandel
parents:
diff changeset
2220 // on the inherited functions.
e78566595089 initial import
mandel
parents:
diff changeset
2221 f->setDeclaringClass(subclass);
e78566595089 initial import
mandel
parents:
diff changeset
2222
e78566595089 initial import
mandel
parents:
diff changeset
2223
e78566595089 initial import
mandel
parents:
diff changeset
2224 if (f->isConstructor() && subclass->isTypeAlias()) {
e78566595089 initial import
mandel
parents:
diff changeset
2225 f->setName(subclass->name());
e78566595089 initial import
mandel
parents:
diff changeset
2226 } else if (f->isConstructor()) {
e78566595089 initial import
mandel
parents:
diff changeset
2227 delete f;
e78566595089 initial import
mandel
parents:
diff changeset
2228 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2229 }
e78566595089 initial import
mandel
parents:
diff changeset
2230
e78566595089 initial import
mandel
parents:
diff changeset
2231 // if the instantiation has a function named the same as an existing
e78566595089 initial import
mandel
parents:
diff changeset
2232 // function we have shadowing so we need to skip it.
e78566595089 initial import
mandel
parents:
diff changeset
2233 bool found = false;
e78566595089 initial import
mandel
parents:
diff changeset
2234 for (int i=0; i<funcs.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
2235 if (funcs.at(i)->name() == f->name()) {
e78566595089 initial import
mandel
parents:
diff changeset
2236 found = true;
e78566595089 initial import
mandel
parents:
diff changeset
2237 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2238 }
e78566595089 initial import
mandel
parents:
diff changeset
2239 }
e78566595089 initial import
mandel
parents:
diff changeset
2240 if (found) {
e78566595089 initial import
mandel
parents:
diff changeset
2241 delete f;
e78566595089 initial import
mandel
parents:
diff changeset
2242 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2243 }
e78566595089 initial import
mandel
parents:
diff changeset
2244
e78566595089 initial import
mandel
parents:
diff changeset
2245 ComplexTypeEntry *te = subclass->typeEntry();
e78566595089 initial import
mandel
parents:
diff changeset
2246 FunctionModificationList mods = function->modifications(template_class);
e78566595089 initial import
mandel
parents:
diff changeset
2247 for (int i=0; i<mods.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
2248 FunctionModification mod = mods.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
2249 mod.signature = f->minimalSignature();
e78566595089 initial import
mandel
parents:
diff changeset
2250
e78566595089 initial import
mandel
parents:
diff changeset
2251 // If we ever need it... Below is the code to do
e78566595089 initial import
mandel
parents:
diff changeset
2252 // substitution of the template instantation type inside
e78566595089 initial import
mandel
parents:
diff changeset
2253 // injected code..
e78566595089 initial import
mandel
parents:
diff changeset
2254 #if 0
e78566595089 initial import
mandel
parents:
diff changeset
2255 if (mod.modifiers & Modification::CodeInjection) {
e78566595089 initial import
mandel
parents:
diff changeset
2256 for (int j=0; j<template_types.size(); ++j) {
e78566595089 initial import
mandel
parents:
diff changeset
2257 CodeSnip &snip = mod.snips.last();
e78566595089 initial import
mandel
parents:
diff changeset
2258 QString code = snip.code();
e78566595089 initial import
mandel
parents:
diff changeset
2259 code.replace(QString::fromLatin1("$$QT_TEMPLATE_%1$$").arg(j),
e78566595089 initial import
mandel
parents:
diff changeset
2260 template_types.at(j)->typeEntry()->qualifiedCppName());
e78566595089 initial import
mandel
parents:
diff changeset
2261 snip.codeList.clear();
e78566595089 initial import
mandel
parents:
diff changeset
2262 snip.addCode(code);
e78566595089 initial import
mandel
parents:
diff changeset
2263 }
e78566595089 initial import
mandel
parents:
diff changeset
2264 }
e78566595089 initial import
mandel
parents:
diff changeset
2265 #endif
e78566595089 initial import
mandel
parents:
diff changeset
2266 te->addFunctionModification(mod);
e78566595089 initial import
mandel
parents:
diff changeset
2267 }
e78566595089 initial import
mandel
parents:
diff changeset
2268
e78566595089 initial import
mandel
parents:
diff changeset
2269 subclass->addFunction(f);
e78566595089 initial import
mandel
parents:
diff changeset
2270 }
e78566595089 initial import
mandel
parents:
diff changeset
2271
e78566595089 initial import
mandel
parents:
diff changeset
2272 // Clean up
e78566595089 initial import
mandel
parents:
diff changeset
2273 foreach (AbstractMetaType *type, template_types) {
e78566595089 initial import
mandel
parents:
diff changeset
2274 delete type;
e78566595089 initial import
mandel
parents:
diff changeset
2275 }
e78566595089 initial import
mandel
parents:
diff changeset
2276
e78566595089 initial import
mandel
parents:
diff changeset
2277
e78566595089 initial import
mandel
parents:
diff changeset
2278 {
e78566595089 initial import
mandel
parents:
diff changeset
2279 subclass->setTemplateBaseClass(template_class);
e78566595089 initial import
mandel
parents:
diff changeset
2280
e78566595089 initial import
mandel
parents:
diff changeset
2281 subclass->setInterfaces(template_class->interfaces());
e78566595089 initial import
mandel
parents:
diff changeset
2282 subclass->setBaseClass(template_class->baseClass());
e78566595089 initial import
mandel
parents:
diff changeset
2283 }
e78566595089 initial import
mandel
parents:
diff changeset
2284
e78566595089 initial import
mandel
parents:
diff changeset
2285 return true;
e78566595089 initial import
mandel
parents:
diff changeset
2286 }
e78566595089 initial import
mandel
parents:
diff changeset
2287
e78566595089 initial import
mandel
parents:
diff changeset
2288 void AbstractMetaBuilder::parseQ_Property(AbstractMetaClass *meta_class, const QStringList &declarations)
e78566595089 initial import
mandel
parents:
diff changeset
2289 {
e78566595089 initial import
mandel
parents:
diff changeset
2290 for (int i=0; i<declarations.size(); ++i) {
e78566595089 initial import
mandel
parents:
diff changeset
2291 QString p = declarations.at(i);
e78566595089 initial import
mandel
parents:
diff changeset
2292
e78566595089 initial import
mandel
parents:
diff changeset
2293 QStringList l = p.split(QLatin1String(" "));
e78566595089 initial import
mandel
parents:
diff changeset
2294
e78566595089 initial import
mandel
parents:
diff changeset
2295
e78566595089 initial import
mandel
parents:
diff changeset
2296 QStringList qualifiedScopeName = currentScope()->qualifiedName();
e78566595089 initial import
mandel
parents:
diff changeset
2297 bool ok = false;
e78566595089 initial import
mandel
parents:
diff changeset
2298 AbstractMetaType *type = 0;
e78566595089 initial import
mandel
parents:
diff changeset
2299 QString scope;
e78566595089 initial import
mandel
parents:
diff changeset
2300 for (int j=qualifiedScopeName.size(); j>=0; --j) {
e78566595089 initial import
mandel
parents:
diff changeset
2301 scope = j > 0 ? QStringList(qualifiedScopeName.mid(0, j)).join("::") + "::" : QString();
e78566595089 initial import
mandel
parents:
diff changeset
2302 TypeInfo info;
e78566595089 initial import
mandel
parents:
diff changeset
2303 info.setQualifiedName((scope + l.at(0)).split("::"));
e78566595089 initial import
mandel
parents:
diff changeset
2304
e78566595089 initial import
mandel
parents:
diff changeset
2305 type = translateType(info, &ok);
e78566595089 initial import
mandel
parents:
diff changeset
2306 if (type != 0 && ok) {
e78566595089 initial import
mandel
parents:
diff changeset
2307 break;
e78566595089 initial import
mandel
parents:
diff changeset
2308 }
e78566595089 initial import
mandel
parents:
diff changeset
2309 }
e78566595089 initial import
mandel
parents:
diff changeset
2310
e78566595089 initial import
mandel
parents:
diff changeset
2311 if (type == 0 || !ok) {
e78566595089 initial import
mandel
parents:
diff changeset
2312 ReportHandler::warning(QString("Unable to decide type of property: '%1' in class '%2'")
e78566595089 initial import
mandel
parents:
diff changeset
2313 .arg(l.at(0)).arg(meta_class->name()));
e78566595089 initial import
mandel
parents:
diff changeset
2314 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2315 }
e78566595089 initial import
mandel
parents:
diff changeset
2316
e78566595089 initial import
mandel
parents:
diff changeset
2317 QString typeName = scope + l.at(0);
e78566595089 initial import
mandel
parents:
diff changeset
2318
e78566595089 initial import
mandel
parents:
diff changeset
2319 QPropertySpec *spec = new QPropertySpec(type->typeEntry());
e78566595089 initial import
mandel
parents:
diff changeset
2320 spec->setName(l.at(1));
e78566595089 initial import
mandel
parents:
diff changeset
2321 spec->setIndex(i);
e78566595089 initial import
mandel
parents:
diff changeset
2322
e78566595089 initial import
mandel
parents:
diff changeset
2323 for (int pos=2; pos+1<l.size(); pos+=2) {
e78566595089 initial import
mandel
parents:
diff changeset
2324 if (l.at(pos) == QLatin1String("READ"))
e78566595089 initial import
mandel
parents:
diff changeset
2325 spec->setRead(l.at(pos+1));
e78566595089 initial import
mandel
parents:
diff changeset
2326 else if (l.at(pos) == QLatin1String("WRITE"))
e78566595089 initial import
mandel
parents:
diff changeset
2327 spec->setWrite(l.at(pos+1));
e78566595089 initial import
mandel
parents:
diff changeset
2328 else if (l.at(pos) == QLatin1String("DESIGNABLE"))
e78566595089 initial import
mandel
parents:
diff changeset
2329 spec->setDesignable(l.at(pos+1));
e78566595089 initial import
mandel
parents:
diff changeset
2330 else if (l.at(pos) == QLatin1String("RESET"))
e78566595089 initial import
mandel
parents:
diff changeset
2331 spec->setReset(l.at(pos+1));
e78566595089 initial import
mandel
parents:
diff changeset
2332 }
e78566595089 initial import
mandel
parents:
diff changeset
2333
e78566595089 initial import
mandel
parents:
diff changeset
2334 meta_class->addPropertySpec(spec);
e78566595089 initial import
mandel
parents:
diff changeset
2335 delete type;
e78566595089 initial import
mandel
parents:
diff changeset
2336 }
e78566595089 initial import
mandel
parents:
diff changeset
2337 }
e78566595089 initial import
mandel
parents:
diff changeset
2338
e78566595089 initial import
mandel
parents:
diff changeset
2339 static void hide_functions(const AbstractMetaFunctionList &l) {
e78566595089 initial import
mandel
parents:
diff changeset
2340 foreach (AbstractMetaFunction *f, l) {
e78566595089 initial import
mandel
parents:
diff changeset
2341 FunctionModification mod;
e78566595089 initial import
mandel
parents:
diff changeset
2342 mod.signature = f->minimalSignature();
e78566595089 initial import
mandel
parents:
diff changeset
2343 mod.modifiers = FunctionModification::Private;
e78566595089 initial import
mandel
parents:
diff changeset
2344 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
e78566595089 initial import
mandel
parents:
diff changeset
2345 }
e78566595089 initial import
mandel
parents:
diff changeset
2346 }
e78566595089 initial import
mandel
parents:
diff changeset
2347
e78566595089 initial import
mandel
parents:
diff changeset
2348 static void remove_function(AbstractMetaFunction *f) {
e78566595089 initial import
mandel
parents:
diff changeset
2349 FunctionModification mod;
e78566595089 initial import
mandel
parents:
diff changeset
2350 mod.removal = TypeSystem::All;
e78566595089 initial import
mandel
parents:
diff changeset
2351 mod.signature = f->minimalSignature();
e78566595089 initial import
mandel
parents:
diff changeset
2352 ((ComplexTypeEntry *) f->implementingClass()->typeEntry())->addFunctionModification(mod);
e78566595089 initial import
mandel
parents:
diff changeset
2353 }
e78566595089 initial import
mandel
parents:
diff changeset
2354
e78566595089 initial import
mandel
parents:
diff changeset
2355 static AbstractMetaFunctionList filter_functions(const AbstractMetaFunctionList &lst, QSet<QString> *signatures)
e78566595089 initial import
mandel
parents:
diff changeset
2356 {
e78566595089 initial import
mandel
parents:
diff changeset
2357 AbstractMetaFunctionList functions;
e78566595089 initial import
mandel
parents:
diff changeset
2358 foreach (AbstractMetaFunction *f, lst) {
e78566595089 initial import
mandel
parents:
diff changeset
2359 QString signature = f->minimalSignature();
e78566595089 initial import
mandel
parents:
diff changeset
2360 int start = signature.indexOf(QLatin1Char('(')) + 1;
e78566595089 initial import
mandel
parents:
diff changeset
2361 int end = signature.lastIndexOf(QLatin1Char(')'));
e78566595089 initial import
mandel
parents:
diff changeset
2362 signature = signature.mid(start, end - start);
e78566595089 initial import
mandel
parents:
diff changeset
2363 if (signatures->contains(signature)) {
e78566595089 initial import
mandel
parents:
diff changeset
2364 remove_function(f);
e78566595089 initial import
mandel
parents:
diff changeset
2365 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2366 }
e78566595089 initial import
mandel
parents:
diff changeset
2367 (*signatures) << signature;
e78566595089 initial import
mandel
parents:
diff changeset
2368 functions << f;
e78566595089 initial import
mandel
parents:
diff changeset
2369 }
e78566595089 initial import
mandel
parents:
diff changeset
2370 return functions;
e78566595089 initial import
mandel
parents:
diff changeset
2371 }
e78566595089 initial import
mandel
parents:
diff changeset
2372
e78566595089 initial import
mandel
parents:
diff changeset
2373 void AbstractMetaBuilder::setupEquals(AbstractMetaClass *cls)
e78566595089 initial import
mandel
parents:
diff changeset
2374 {
e78566595089 initial import
mandel
parents:
diff changeset
2375 AbstractMetaFunctionList equals;
e78566595089 initial import
mandel
parents:
diff changeset
2376 AbstractMetaFunctionList nequals;
e78566595089 initial import
mandel
parents:
diff changeset
2377
e78566595089 initial import
mandel
parents:
diff changeset
2378 QString op_equals = QLatin1String("operator_equal");
e78566595089 initial import
mandel
parents:
diff changeset
2379 QString op_nequals = QLatin1String("operator_not_equal");
e78566595089 initial import
mandel
parents:
diff changeset
2380
e78566595089 initial import
mandel
parents:
diff changeset
2381 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
e78566595089 initial import
mandel
parents:
diff changeset
2382 | AbstractMetaClass::NotRemovedFromTargetLang);
e78566595089 initial import
mandel
parents:
diff changeset
2383 foreach (AbstractMetaFunction *f, functions) {
e78566595089 initial import
mandel
parents:
diff changeset
2384 if (f->name() == op_equals)
e78566595089 initial import
mandel
parents:
diff changeset
2385 equals << f;
e78566595089 initial import
mandel
parents:
diff changeset
2386 else if (f->name() == op_nequals)
e78566595089 initial import
mandel
parents:
diff changeset
2387 nequals << f;
e78566595089 initial import
mandel
parents:
diff changeset
2388 }
e78566595089 initial import
mandel
parents:
diff changeset
2389
e78566595089 initial import
mandel
parents:
diff changeset
2390 if (equals.size() || nequals.size()) {
e78566595089 initial import
mandel
parents:
diff changeset
2391 if (!cls->hasHashFunction()) {
e78566595089 initial import
mandel
parents:
diff changeset
2392 ReportHandler::warning(QString::fromLatin1("Class '%1' has equals operators but no qHash() function")
e78566595089 initial import
mandel
parents:
diff changeset
2393 .arg(cls->name()));
e78566595089 initial import
mandel
parents:
diff changeset
2394 }
e78566595089 initial import
mandel
parents:
diff changeset
2395
e78566595089 initial import
mandel
parents:
diff changeset
2396 hide_functions(equals);
e78566595089 initial import
mandel
parents:
diff changeset
2397 hide_functions(nequals);
e78566595089 initial import
mandel
parents:
diff changeset
2398
e78566595089 initial import
mandel
parents:
diff changeset
2399 // We only need == if we have both == and !=, and one == for
e78566595089 initial import
mandel
parents:
diff changeset
2400 // each signature type, like QDateTime::==(QDate) and (QTime)
e78566595089 initial import
mandel
parents:
diff changeset
2401 // if such a thing exists...
e78566595089 initial import
mandel
parents:
diff changeset
2402 QSet<QString> func_signatures;
e78566595089 initial import
mandel
parents:
diff changeset
2403 cls->setEqualsFunctions(filter_functions(equals, &func_signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2404 cls->setNotEqualsFunctions(filter_functions(nequals, &func_signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2405 }
e78566595089 initial import
mandel
parents:
diff changeset
2406 }
e78566595089 initial import
mandel
parents:
diff changeset
2407
e78566595089 initial import
mandel
parents:
diff changeset
2408 void AbstractMetaBuilder::setupComparable(AbstractMetaClass *cls)
e78566595089 initial import
mandel
parents:
diff changeset
2409 {
e78566595089 initial import
mandel
parents:
diff changeset
2410 AbstractMetaFunctionList greater;
e78566595089 initial import
mandel
parents:
diff changeset
2411 AbstractMetaFunctionList greaterEquals;
e78566595089 initial import
mandel
parents:
diff changeset
2412 AbstractMetaFunctionList less;
e78566595089 initial import
mandel
parents:
diff changeset
2413 AbstractMetaFunctionList lessEquals;
e78566595089 initial import
mandel
parents:
diff changeset
2414
e78566595089 initial import
mandel
parents:
diff changeset
2415 QString op_greater = QLatin1String("operator_greater");
e78566595089 initial import
mandel
parents:
diff changeset
2416 QString op_greater_eq = QLatin1String("operator_greater_or_equal");
e78566595089 initial import
mandel
parents:
diff changeset
2417 QString op_less = QLatin1String("operator_less");
e78566595089 initial import
mandel
parents:
diff changeset
2418 QString op_less_eq = QLatin1String("operator_less_or_equal");
e78566595089 initial import
mandel
parents:
diff changeset
2419
e78566595089 initial import
mandel
parents:
diff changeset
2420 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements
e78566595089 initial import
mandel
parents:
diff changeset
2421 | AbstractMetaClass::NotRemovedFromTargetLang);
e78566595089 initial import
mandel
parents:
diff changeset
2422 foreach (AbstractMetaFunction *f, functions) {
e78566595089 initial import
mandel
parents:
diff changeset
2423 if (f->name() == op_greater)
e78566595089 initial import
mandel
parents:
diff changeset
2424 greater << f;
e78566595089 initial import
mandel
parents:
diff changeset
2425 else if (f->name() == op_greater_eq)
e78566595089 initial import
mandel
parents:
diff changeset
2426 greaterEquals << f;
e78566595089 initial import
mandel
parents:
diff changeset
2427 else if (f->name() == op_less)
e78566595089 initial import
mandel
parents:
diff changeset
2428 less << f;
e78566595089 initial import
mandel
parents:
diff changeset
2429 else if (f->name() == op_less_eq)
e78566595089 initial import
mandel
parents:
diff changeset
2430 lessEquals << f;
e78566595089 initial import
mandel
parents:
diff changeset
2431 }
e78566595089 initial import
mandel
parents:
diff changeset
2432
e78566595089 initial import
mandel
parents:
diff changeset
2433 bool hasEquals = cls->equalsFunctions().size() || cls->notEqualsFunctions().size();
e78566595089 initial import
mandel
parents:
diff changeset
2434
e78566595089 initial import
mandel
parents:
diff changeset
2435 // Conditions for comparable is:
e78566595089 initial import
mandel
parents:
diff changeset
2436 // >, ==, < - The basic case
e78566595089 initial import
mandel
parents:
diff changeset
2437 // >, == - Less than becomes else case
e78566595089 initial import
mandel
parents:
diff changeset
2438 // <, == - Greater than becomes else case
e78566595089 initial import
mandel
parents:
diff changeset
2439 // >=, <= - if (<= && >=) -> equal
e78566595089 initial import
mandel
parents:
diff changeset
2440 bool mightBeComparable = greater.size() || greaterEquals.size() || less.size() || lessEquals.size()
e78566595089 initial import
mandel
parents:
diff changeset
2441 || greaterEquals.size() == 1 || lessEquals.size() == 1;
e78566595089 initial import
mandel
parents:
diff changeset
2442
e78566595089 initial import
mandel
parents:
diff changeset
2443 if (mightBeComparable) {
e78566595089 initial import
mandel
parents:
diff changeset
2444 QSet<QString> signatures;
e78566595089 initial import
mandel
parents:
diff changeset
2445
e78566595089 initial import
mandel
parents:
diff changeset
2446 // We only hide the original functions if we are able to make a compareTo() method
e78566595089 initial import
mandel
parents:
diff changeset
2447 bool wasComparable = false;
e78566595089 initial import
mandel
parents:
diff changeset
2448
e78566595089 initial import
mandel
parents:
diff changeset
2449 // The three upper cases, prefer the <, == approach
e78566595089 initial import
mandel
parents:
diff changeset
2450 if (hasEquals && (greater.size() || less.size())) {
e78566595089 initial import
mandel
parents:
diff changeset
2451 cls->setLessThanFunctions(filter_functions(less, &signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2452 cls->setGreaterThanFunctions(filter_functions(greater, &signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2453 filter_functions(greaterEquals, &signatures);
e78566595089 initial import
mandel
parents:
diff changeset
2454 filter_functions(lessEquals, &signatures);
e78566595089 initial import
mandel
parents:
diff changeset
2455 wasComparable = true;
e78566595089 initial import
mandel
parents:
diff changeset
2456 } else if (hasEquals && (greaterEquals.size() || lessEquals.size())) {
e78566595089 initial import
mandel
parents:
diff changeset
2457 cls->setLessThanEqFunctions(filter_functions(lessEquals, &signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2458 cls->setGreaterThanEqFunctions(filter_functions(greaterEquals, &signatures));
e78566595089 initial import
mandel
parents:
diff changeset
2459 wasComparable = true;
e78566595089 initial import
mandel
parents:
diff changeset
2460 } else if (greaterEquals.size() == 1 || lessEquals.size() == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
2461 cls->setGreaterThanEqFunctions(greaterEquals);
e78566595089 initial import
mandel
parents:
diff changeset
2462 cls->setLessThanEqFunctions(lessEquals);
e78566595089 initial import
mandel
parents:
diff changeset
2463 filter_functions(less, &signatures);
e78566595089 initial import
mandel
parents:
diff changeset
2464 filter_functions(greater, &signatures);
e78566595089 initial import
mandel
parents:
diff changeset
2465 wasComparable = true;
e78566595089 initial import
mandel
parents:
diff changeset
2466 }
e78566595089 initial import
mandel
parents:
diff changeset
2467
e78566595089 initial import
mandel
parents:
diff changeset
2468 if (wasComparable) {
e78566595089 initial import
mandel
parents:
diff changeset
2469 hide_functions(greater);
e78566595089 initial import
mandel
parents:
diff changeset
2470 hide_functions(greaterEquals);
e78566595089 initial import
mandel
parents:
diff changeset
2471 hide_functions(less);
e78566595089 initial import
mandel
parents:
diff changeset
2472 hide_functions(lessEquals);
e78566595089 initial import
mandel
parents:
diff changeset
2473 }
e78566595089 initial import
mandel
parents:
diff changeset
2474 }
e78566595089 initial import
mandel
parents:
diff changeset
2475
e78566595089 initial import
mandel
parents:
diff changeset
2476 }
e78566595089 initial import
mandel
parents:
diff changeset
2477
e78566595089 initial import
mandel
parents:
diff changeset
2478 void AbstractMetaBuilder::setupClonable(AbstractMetaClass *cls)
e78566595089 initial import
mandel
parents:
diff changeset
2479 {
e78566595089 initial import
mandel
parents:
diff changeset
2480 // All value types are required to have a copy constructor,
e78566595089 initial import
mandel
parents:
diff changeset
2481 // or they will not work as value types (it won't even compile,
e78566595089 initial import
mandel
parents:
diff changeset
2482 // because of calls to qRegisterMetaType(). Thus all value types
e78566595089 initial import
mandel
parents:
diff changeset
2483 // should be cloneable.
e78566595089 initial import
mandel
parents:
diff changeset
2484 if (cls->typeEntry()->isValue()) {
e78566595089 initial import
mandel
parents:
diff changeset
2485 cls->setHasCloneOperator(true);
e78566595089 initial import
mandel
parents:
diff changeset
2486 return;
e78566595089 initial import
mandel
parents:
diff changeset
2487 } else {
e78566595089 initial import
mandel
parents:
diff changeset
2488 QString op_assign = QLatin1String("operator_assign");
e78566595089 initial import
mandel
parents:
diff changeset
2489
e78566595089 initial import
mandel
parents:
diff changeset
2490 AbstractMetaFunctionList functions = cls->queryFunctions(AbstractMetaClass::ClassImplements);
e78566595089 initial import
mandel
parents:
diff changeset
2491 foreach (AbstractMetaFunction *f, functions) {
e78566595089 initial import
mandel
parents:
diff changeset
2492 if ((f->name() == op_assign || f->isConstructor()) && f->isPublic()) {
e78566595089 initial import
mandel
parents:
diff changeset
2493 AbstractMetaArgumentList arguments = f->arguments();
e78566595089 initial import
mandel
parents:
diff changeset
2494 if (f->actualMinimumArgumentCount() == 1) {
e78566595089 initial import
mandel
parents:
diff changeset
2495 if (cls->typeEntry()->qualifiedCppName() == arguments.at(0)->type()->typeEntry()->qualifiedCppName()) {
e78566595089 initial import
mandel
parents:
diff changeset
2496 if (cls->typeEntry()->isValue()) {
e78566595089 initial import
mandel
parents:
diff changeset
2497 cls->setHasCloneOperator(true);
e78566595089 initial import
mandel
parents:
diff changeset
2498 return;
e78566595089 initial import
mandel
parents:
diff changeset
2499 }
e78566595089 initial import
mandel
parents:
diff changeset
2500 }
e78566595089 initial import
mandel
parents:
diff changeset
2501 }
e78566595089 initial import
mandel
parents:
diff changeset
2502 }
e78566595089 initial import
mandel
parents:
diff changeset
2503 }
e78566595089 initial import
mandel
parents:
diff changeset
2504 }
e78566595089 initial import
mandel
parents:
diff changeset
2505 }
e78566595089 initial import
mandel
parents:
diff changeset
2506
e78566595089 initial import
mandel
parents:
diff changeset
2507 static void write_reject_log_file(const QString &name,
e78566595089 initial import
mandel
parents:
diff changeset
2508 const QMap<QString, AbstractMetaBuilder::RejectReason> &rejects)
e78566595089 initial import
mandel
parents:
diff changeset
2509 {
e78566595089 initial import
mandel
parents:
diff changeset
2510 QFile f(name);
e78566595089 initial import
mandel
parents:
diff changeset
2511 if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
e78566595089 initial import
mandel
parents:
diff changeset
2512 ReportHandler::warning(QString("failed to write log file: '%1'")
e78566595089 initial import
mandel
parents:
diff changeset
2513 .arg(f.fileName()));
e78566595089 initial import
mandel
parents:
diff changeset
2514 return;
e78566595089 initial import
mandel
parents:
diff changeset
2515 }
e78566595089 initial import
mandel
parents:
diff changeset
2516
e78566595089 initial import
mandel
parents:
diff changeset
2517 QTextStream s(&f);
e78566595089 initial import
mandel
parents:
diff changeset
2518
e78566595089 initial import
mandel
parents:
diff changeset
2519
e78566595089 initial import
mandel
parents:
diff changeset
2520 for (int reason=0; reason<AbstractMetaBuilder::NoReason; ++reason) {
e78566595089 initial import
mandel
parents:
diff changeset
2521 s << QString(72, '*') << endl;
e78566595089 initial import
mandel
parents:
diff changeset
2522 switch (reason) {
e78566595089 initial import
mandel
parents:
diff changeset
2523 case AbstractMetaBuilder::NotInTypeSystem:
e78566595089 initial import
mandel
parents:
diff changeset
2524 s << "Not in type system";
e78566595089 initial import
mandel
parents:
diff changeset
2525 break;
e78566595089 initial import
mandel
parents:
diff changeset
2526 case AbstractMetaBuilder::GenerationDisabled:
e78566595089 initial import
mandel
parents:
diff changeset
2527 s << "Generation disabled by type system";
e78566595089 initial import
mandel
parents:
diff changeset
2528 break;
e78566595089 initial import
mandel
parents:
diff changeset
2529 case AbstractMetaBuilder::RedefinedToNotClass:
e78566595089 initial import
mandel
parents:
diff changeset
2530 s << "Type redefined to not be a class";
e78566595089 initial import
mandel
parents:
diff changeset
2531 break;
e78566595089 initial import
mandel
parents:
diff changeset
2532
e78566595089 initial import
mandel
parents:
diff changeset
2533 case AbstractMetaBuilder::UnmatchedReturnType:
e78566595089 initial import
mandel
parents:
diff changeset
2534 s << "Unmatched return type";
e78566595089 initial import
mandel
parents:
diff changeset
2535 break;
e78566595089 initial import
mandel
parents:
diff changeset
2536
e78566595089 initial import
mandel
parents:
diff changeset
2537 case AbstractMetaBuilder::UnmatchedArgumentType:
e78566595089 initial import
mandel
parents:
diff changeset
2538 s << "Unmatched argument type";
e78566595089 initial import
mandel
parents:
diff changeset
2539 break;
e78566595089 initial import
mandel
parents:
diff changeset
2540
e78566595089 initial import
mandel
parents:
diff changeset
2541 default:
e78566595089 initial import
mandel
parents:
diff changeset
2542 s << "unknown reason";
e78566595089 initial import
mandel
parents:
diff changeset
2543 break;
e78566595089 initial import
mandel
parents:
diff changeset
2544 }
e78566595089 initial import
mandel
parents:
diff changeset
2545
e78566595089 initial import
mandel
parents:
diff changeset
2546 s << endl;
e78566595089 initial import
mandel
parents:
diff changeset
2547
e78566595089 initial import
mandel
parents:
diff changeset
2548 for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
e78566595089 initial import
mandel
parents:
diff changeset
2549 it != rejects.constEnd(); ++it) {
e78566595089 initial import
mandel
parents:
diff changeset
2550 if (it.value() != reason)
e78566595089 initial import
mandel
parents:
diff changeset
2551 continue;
e78566595089 initial import
mandel
parents:
diff changeset
2552 s << " - " << it.key() << endl;
e78566595089 initial import
mandel
parents:
diff changeset
2553 }
e78566595089 initial import
mandel
parents:
diff changeset
2554
e78566595089 initial import
mandel
parents:
diff changeset
2555 s << QString(72, '*') << endl << endl;
e78566595089 initial import
mandel
parents:
diff changeset
2556 }
e78566595089 initial import
mandel
parents:
diff changeset
2557
e78566595089 initial import
mandel
parents:
diff changeset
2558 }
e78566595089 initial import
mandel
parents:
diff changeset
2559
e78566595089 initial import
mandel
parents:
diff changeset
2560
e78566595089 initial import
mandel
parents:
diff changeset
2561 void AbstractMetaBuilder::dumpLog()
e78566595089 initial import
mandel
parents:
diff changeset
2562 {
e78566595089 initial import
mandel
parents:
diff changeset
2563 write_reject_log_file("mjb_rejected_classes.log", m_rejected_classes);
e78566595089 initial import
mandel
parents:
diff changeset
2564 write_reject_log_file("mjb_rejected_enums.log", m_rejected_enums);
e78566595089 initial import
mandel
parents:
diff changeset
2565 write_reject_log_file("mjb_rejected_functions.log", m_rejected_functions);
e78566595089 initial import
mandel
parents:
diff changeset
2566 write_reject_log_file("mjb_rejected_fields.log", m_rejected_fields);
e78566595089 initial import
mandel
parents:
diff changeset
2567 }
e78566595089 initial import
mandel
parents:
diff changeset
2568
e78566595089 initial import
mandel
parents:
diff changeset
2569 AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted() const
e78566595089 initial import
mandel
parents:
diff changeset
2570 {
e78566595089 initial import
mandel
parents:
diff changeset
2571 AbstractMetaClassList res;
e78566595089 initial import
mandel
parents:
diff changeset
2572
e78566595089 initial import
mandel
parents:
diff changeset
2573 AbstractMetaClassList classes = m_meta_classes;
e78566595089 initial import
mandel
parents:
diff changeset
2574 qSort(classes);
e78566595089 initial import
mandel
parents:
diff changeset
2575
e78566595089 initial import
mandel
parents:
diff changeset
2576 QSet<AbstractMetaClass*> noDependency;
e78566595089 initial import
mandel
parents:
diff changeset
2577 QHash<AbstractMetaClass*, QSet<AbstractMetaClass* >* > hash;
e78566595089 initial import
mandel
parents:
diff changeset
2578 foreach (AbstractMetaClass *cls, classes) {
e78566595089 initial import
mandel
parents:
diff changeset
2579 QSet<AbstractMetaClass* > *depends = new QSet<AbstractMetaClass* >();
e78566595089 initial import
mandel
parents:
diff changeset
2580
e78566595089 initial import
mandel
parents:
diff changeset
2581 if (cls->baseClass())
e78566595089 initial import
mandel
parents:
diff changeset
2582 depends->insert(cls->baseClass());
e78566595089 initial import
mandel
parents:
diff changeset
2583
e78566595089 initial import
mandel
parents:
diff changeset
2584 foreach (AbstractMetaClass *interface, cls->interfaces()) {
e78566595089 initial import
mandel
parents:
diff changeset
2585 depends->insert(interface);
e78566595089 initial import
mandel
parents:
diff changeset
2586 }
e78566595089 initial import
mandel
parents:
diff changeset
2587
e78566595089 initial import
mandel
parents:
diff changeset
2588 if (depends->empty()) {
e78566595089 initial import
mandel
parents:
diff changeset
2589 noDependency.insert(cls);
e78566595089 initial import
mandel
parents:
diff changeset
2590 } else {
e78566595089 initial import
mandel
parents:
diff changeset
2591 hash.insert(cls, depends);
e78566595089 initial import
mandel
parents:
diff changeset
2592 }
e78566595089 initial import
mandel
parents:
diff changeset
2593 }
e78566595089 initial import
mandel
parents:
diff changeset
2594
e78566595089 initial import
mandel
parents:
diff changeset
2595 while (!noDependency.empty()) {
e78566595089 initial import
mandel
parents:
diff changeset
2596 foreach (AbstractMetaClass *cls, noDependency.values()) {
e78566595089 initial import
mandel
parents:
diff changeset
2597 if(!cls->isInterface())
e78566595089 initial import
mandel
parents:
diff changeset
2598 res.append(cls);
e78566595089 initial import
mandel
parents:
diff changeset
2599 noDependency.remove(cls);
e78566595089 initial import
mandel
parents:
diff changeset
2600 QHashIterator<AbstractMetaClass*, QSet<AbstractMetaClass* >* > i(hash);
e78566595089 initial import
mandel
parents:
diff changeset
2601 while (i.hasNext()) {
e78566595089 initial import
mandel
parents:
diff changeset
2602 i.next();
e78566595089 initial import
mandel
parents:
diff changeset
2603 i.value()->remove(cls);
e78566595089 initial import
mandel
parents:
diff changeset
2604 if (i.value()->empty()) {
e78566595089 initial import
mandel
parents:
diff changeset
2605 AbstractMetaClass *key = i.key();
e78566595089 initial import
mandel
parents:
diff changeset
2606 noDependency.insert(key);
e78566595089 initial import
mandel
parents:
diff changeset
2607 hash.remove(key);
e78566595089 initial import
mandel
parents:
diff changeset
2608 delete(i.value());
e78566595089 initial import
mandel
parents:
diff changeset
2609 }
e78566595089 initial import
mandel
parents:
diff changeset
2610 }
e78566595089 initial import
mandel
parents:
diff changeset
2611 }
e78566595089 initial import
mandel
parents:
diff changeset
2612 }
e78566595089 initial import
mandel
parents:
diff changeset
2613
e78566595089 initial import
mandel
parents:
diff changeset
2614 if (!noDependency.empty() || !hash.empty()) {
e78566595089 initial import
mandel
parents:
diff changeset
2615 qWarning("dependency graph was cyclic.");
e78566595089 initial import
mandel
parents:
diff changeset
2616 }
e78566595089 initial import
mandel
parents:
diff changeset
2617
e78566595089 initial import
mandel
parents:
diff changeset
2618 return res;
e78566595089 initial import
mandel
parents:
diff changeset
2619 }