annotate generator/abstractmetabuilder.cpp @ 393:1049b01aebd2

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