support for creating template instance classes
[lqt/mk.git] / cpptoxml / parser / codemodel.cpp
blobfccedd9bdafa258503465987c5d11d8d1f01d06e
1 /****************************************************************************
2 **
3 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
4 ** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
5 **
6 ** This file is part of the Qt Script Generator project on Trolltech Labs.
7 **
8 ** This file may be used under the terms of the GNU General Public
9 ** License version 2.0 as published by the Free Software Foundation
10 ** and appearing in the file LICENSE.GPL included in the packaging of
11 ** this file. Please review the following information to ensure GNU
12 ** General Public Licensing requirements will be met:
13 ** http://www.trolltech.com/products/qt/opensource.html
15 ** If you are unsure which license is appropriate for your use, please
16 ** review the following information:
17 ** http://www.trolltech.com/products/qt/licensing.html or contact the
18 ** sales department at sales@trolltech.com.
20 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
21 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 ****************************************************************************/
26 #include "codemodel.h"
28 // ---------------------------------------------------------------------------
29 CodeModel::CodeModel()
30 : _M_creation_id(0)
32 _M_globalNamespace = create<NamespaceModelItem>();
35 CodeModel::~CodeModel()
39 void CodeModel::wipeout()
41 _M_globalNamespace = create<NamespaceModelItem>();
42 _M_files.clear();
45 FileList CodeModel::files() const
47 return _M_files.values();
50 NamespaceModelItem CodeModel::globalNamespace() const
52 return _M_globalNamespace;
55 void CodeModel::addFile(FileModelItem item)
57 _M_creation_id = 0; // reset the creation id
58 _M_files.insert(item->name(), item);
61 void CodeModel::removeFile(FileModelItem item)
63 QHash<QString, FileModelItem>::Iterator it = _M_files.find(item->name());
65 if (it != _M_files.end() && it.value() == item)
66 _M_files.erase(it);
69 FileModelItem CodeModel::findFile(const QString &name) const
71 return _M_files.value(name);
74 QHash<QString, FileModelItem> CodeModel::fileMap() const
76 return _M_files;
79 CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const
81 for (int i=0; i<qualifiedName.size(); ++i) {
82 // ### Extend to look for members etc too.
83 const QString &name = qualifiedName.at(i);
85 if (NamespaceModelItem ns = model_dynamic_cast<NamespaceModelItem>(scope))
87 if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) {
88 scope = tmp_ns;
89 continue;
93 if (ScopeModelItem ss = model_dynamic_cast<ScopeModelItem>(scope))
95 if (ClassModelItem cs = ss->findClass(name))
97 scope = cs;
99 else if (EnumModelItem es = ss->findEnum(name))
101 if (i == qualifiedName.size () - 1)
102 return es->toItem();
104 else if (TypeAliasModelItem tp = ss->findTypeAlias(name))
106 if (i == qualifiedName.size () - 1)
107 return tp->toItem ();
109 else
111 // If we don't find the name in the scope chain we
112 // need to return an empty item to indicate failure...
113 return CodeModelItem();
118 return scope;
122 // ---------------------------------------------------------------------------
123 TypeInfo TypeInfo::combine (const TypeInfo &__lhs, const TypeInfo &__rhs)
125 TypeInfo __result = __lhs;
127 __result.setConstant (__result.isConstant () || __rhs.isConstant ());
128 __result.setVolatile (__result.isVolatile () || __rhs.isVolatile ());
129 __result.setReference (__result.isReference () || __rhs.isReference ());
130 __result.setIndirections (__result.indirections () + __rhs.indirections ());
131 __result.setArrayElements (__result.arrayElements () + __rhs.arrayElements ());
133 return __result;
136 TypeInfo TypeInfo::resolveType (TypeInfo const &__type, CodeModelItem __scope)
138 CodeModel *__model = __scope->model ();
139 Q_ASSERT (__model != 0);
141 CodeModelItem __item = __model->findItem (__type.qualifiedName (), __scope);
143 // Copy the type and replace with the proper qualified name. This
144 // only makes sence to do if we're actually getting a resolved
145 // type with a namespace. We only get this if the returned type
146 // has more than 2 entries in the qualified name... This test
147 // could be improved by returning if the type was found or not.
148 TypeInfo otherType(__type);
149 if (__item && __item->qualifiedName().size() > 1) {
150 otherType.setQualifiedName(__item->qualifiedName());
153 if (TypeAliasModelItem __alias = model_dynamic_cast<TypeAliasModelItem> (__item))
154 return resolveType (TypeInfo::combine (__alias->type (), otherType), __scope);
156 return otherType;
159 QString TypeInfo::toString() const
161 QString tmp;
163 tmp += m_qualifiedName.join("::");
164 if (isConstant())
165 tmp += QLatin1String(" const");
167 if (isVolatile())
168 tmp += QLatin1String(" volatile");
170 if (indirections())
171 tmp += QString(indirections(), QLatin1Char('*'));
173 if (isReference())
174 tmp += QLatin1Char('&');
176 if (isFunctionPointer())
178 tmp += QLatin1String(" (*)(");
179 for (int i=0; i<m_arguments.count(); ++i)
181 if (i != 0)
182 tmp += QLatin1String(", ");
184 tmp += m_arguments.at(i).toString();
186 tmp += QLatin1String(")");
189 foreach (const QString& elt, arrayElements ())
191 tmp += QLatin1String ("[");
192 tmp += elt;
193 tmp += QLatin1String ("]");
196 return tmp;
199 bool TypeInfo::operator==(const TypeInfo &other)
201 if (arrayElements().count() != other.arrayElements().count())
202 return false;
204 #if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break
205 for (int i=0; i<arrayElements().count(); ++i)
207 QString elt1 = arrayElements ().at (i).trimmed ();
208 QString elt2 = other.arrayElements ().at (i).trimmed ();
210 if (elt1 != elt2)
211 return false;
213 #endif
215 return flags == other.flags
216 && m_qualifiedName == other.m_qualifiedName
217 && (!f.m_functionPointer || m_arguments == other.m_arguments);
220 // ---------------------------------------------------------------------------
221 _CodeModelItem::_CodeModelItem(CodeModel *model, int kind)
222 : _M_model(model),
223 _M_kind(kind),
224 _M_startLine(0),
225 _M_startColumn(0),
226 _M_endLine(0),
227 _M_endColumn(0),
228 _M_creation_id(0)
232 _CodeModelItem::~_CodeModelItem()
236 CodeModelItem _CodeModelItem::toItem() const
238 return CodeModelItem(const_cast<_CodeModelItem*>(this));
241 int _CodeModelItem::kind() const
243 return _M_kind;
246 void _CodeModelItem::setKind(int kind)
248 _M_kind = kind;
251 QStringList _CodeModelItem::qualifiedName() const
253 QStringList q = scope();
255 if (!name().isEmpty())
256 q += name();
258 return q;
261 QString _CodeModelItem::name() const
263 return _M_name;
266 void _CodeModelItem::setName(const QString &name)
268 _M_name = name;
271 QStringList _CodeModelItem::scope() const
273 return _M_scope;
276 void _CodeModelItem::setScope(const QStringList &scope)
278 _M_scope = scope;
281 QString _CodeModelItem::fileName() const
283 return _M_fileName;
286 void _CodeModelItem::setFileName(const QString &fileName)
288 _M_fileName = fileName;
291 FileModelItem _CodeModelItem::file() const
293 return model()->findFile(fileName());
296 void _CodeModelItem::getStartPosition(int *line, int *column)
298 *line = _M_startLine;
299 *column = _M_startColumn;
302 void _CodeModelItem::setStartPosition(int line, int column)
304 _M_startLine = line;
305 _M_startColumn = column;
308 void _CodeModelItem::getEndPosition(int *line, int *column)
310 *line = _M_endLine;
311 *column = _M_endColumn;
314 void _CodeModelItem::setEndPosition(int line, int column)
316 _M_endLine = line;
317 _M_endColumn = column;
320 // ---------------------------------------------------------------------------
321 QStringList _ClassModelItem::baseClasses() const
323 return _M_baseClasses;
326 void _ClassModelItem::setBaseClasses(const QStringList &baseClasses)
328 _M_baseClasses = baseClasses;
329 _M_baseModifiers = QStringList();
330 while (_M_baseModifiers.size()>_M_baseClasses.size()) {
331 _M_baseModifiers.pop_back();
333 while (_M_baseModifiers.size()<_M_baseClasses.size()) {
334 _M_baseModifiers.push_back(QString());
338 QStringList _ClassModelItem::baseModifiers() const
340 return _M_baseModifiers;
343 void _ClassModelItem::setBaseModifiers(const QStringList &baseModifiers)
345 _M_baseModifiers = baseModifiers;
346 while (_M_baseModifiers.size()>_M_baseClasses.size()) {
347 _M_baseModifiers.pop_back();
349 while (_M_baseModifiers.size()<_M_baseClasses.size()) {
350 _M_baseModifiers.push_back(QString());
354 TemplateParameterList _ClassModelItem::templateParameters() const
356 return _M_templateParameters;
359 void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters)
361 _M_templateParameters = templateParameters;
364 void _ClassModelItem::addBaseClass(const QString &baseClass, const QString &baseModifier)
366 _M_baseClasses.append(baseClass);
367 _M_baseModifiers.append(baseModifier);
370 void _ClassModelItem::removeBaseClass(const QString &baseClass)
372 int index = _M_baseClasses.indexOf(baseClass);
373 _M_baseClasses.removeAt(index);
374 _M_baseModifiers.removeAt(index);
377 bool _ClassModelItem::extendsClass(const QString &name) const
379 return _M_baseClasses.contains(name);
382 void _ClassModelItem::setClassType(CodeModel::ClassType type)
384 _M_classType = type;
387 CodeModel::ClassType _ClassModelItem::classType() const
389 return _M_classType;
392 void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration)
394 _M_propertyDeclarations << propertyDeclaration;
397 CodeModel::AccessPolicy _ClassModelItem::accessPolicy() const
399 return _M_accessPolicy;
402 void _ClassModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
404 _M_accessPolicy = accessPolicy;
408 // ---------------------------------------------------------------------------
409 FunctionModelItem _ScopeModelItem::declaredFunction(FunctionModelItem item)
411 FunctionList function_list = findFunctions(item->name());
413 foreach (FunctionModelItem fun, function_list)
415 if (fun->isSimilar(item))
416 return fun;
419 return FunctionModelItem();
422 ClassList _ScopeModelItem::classes() const
424 return _M_classes.values();
427 TypeAliasList _ScopeModelItem::typeAliases() const
429 return _M_typeAliases.values();
432 VariableList _ScopeModelItem::variables() const
434 return _M_variables.values();
437 FunctionList _ScopeModelItem::functions() const
439 return _M_functions.values();
442 void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration)
444 _M_enumsDeclarations << enumsDeclaration;
447 FunctionDefinitionList _ScopeModelItem::functionDefinitions() const
449 return _M_functionDefinitions.values();
452 EnumList _ScopeModelItem::enums() const
454 return _M_enums.values();
457 void _ScopeModelItem::addClass(ClassModelItem item)
459 QString name = item->name();
460 int idx = name.indexOf("<");
461 if (idx > 0)
462 _M_classes.insert(name.left(idx), item);
463 _M_classes.insert(name, item);
466 void _ScopeModelItem::addFunction(FunctionModelItem item)
468 _M_functions.insert(item->name(), item);
471 void _ScopeModelItem::addFunctionDefinition(FunctionDefinitionModelItem item)
473 _M_functionDefinitions.insert(item->name(), item);
476 void _ScopeModelItem::addVariable(VariableModelItem item)
478 _M_variables.insert(item->name(), item);
481 void _ScopeModelItem::addTypeAlias(TypeAliasModelItem item)
483 _M_typeAliases.insert(item->name(), item);
486 void _ScopeModelItem::addEnum(EnumModelItem item)
488 _M_enums.insert(item->name(), item);
491 void _ScopeModelItem::removeClass(ClassModelItem item)
493 QHash<QString, ClassModelItem>::Iterator it = _M_classes.find(item->name());
495 if (it != _M_classes.end() && it.value() == item)
496 _M_classes.erase(it);
499 void _ScopeModelItem::removeFunction(FunctionModelItem item)
501 QMultiHash<QString, FunctionModelItem>::Iterator it = _M_functions.find(item->name());
503 while (it != _M_functions.end() && it.key() == item->name()
504 && it.value() != item)
506 ++it;
509 if (it != _M_functions.end() && it.value() == item)
511 _M_functions.erase(it);
515 void _ScopeModelItem::removeFunctionDefinition(FunctionDefinitionModelItem item)
517 QMultiHash<QString, FunctionDefinitionModelItem>::Iterator it = _M_functionDefinitions.find(item->name());
519 while (it != _M_functionDefinitions.end() && it.key() == item->name()
520 && it.value() != item)
522 ++it;
525 if (it != _M_functionDefinitions.end() && it.value() == item)
527 _M_functionDefinitions.erase(it);
531 void _ScopeModelItem::removeVariable(VariableModelItem item)
533 QHash<QString, VariableModelItem>::Iterator it = _M_variables.find(item->name());
535 if (it != _M_variables.end() && it.value() == item)
536 _M_variables.erase(it);
539 void _ScopeModelItem::removeTypeAlias(TypeAliasModelItem item)
541 QHash<QString, TypeAliasModelItem>::Iterator it = _M_typeAliases.find(item->name());
543 if (it != _M_typeAliases.end() && it.value() == item)
544 _M_typeAliases.erase(it);
547 void _ScopeModelItem::removeEnum(EnumModelItem item)
549 QHash<QString, EnumModelItem>::Iterator it = _M_enums.find(item->name());
551 if (it != _M_enums.end() && it.value() == item)
552 _M_enums.erase(it);
555 ClassModelItem _ScopeModelItem::findClass(const QString &name) const
557 return _M_classes.value(name);
560 VariableModelItem _ScopeModelItem::findVariable(const QString &name) const
562 return _M_variables.value(name);
565 TypeAliasModelItem _ScopeModelItem::findTypeAlias(const QString &name) const
567 return _M_typeAliases.value(name);
570 EnumModelItem _ScopeModelItem::findEnum(const QString &name) const
572 return _M_enums.value(name);
575 FunctionList _ScopeModelItem::findFunctions(const QString &name) const
577 return _M_functions.values(name);
580 FunctionDefinitionList _ScopeModelItem::findFunctionDefinitions(const QString &name) const
582 return _M_functionDefinitions.values(name);
585 // ---------------------------------------------------------------------------
586 NamespaceList _NamespaceModelItem::namespaces() const
588 return _M_namespaces.values();
590 void _NamespaceModelItem::addNamespace(NamespaceModelItem item)
592 _M_namespaces.insert(item->name(), item);
594 void _NamespaceModelItem::removeNamespace(NamespaceModelItem item)
596 QHash<QString, NamespaceModelItem>::Iterator it = _M_namespaces.find(item->name());
598 if (it != _M_namespaces.end() && it.value() == item)
599 _M_namespaces.erase(it);
602 NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const
604 return _M_namespaces.value(name);
607 // ---------------------------------------------------------------------------
608 TypeInfo _ArgumentModelItem::type() const
610 return _M_type;
613 void _ArgumentModelItem::setType(const TypeInfo &type)
615 _M_type = type;
618 bool _ArgumentModelItem::defaultValue() const
620 return _M_defaultValue;
623 void _ArgumentModelItem::setDefaultValue(bool defaultValue)
625 _M_defaultValue = defaultValue;
628 // ---------------------------------------------------------------------------
629 bool _FunctionModelItem::isSimilar(FunctionModelItem other) const
631 if (name() != other->name())
632 return false;
634 if (isConstant() != other->isConstant())
635 return false;
637 if (isVariadics() != other->isVariadics())
638 return false;
640 if (arguments().count() != other->arguments().count())
641 return false;
643 // ### check the template parameters
645 for (int i=0; i<arguments().count(); ++i)
647 ArgumentModelItem arg1 = arguments().at(i);
648 ArgumentModelItem arg2 = other->arguments().at(i);
650 if (arg1->type() != arg2->type())
651 return false;
654 return true;
657 ArgumentList _FunctionModelItem::arguments() const
659 return _M_arguments;
662 void _FunctionModelItem::addArgument(ArgumentModelItem item)
664 _M_arguments.append(item);
667 void _FunctionModelItem::removeArgument(ArgumentModelItem item)
669 _M_arguments.removeAt(_M_arguments.indexOf(item));
672 CodeModel::FunctionType _FunctionModelItem::functionType() const
674 return _M_functionType;
677 void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType)
679 _M_functionType = functionType;
682 bool _FunctionModelItem::isVariadics() const
684 return f._M_isVariadics;
687 void _FunctionModelItem::setVariadics(bool isVariadics)
689 f._M_isVariadics = isVariadics;
692 bool _FunctionModelItem::isVirtual() const
694 return f._M_isVirtual;
697 void _FunctionModelItem::setVirtual(bool isVirtual)
699 f._M_isVirtual = isVirtual;
702 bool _FunctionModelItem::isInline() const
704 return f._M_isInline;
707 void _FunctionModelItem::setInline(bool isInline)
709 f._M_isInline = isInline;
712 bool _FunctionModelItem::isExplicit() const
714 return f._M_isExplicit;
717 void _FunctionModelItem::setExplicit(bool isExplicit)
719 f._M_isExplicit = isExplicit;
722 bool _FunctionModelItem::isAbstract() const
724 return f._M_isAbstract;
727 void _FunctionModelItem::setAbstract(bool isAbstract)
729 f._M_isAbstract = isAbstract;
732 // Qt
733 bool _FunctionModelItem::isInvokable() const
735 return _M_isInvokable;
738 void _FunctionModelItem::setInvokable(bool isInvokable)
740 _M_isInvokable = isInvokable;
743 // ---------------------------------------------------------------------------
744 TypeInfo _TypeAliasModelItem::type() const
746 return _M_type;
749 void _TypeAliasModelItem::setType(const TypeInfo &type)
751 _M_type = type;
754 // ---------------------------------------------------------------------------
755 CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const
757 return _M_accessPolicy;
760 void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
762 _M_accessPolicy = accessPolicy;
765 EnumeratorList _EnumModelItem::enumerators() const
767 return _M_enumerators;
770 void _EnumModelItem::addEnumerator(EnumeratorModelItem item)
772 _M_enumerators.append(item);
775 void _EnumModelItem::removeEnumerator(EnumeratorModelItem item)
777 _M_enumerators.removeAt(_M_enumerators.indexOf(item));
780 // ---------------------------------------------------------------------------
781 QString _EnumeratorModelItem::value() const
783 return _M_value;
786 void _EnumeratorModelItem::setValue(const QString &value)
788 _M_value = value;
791 // ---------------------------------------------------------------------------
792 TypeInfo _TemplateParameterModelItem::type() const
794 return _M_type;
797 void _TemplateParameterModelItem::setType(const TypeInfo &type)
799 _M_type = type;
802 bool _TemplateParameterModelItem::defaultValue() const
804 return _M_defaultValue;
807 void _TemplateParameterModelItem::setDefaultValue(bool defaultValue)
809 _M_defaultValue = defaultValue;
812 // ---------------------------------------------------------------------------
813 ScopeModelItem _ScopeModelItem::create(CodeModel *model)
815 ScopeModelItem item(new _ScopeModelItem(model));
816 return item;
819 ClassModelItem _ClassModelItem::create(CodeModel *model)
821 ClassModelItem item(new _ClassModelItem(model));
822 return item;
825 NamespaceModelItem _NamespaceModelItem::create(CodeModel *model)
827 NamespaceModelItem item(new _NamespaceModelItem(model));
828 return item;
831 FileModelItem _FileModelItem::create(CodeModel *model)
833 FileModelItem item(new _FileModelItem(model));
834 return item;
837 ArgumentModelItem _ArgumentModelItem::create(CodeModel *model)
839 ArgumentModelItem item(new _ArgumentModelItem(model));
840 return item;
843 FunctionModelItem _FunctionModelItem::create(CodeModel *model)
845 FunctionModelItem item(new _FunctionModelItem(model));
846 return item;
849 FunctionDefinitionModelItem _FunctionDefinitionModelItem::create(CodeModel *model)
851 FunctionDefinitionModelItem item(new _FunctionDefinitionModelItem(model));
852 return item;
855 VariableModelItem _VariableModelItem::create(CodeModel *model)
857 VariableModelItem item(new _VariableModelItem(model));
858 return item;
861 TypeAliasModelItem _TypeAliasModelItem::create(CodeModel *model)
863 TypeAliasModelItem item(new _TypeAliasModelItem(model));
864 return item;
867 EnumModelItem _EnumModelItem::create(CodeModel *model)
869 EnumModelItem item(new _EnumModelItem(model));
870 return item;
873 EnumeratorModelItem _EnumeratorModelItem::create(CodeModel *model)
875 EnumeratorModelItem item(new _EnumeratorModelItem(model));
876 return item;
879 TemplateParameterModelItem _TemplateParameterModelItem::create(CodeModel *model)
881 TemplateParameterModelItem item(new _TemplateParameterModelItem(model));
882 return item;
885 // ---------------------------------------------------------------------------
886 TypeInfo _MemberModelItem::type() const
888 return _M_type;
891 void _MemberModelItem::setType(const TypeInfo &type)
893 _M_type = type;
896 CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const
898 return _M_accessPolicy;
901 void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy)
903 _M_accessPolicy = accessPolicy;
906 bool _MemberModelItem::isStatic() const
908 return f._M_isStatic;
911 void _MemberModelItem::setStatic(bool isStatic)
913 f._M_isStatic = isStatic;
916 bool _MemberModelItem::isConstant() const
918 return f._M_isConstant;
921 void _MemberModelItem::setConstant(bool isConstant)
923 f._M_isConstant = isConstant;
926 bool _MemberModelItem::isVolatile() const
928 return f._M_isVolatile;
931 void _MemberModelItem::setVolatile(bool isVolatile)
933 f._M_isVolatile = isVolatile;
936 bool _MemberModelItem::isAuto() const
938 return f._M_isAuto;
941 void _MemberModelItem::setAuto(bool isAuto)
943 f._M_isAuto = isAuto;
946 bool _MemberModelItem::isFriend() const
948 return f._M_isFriend;
951 void _MemberModelItem::setFriend(bool isFriend)
953 f._M_isFriend = isFriend;
956 bool _MemberModelItem::isRegister() const
958 return f._M_isRegister;
961 void _MemberModelItem::setRegister(bool isRegister)
963 f._M_isRegister = isRegister;
966 bool _MemberModelItem::isExtern() const
968 return f._M_isExtern;
971 void _MemberModelItem::setExtern(bool isExtern)
973 f._M_isExtern = isExtern;
976 bool _MemberModelItem::isMutable() const
978 return f._M_isMutable;
981 void _MemberModelItem::setMutable(bool isMutable)
983 f._M_isMutable = isMutable;
986 // kate: space-indent on; indent-width 2; replace-tabs on;