1 /****************************************************************************
3 ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
4 ** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
6 ** This file is part of the Qt Script Generator project on Trolltech Labs.
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()
32 _M_globalNamespace
= create
<NamespaceModelItem
>();
35 CodeModel::~CodeModel()
39 void CodeModel::wipeout()
41 _M_globalNamespace
= create
<NamespaceModelItem
>();
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
)
69 FileModelItem
CodeModel::findFile(const QString
&name
) const
71 return _M_files
.value(name
);
74 QHash
<QString
, FileModelItem
> CodeModel::fileMap() const
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
)) {
93 if (ScopeModelItem ss
= model_dynamic_cast
<ScopeModelItem
>(scope
))
95 if (ClassModelItem cs
= ss
->findClass(name
))
99 else if (EnumModelItem es
= ss
->findEnum(name
))
101 if (i
== qualifiedName
.size () - 1)
104 else if (TypeAliasModelItem tp
= ss
->findTypeAlias(name
))
106 if (i
== qualifiedName
.size () - 1)
107 return tp
->toItem ();
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();
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 ());
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
);
159 QString
TypeInfo::toString() const
163 tmp
+= m_qualifiedName
.join("::");
165 tmp
+= QLatin1String(" const");
168 tmp
+= QLatin1String(" volatile");
171 tmp
+= QString(indirections(), QLatin1Char('*'));
174 tmp
+= QLatin1Char('&');
176 if (isFunctionPointer())
178 tmp
+= QLatin1String(" (*)(");
179 for (int i
=0; i
<m_arguments
.count(); ++i
)
182 tmp
+= QLatin1String(", ");
184 tmp
+= m_arguments
.at(i
).toString();
186 tmp
+= QLatin1String(")");
189 foreach (const QString
& elt
, arrayElements ())
191 tmp
+= QLatin1String ("[");
193 tmp
+= QLatin1String ("]");
199 bool TypeInfo::operator==(const TypeInfo
&other
)
201 if (arrayElements().count() != other
.arrayElements().count())
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 ();
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
)
232 _CodeModelItem::~_CodeModelItem()
236 CodeModelItem
_CodeModelItem::toItem() const
238 return CodeModelItem(const_cast<_CodeModelItem
*>(this));
241 int _CodeModelItem::kind() const
246 void _CodeModelItem::setKind(int kind
)
251 QStringList
_CodeModelItem::qualifiedName() const
253 QStringList q
= scope();
255 if (!name().isEmpty())
261 QString
_CodeModelItem::name() const
266 void _CodeModelItem::setName(const QString
&name
)
271 QStringList
_CodeModelItem::scope() const
276 void _CodeModelItem::setScope(const QStringList
&scope
)
281 QString
_CodeModelItem::fileName() const
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
)
305 _M_startColumn
= column
;
308 void _CodeModelItem::getEndPosition(int *line
, int *column
)
311 *column
= _M_endColumn
;
314 void _CodeModelItem::setEndPosition(int line
, int column
)
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
)
387 CodeModel::ClassType
_ClassModelItem::classType() const
392 void _ClassModelItem::addPropertyDeclaration(const QString
&propertyDeclaration
)
394 _M_propertyDeclarations
<< propertyDeclaration
;
398 // ---------------------------------------------------------------------------
399 FunctionModelItem
_ScopeModelItem::declaredFunction(FunctionModelItem item
)
401 FunctionList function_list
= findFunctions(item
->name());
403 foreach (FunctionModelItem fun
, function_list
)
405 if (fun
->isSimilar(item
))
409 return FunctionModelItem();
412 ClassList
_ScopeModelItem::classes() const
414 return _M_classes
.values();
417 TypeAliasList
_ScopeModelItem::typeAliases() const
419 return _M_typeAliases
.values();
422 VariableList
_ScopeModelItem::variables() const
424 return _M_variables
.values();
427 FunctionList
_ScopeModelItem::functions() const
429 return _M_functions
.values();
432 void _ScopeModelItem::addEnumsDeclaration(const QString
&enumsDeclaration
)
434 _M_enumsDeclarations
<< enumsDeclaration
;
437 FunctionDefinitionList
_ScopeModelItem::functionDefinitions() const
439 return _M_functionDefinitions
.values();
442 EnumList
_ScopeModelItem::enums() const
444 return _M_enums
.values();
447 void _ScopeModelItem::addClass(ClassModelItem item
)
449 QString name
= item
->name();
450 int idx
= name
.indexOf("<");
452 _M_classes
.insert(name
.left(idx
), item
);
453 _M_classes
.insert(name
, item
);
456 void _ScopeModelItem::addFunction(FunctionModelItem item
)
458 _M_functions
.insert(item
->name(), item
);
461 void _ScopeModelItem::addFunctionDefinition(FunctionDefinitionModelItem item
)
463 _M_functionDefinitions
.insert(item
->name(), item
);
466 void _ScopeModelItem::addVariable(VariableModelItem item
)
468 _M_variables
.insert(item
->name(), item
);
471 void _ScopeModelItem::addTypeAlias(TypeAliasModelItem item
)
473 _M_typeAliases
.insert(item
->name(), item
);
476 void _ScopeModelItem::addEnum(EnumModelItem item
)
478 _M_enums
.insert(item
->name(), item
);
481 void _ScopeModelItem::removeClass(ClassModelItem item
)
483 QHash
<QString
, ClassModelItem
>::Iterator it
= _M_classes
.find(item
->name());
485 if (it
!= _M_classes
.end() && it
.value() == item
)
486 _M_classes
.erase(it
);
489 void _ScopeModelItem::removeFunction(FunctionModelItem item
)
491 QMultiHash
<QString
, FunctionModelItem
>::Iterator it
= _M_functions
.find(item
->name());
493 while (it
!= _M_functions
.end() && it
.key() == item
->name()
494 && it
.value() != item
)
499 if (it
!= _M_functions
.end() && it
.value() == item
)
501 _M_functions
.erase(it
);
505 void _ScopeModelItem::removeFunctionDefinition(FunctionDefinitionModelItem item
)
507 QMultiHash
<QString
, FunctionDefinitionModelItem
>::Iterator it
= _M_functionDefinitions
.find(item
->name());
509 while (it
!= _M_functionDefinitions
.end() && it
.key() == item
->name()
510 && it
.value() != item
)
515 if (it
!= _M_functionDefinitions
.end() && it
.value() == item
)
517 _M_functionDefinitions
.erase(it
);
521 void _ScopeModelItem::removeVariable(VariableModelItem item
)
523 QHash
<QString
, VariableModelItem
>::Iterator it
= _M_variables
.find(item
->name());
525 if (it
!= _M_variables
.end() && it
.value() == item
)
526 _M_variables
.erase(it
);
529 void _ScopeModelItem::removeTypeAlias(TypeAliasModelItem item
)
531 QHash
<QString
, TypeAliasModelItem
>::Iterator it
= _M_typeAliases
.find(item
->name());
533 if (it
!= _M_typeAliases
.end() && it
.value() == item
)
534 _M_typeAliases
.erase(it
);
537 void _ScopeModelItem::removeEnum(EnumModelItem item
)
539 QHash
<QString
, EnumModelItem
>::Iterator it
= _M_enums
.find(item
->name());
541 if (it
!= _M_enums
.end() && it
.value() == item
)
545 ClassModelItem
_ScopeModelItem::findClass(const QString
&name
) const
547 return _M_classes
.value(name
);
550 VariableModelItem
_ScopeModelItem::findVariable(const QString
&name
) const
552 return _M_variables
.value(name
);
555 TypeAliasModelItem
_ScopeModelItem::findTypeAlias(const QString
&name
) const
557 return _M_typeAliases
.value(name
);
560 EnumModelItem
_ScopeModelItem::findEnum(const QString
&name
) const
562 return _M_enums
.value(name
);
565 FunctionList
_ScopeModelItem::findFunctions(const QString
&name
) const
567 return _M_functions
.values(name
);
570 FunctionDefinitionList
_ScopeModelItem::findFunctionDefinitions(const QString
&name
) const
572 return _M_functionDefinitions
.values(name
);
575 // ---------------------------------------------------------------------------
576 NamespaceList
_NamespaceModelItem::namespaces() const
578 return _M_namespaces
.values();
580 void _NamespaceModelItem::addNamespace(NamespaceModelItem item
)
582 _M_namespaces
.insert(item
->name(), item
);
584 void _NamespaceModelItem::removeNamespace(NamespaceModelItem item
)
586 QHash
<QString
, NamespaceModelItem
>::Iterator it
= _M_namespaces
.find(item
->name());
588 if (it
!= _M_namespaces
.end() && it
.value() == item
)
589 _M_namespaces
.erase(it
);
592 NamespaceModelItem
_NamespaceModelItem::findNamespace(const QString
&name
) const
594 return _M_namespaces
.value(name
);
597 // ---------------------------------------------------------------------------
598 TypeInfo
_ArgumentModelItem::type() const
603 void _ArgumentModelItem::setType(const TypeInfo
&type
)
608 bool _ArgumentModelItem::defaultValue() const
610 return _M_defaultValue
;
613 void _ArgumentModelItem::setDefaultValue(bool defaultValue
)
615 _M_defaultValue
= defaultValue
;
618 // ---------------------------------------------------------------------------
619 bool _FunctionModelItem::isSimilar(FunctionModelItem other
) const
621 if (name() != other
->name())
624 if (isConstant() != other
->isConstant())
627 if (isVariadics() != other
->isVariadics())
630 if (arguments().count() != other
->arguments().count())
633 // ### check the template parameters
635 for (int i
=0; i
<arguments().count(); ++i
)
637 ArgumentModelItem arg1
= arguments().at(i
);
638 ArgumentModelItem arg2
= other
->arguments().at(i
);
640 if (arg1
->type() != arg2
->type())
647 ArgumentList
_FunctionModelItem::arguments() const
652 void _FunctionModelItem::addArgument(ArgumentModelItem item
)
654 _M_arguments
.append(item
);
657 void _FunctionModelItem::removeArgument(ArgumentModelItem item
)
659 _M_arguments
.removeAt(_M_arguments
.indexOf(item
));
662 CodeModel::FunctionType
_FunctionModelItem::functionType() const
664 return _M_functionType
;
667 void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType
)
669 _M_functionType
= functionType
;
672 bool _FunctionModelItem::isVariadics() const
674 return f
._M_isVariadics
;
677 void _FunctionModelItem::setVariadics(bool isVariadics
)
679 f
._M_isVariadics
= isVariadics
;
682 bool _FunctionModelItem::isVirtual() const
684 return f
._M_isVirtual
;
687 void _FunctionModelItem::setVirtual(bool isVirtual
)
689 f
._M_isVirtual
= isVirtual
;
692 bool _FunctionModelItem::isInline() const
694 return f
._M_isInline
;
697 void _FunctionModelItem::setInline(bool isInline
)
699 f
._M_isInline
= isInline
;
702 bool _FunctionModelItem::isExplicit() const
704 return f
._M_isExplicit
;
707 void _FunctionModelItem::setExplicit(bool isExplicit
)
709 f
._M_isExplicit
= isExplicit
;
712 bool _FunctionModelItem::isAbstract() const
714 return f
._M_isAbstract
;
717 void _FunctionModelItem::setAbstract(bool isAbstract
)
719 f
._M_isAbstract
= isAbstract
;
723 bool _FunctionModelItem::isInvokable() const
725 return _M_isInvokable
;
728 void _FunctionModelItem::setInvokable(bool isInvokable
)
730 _M_isInvokable
= isInvokable
;
733 // ---------------------------------------------------------------------------
734 TypeInfo
_TypeAliasModelItem::type() const
739 void _TypeAliasModelItem::setType(const TypeInfo
&type
)
744 // ---------------------------------------------------------------------------
745 CodeModel::AccessPolicy
_EnumModelItem::accessPolicy() const
747 return _M_accessPolicy
;
750 void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy
)
752 _M_accessPolicy
= accessPolicy
;
755 EnumeratorList
_EnumModelItem::enumerators() const
757 return _M_enumerators
;
760 void _EnumModelItem::addEnumerator(EnumeratorModelItem item
)
762 _M_enumerators
.append(item
);
765 void _EnumModelItem::removeEnumerator(EnumeratorModelItem item
)
767 _M_enumerators
.removeAt(_M_enumerators
.indexOf(item
));
770 // ---------------------------------------------------------------------------
771 QString
_EnumeratorModelItem::value() const
776 void _EnumeratorModelItem::setValue(const QString
&value
)
781 // ---------------------------------------------------------------------------
782 TypeInfo
_TemplateParameterModelItem::type() const
787 void _TemplateParameterModelItem::setType(const TypeInfo
&type
)
792 bool _TemplateParameterModelItem::defaultValue() const
794 return _M_defaultValue
;
797 void _TemplateParameterModelItem::setDefaultValue(bool defaultValue
)
799 _M_defaultValue
= defaultValue
;
802 // ---------------------------------------------------------------------------
803 ScopeModelItem
_ScopeModelItem::create(CodeModel
*model
)
805 ScopeModelItem
item(new _ScopeModelItem(model
));
809 ClassModelItem
_ClassModelItem::create(CodeModel
*model
)
811 ClassModelItem
item(new _ClassModelItem(model
));
815 NamespaceModelItem
_NamespaceModelItem::create(CodeModel
*model
)
817 NamespaceModelItem
item(new _NamespaceModelItem(model
));
821 FileModelItem
_FileModelItem::create(CodeModel
*model
)
823 FileModelItem
item(new _FileModelItem(model
));
827 ArgumentModelItem
_ArgumentModelItem::create(CodeModel
*model
)
829 ArgumentModelItem
item(new _ArgumentModelItem(model
));
833 FunctionModelItem
_FunctionModelItem::create(CodeModel
*model
)
835 FunctionModelItem
item(new _FunctionModelItem(model
));
839 FunctionDefinitionModelItem
_FunctionDefinitionModelItem::create(CodeModel
*model
)
841 FunctionDefinitionModelItem
item(new _FunctionDefinitionModelItem(model
));
845 VariableModelItem
_VariableModelItem::create(CodeModel
*model
)
847 VariableModelItem
item(new _VariableModelItem(model
));
851 TypeAliasModelItem
_TypeAliasModelItem::create(CodeModel
*model
)
853 TypeAliasModelItem
item(new _TypeAliasModelItem(model
));
857 EnumModelItem
_EnumModelItem::create(CodeModel
*model
)
859 EnumModelItem
item(new _EnumModelItem(model
));
863 EnumeratorModelItem
_EnumeratorModelItem::create(CodeModel
*model
)
865 EnumeratorModelItem
item(new _EnumeratorModelItem(model
));
869 TemplateParameterModelItem
_TemplateParameterModelItem::create(CodeModel
*model
)
871 TemplateParameterModelItem
item(new _TemplateParameterModelItem(model
));
875 // ---------------------------------------------------------------------------
876 TypeInfo
_MemberModelItem::type() const
881 void _MemberModelItem::setType(const TypeInfo
&type
)
886 CodeModel::AccessPolicy
_MemberModelItem::accessPolicy() const
888 return _M_accessPolicy
;
891 void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy
)
893 _M_accessPolicy
= accessPolicy
;
896 bool _MemberModelItem::isStatic() const
898 return f
._M_isStatic
;
901 void _MemberModelItem::setStatic(bool isStatic
)
903 f
._M_isStatic
= isStatic
;
906 bool _MemberModelItem::isConstant() const
908 return f
._M_isConstant
;
911 void _MemberModelItem::setConstant(bool isConstant
)
913 f
._M_isConstant
= isConstant
;
916 bool _MemberModelItem::isVolatile() const
918 return f
._M_isVolatile
;
921 void _MemberModelItem::setVolatile(bool isVolatile
)
923 f
._M_isVolatile
= isVolatile
;
926 bool _MemberModelItem::isAuto() const
931 void _MemberModelItem::setAuto(bool isAuto
)
933 f
._M_isAuto
= isAuto
;
936 bool _MemberModelItem::isFriend() const
938 return f
._M_isFriend
;
941 void _MemberModelItem::setFriend(bool isFriend
)
943 f
._M_isFriend
= isFriend
;
946 bool _MemberModelItem::isRegister() const
948 return f
._M_isRegister
;
951 void _MemberModelItem::setRegister(bool isRegister
)
953 f
._M_isRegister
= isRegister
;
956 bool _MemberModelItem::isExtern() const
958 return f
._M_isExtern
;
961 void _MemberModelItem::setExtern(bool isExtern
)
963 f
._M_isExtern
= isExtern
;
966 bool _MemberModelItem::isMutable() const
968 return f
._M_isMutable
;
971 void _MemberModelItem::setMutable(bool isMutable
)
973 f
._M_isMutable
= isMutable
;
976 // kate: space-indent on; indent-width 2; replace-tabs on;