1 /****************************************************************************
2 **
3 ** Copyright (C) 2001-2004 Roberto Raggi
4 ** Copyright (C) 2015 The Qt Company Ltd.
5 ** Contact: http://www.qt.io/licensing/
6 **
7 ** This file is part of the qt3to4 porting application of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see http://www.qt.io/terms-conditions. For further
16 ** information use the contact form at http://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 2.1 or version 3 as published by the Free
21 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
22 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
23 ** following information to ensure the GNU Lesser General Public License
24 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
25 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
26 **
27 ** As a special exception, The Qt Company gives you certain additional
28 ** rights. These rights are described in The Qt Company LGPL Exception
29 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
30 **
31 ** GNU General Public License Usage
32 ** Alternatively, this file may be used under the terms of the GNU
33 ** General Public License version 3.0 as published by the Free Software
34 ** Foundation and appearing in the file LICENSE.GPL included in the
35 ** packaging of this file. Please review the following information to
36 ** ensure the GNU General Public License version 3.0 requirements will be
37 ** met: http://www.gnu.org/copyleft/gpl.html.
38 **
39 ** $QT_END_LICENSE$
40 **
41 ****************************************************************************/
42
43 #ifndef CODEMODEL_H
44 #define CODEMODEL_H
45
46 #include "smallobject.h"
47 #include "tokenengine.h"
48
49 #include <QByteArray>
50 #include <QList>
51 #include <QMap>
52 #include <QHash>
53
54 QT_BEGIN_NAMESPACE
55
56 namespace CodeModel
57 {
58
59 // types
60 struct Type;
61 struct EnumType;
62 struct EnumeratorType;
63 struct ClassType;
64 struct BuiltinType;
65 struct PointerType;
66 struct ReferenceType;
67 struct GenericType;
68 struct AliasType;
69 struct FunctionType;
70 struct UnknownType;
71
72 // Scopes contain child scopes, members and types.
73 struct Scope;
74 struct ClassScope;
75 struct NamespaceScope;
76 struct BlockScope;
77
78 // Members introduces names into scopes, and are also linked to a specific
79 // token in a source file.
80 struct Member;
81 struct FunctionMember;
82 struct VariableMember;
83 struct UsingDeclarationMember;
84 struct NamespaceMember;
85 struct TypeMember;
86
87 // Name uses links uses of a name to its declaration (a Member), and also to a
88 // token in a source file.
89 struct NameUse;
90
91 struct Argument;
92 struct UsingDirectiveLink;
93
94 template <typename CollectedType>
95 class Collection: public QMultiHash<QByteArray, CollectedType *>
96 {
97 public:
add(CollectedType * collectedItem)98 void add(CollectedType *collectedItem)
99 { this->insert(collectedItem->name(), collectedItem); }
100 };
101
102 typedef Collection<Scope> ScopeCollection;
103 typedef Collection<Member> MemberCollection;
104 typedef Collection<Type> TypeCollection;
105 typedef Collection<NameUse> NameUseCollection;
106 typedef Collection<Argument> ArgumentCollection;
107
108 struct SemanticInfo
109 {
110 CodeModel::NamespaceScope *codeModel;
111
112 // tokenindex -> NameUse* map. Use map here bacause we expect name uses to
113 // be sparesly distributed among the tokens.
114 QMap<int, NameUse*> nameUses;
115 };
116
117
118 struct Item
119 {
ItemItem120 Item() {}
~ItemItem121 virtual ~Item() {}
122 virtual QByteArray name() const = 0;
123 };
124
125 struct Type: public Item
126 {
127 virtual QByteArray name() const =0;
128
toEnumTypeType129 virtual EnumType *toEnumType() const
130 { return 0; }
131
toClassTypeType132 virtual ClassType *toClassType() const
133 { return 0; }
134
toUnknownTypeType135 virtual UnknownType *toUnknownType() const
136 { return 0; }
137
toBuiltinTypeType138 virtual BuiltinType *toBuiltinType() const
139 { return 0; }
140
toPointerTypeType141 virtual PointerType *toPointerType() const
142 { return 0; }
143
toReferenceTypeType144 virtual ReferenceType *toReferenceType() const
145 { return 0; }
146
toGenericTypeType147 virtual GenericType *toGenericType() const
148 { return 0; }
149
toAliasTypeType150 virtual AliasType *toAliasType() const
151 { return 0; }
152 };
153
154 struct Scope: public Item
155 {
ScopeScope156 Scope()
157 : m_parent(0) {}
158
setParentScope159 void setParent(Scope *parent)
160 { m_parent = parent; }
161
parentScope162 Scope *parent() const
163 { return m_parent; }
164
nameScope165 QByteArray name() const
166 { return m_name; }
167
setNameScope168 void setName(const QByteArray &name)
169 { m_name=name; }
170
toNamespaceScopeScope171 virtual NamespaceScope *toNamespaceScope() const
172 { return 0; }
173
toClassScopeScope174 virtual ClassScope *toClassScope() const
175 { return 0; }
176
toBlockScopeScope177 virtual BlockScope *toBlockScope() const
178 { return 0; }
179
scopesScope180 const Collection<Scope> scopes() const
181 { return m_scopes; }
typesScope182 const Collection<Type> types() const
183 { return m_types; }
membersScope184 const Collection<Member> members() const
185 { return m_members; }
nameUsesScope186 const Collection<NameUse> nameUses() const
187 { return m_nameUses; }
188
189 void addScope(Scope *scope);
190 void addType(Type *type);
191 void addMember(Member *member);
192 void addNameUse(NameUse *nameUse);
193 private:
194 Scope *m_parent;
195 QByteArray m_name;
196 Collection<Scope> m_scopes;
197 Collection<Type> m_types;
198 Collection<Member> m_members;
199 Collection<NameUse> m_nameUses;
200 };
201
202 struct Member: public Item
203 {
204 enum Binding // ### not used yet
205 {
206 Static,
207 Instance
208 };
209
210 enum Access // ### not used yet
211 {
212 Public,
213 Protected,
214 Private
215 };
216
MemberMember217 Member()
218 : m_binding(Static), m_access(Public),
219 m_parent(0), m_constant(0), m_static(0) {}
220
nameMember221 QByteArray name() const
222 { return m_name; }
223
setNameMember224 void setName(const QByteArray &name)
225 { m_name = name; }
226
nameTokenMember227 TokenEngine::TokenRef nameToken() const
228 { return m_nameToken; }
229
setNameTokenMember230 void setNameToken(TokenEngine::TokenRef nameToken)
231 { m_nameToken = nameToken; }
232
bindingMember233 Binding binding() const
234 { return m_binding; }
235
setBindingMember236 void setBinding(Binding binding)
237 { m_binding = binding; }
238
accessMember239 Access access() const
240 { return m_access; }
241
setAccessMember242 void setAccess(Access access)
243 { m_access = access; }
244
isConstantMember245 bool isConstant() const
246 { return m_constant; }
247
setConstantMember248 void setConstant(bool b)
249 { m_constant = b; }
250
isStaticMember251 bool isStatic() const
252 { return m_static; }
253
setStaticMember254 void setStatic(bool b)
255 { m_static = b; }
256
parentMember257 Scope *parent() const
258 { return m_parent; }
259
setParentMember260 void setParent(Scope *parent)
261 { m_parent = parent; }
262
toFunctionMemberMember263 virtual FunctionMember *toFunctionMember() const
264 { return 0; }
265
toVariableMemberMember266 virtual VariableMember *toVariableMember() const
267 { return 0; }
268
toUsingDeclarationMemberMember269 virtual UsingDeclarationMember *toUsingDeclarationMember() const
270 { return 0; }
271
toNamespaceMemberMember272 virtual NamespaceMember *toNamespaceMember() const
273 { return 0; }
274
toTypeMemberMember275 virtual TypeMember *toTypeMember() const
276 { return 0; }
277
278 private:
279 Binding m_binding;
280 Access m_access;
281 Scope *m_parent;
282 QByteArray m_name;
283 TokenEngine::TokenRef m_nameToken;
284 uint m_constant : 1;
285 uint m_static : 1;
286 };
287
288 struct ClassScope: public Scope
289 {
baseClassesClassScope290 const Collection<Type> baseClasses() const
291 { return m_baseClasses; }
292
addBaseClassClassScope293 void addBaseClass(Type *baseClass)
294 {
295 Q_ASSERT(baseClass->toClassType());
296 m_baseClasses.add(baseClass);
297 }
298
toClassScopeClassScope299 virtual ClassScope *toClassScope() const
300 { return const_cast<ClassScope*>(this); }
301
302 private:
303 Collection<Type> m_baseClasses;
304 };
305
306 struct UsingDirectiveLinkable : public Scope
307 {
usingDirectiveLinksUsingDirectiveLinkable308 const QList<UsingDirectiveLink *> usingDirectiveLinks() const
309 { return m_usingDirectiveLinks; }
310
addUsingDirectiveLinkUsingDirectiveLinkable311 void addUsingDirectiveLink(UsingDirectiveLink *usingDirectiveLink)
312 { m_usingDirectiveLinks.append(usingDirectiveLink); }
313 private:
314 QList<UsingDirectiveLink *> m_usingDirectiveLinks;
315 };
316
317 struct NamespaceScope: public UsingDirectiveLinkable
318 {
NamespaceScopeNamespaceScope319 NamespaceScope() {}
320
toNamespaceScopeNamespaceScope321 virtual NamespaceScope *toNamespaceScope() const
322 { return const_cast<NamespaceScope*>(this); }
323 };
324
325 struct BlockScope: public UsingDirectiveLinkable
326 {
BlockScopeBlockScope327 BlockScope() {}
328
toBlockScopeBlockScope329 virtual BlockScope *toBlockScope() const
330 { return const_cast<BlockScope*>(this); }
331 };
332
333 struct EnumType: public Type
334 {
EnumTypeEnumType335 EnumType()
336 : m_parent(0) {}
337
nameEnumType338 QByteArray name() const
339 { return m_name; }
340
setNameEnumType341 void setName(const QByteArray &name)
342 { m_name = name; }
343
parentEnumType344 Scope *parent() const
345 { return m_parent; }
346
setParentEnumType347 void setParent(Scope *parent)
348 { m_parent = parent; }
349
toEnumTypeEnumType350 virtual EnumType *toEnumType() const
351 { return const_cast<EnumType*>(this); }
352
353 private:
354 Scope *m_parent;
355 QByteArray m_name;
356 };
357
358 struct UnknownType: public Type
359 {
UnknownTypeUnknownType360 UnknownType()
361 : m_parent(0) {}
362
nameUnknownType363 QByteArray name() const
364 { return m_name; }
365
setNameUnknownType366 void setName(const QByteArray &name)
367 { m_name = name; }
368
parentUnknownType369 Scope *parent() const
370 { return m_parent; }
371
setParentUnknownType372 void setParent(Scope *parent)
373 { m_parent = parent; }
374
toUnknownTypeUnknownType375 virtual UnknownType *toUnknownType() const
376 { return const_cast<UnknownType*>(this); }
377
378 private:
379 Scope *m_parent;
380 QByteArray m_name;
381 };
382
383 struct ClassType: public Type
384 {
ClassTypeClassType385 ClassType()
386 : m_parent(0), m_scope(0) {}
387
scopeClassType388 ClassScope *scope() const
389 { return m_scope; }
390
setScopeClassType391 void setScope(ClassScope *scope)
392 { m_scope = scope; }
393
nameClassType394 QByteArray name() const
395 { return m_scope ? m_scope->name() : /*anonymous*/ QByteArray(); }
396
parentClassType397 Scope *parent() const
398 { return m_parent; }
399
setParentClassType400 void setParent(Scope *parent)
401 { m_parent = parent; }
402
toClassTypeClassType403 virtual ClassType *toClassType() const
404 { return const_cast<ClassType*>(this); }
405
406 private:
407 Scope *m_parent;
408 ClassScope *m_scope;
409
410 };
411
412 struct BuiltinType: public Type
413 {
414 protected:
BuiltinTypeBuiltinType415 BuiltinType(const QByteArray &name, Scope *parent)
416 : m_name(name), m_parent(parent) {}
417
418 public:
nameBuiltinType419 QByteArray name() const
420 { return m_name; }
421
parentBuiltinType422 Scope *parent() const
423 { return m_parent; }
424
toBuiltinTypeBuiltinType425 virtual BuiltinType *toBuiltinType() const
426 { return const_cast<BuiltinType*>(this); }
427
428 static BuiltinType Bool;
429 static BuiltinType Void;
430 static BuiltinType Char;
431 static BuiltinType Short;
432 static BuiltinType Int;
433 static BuiltinType Long;
434 static BuiltinType Double;
435 static BuiltinType Float;
436 static BuiltinType Unsigned;
437 static BuiltinType Signed;
438 // ### more
439
440 private:
441 QByteArray m_name;
442 Scope *m_parent;
443 };
444
445 struct PointerType: public Type
446 {
PointerTypePointerType447 PointerType()
448 : m_parent(0), m_baseType(0) {}
449
baseTypePointerType450 Type *baseType() const
451 { return m_baseType; }
452
setBaseTypePointerType453 void setBaseType(Type *baseType)
454 { m_baseType = baseType; }
455
namePointerType456 QByteArray name() const
457 { return m_baseType->name(); }
458
parentPointerType459 Scope *parent() const
460 { return m_parent; }
461
setParentPointerType462 void setParent(Scope *parent)
463 { m_parent = parent; }
464
toPointerTypePointerType465 virtual PointerType *toPointerType() const
466 { return const_cast<PointerType*>(this); }
467
468 private:
469 Scope *m_parent;
470 Type *m_baseType;
471 };
472
473 struct ReferenceType: public Type
474 {
ReferenceTypeReferenceType475 ReferenceType()
476 : m_parent(0), m_baseType(0) {}
477
baseTypeReferenceType478 Type *baseType() const
479 { return m_baseType; }
480
setBaseTypeReferenceType481 void setBaseType(Type *baseType)
482 { m_baseType = baseType; }
483
nameReferenceType484 QByteArray name() const
485 { return m_baseType->name(); }
486
parentReferenceType487 Scope *parent() const
488 { return m_parent; }
489
setParentReferenceType490 void setParent(Scope *parent)
491 { m_parent = parent; }
492
toReferenceTypeReferenceType493 virtual ReferenceType *toReferenceType() const
494 { return const_cast<ReferenceType*>(this); }
495
496 private:
497 Scope *m_parent;
498 Type *m_baseType;
499 };
500
501 struct GenericType: public Type // ### implement me
502 {
toGenericTypeGenericType503 virtual GenericType *toGenericType() const
504 { return const_cast<GenericType*>(this); }
505 };
506
507 struct AliasType: public Type // ### implement me
508 {
AliasTypeAliasType509 AliasType ()
510 : m_parent(0) {}
511
nameAliasType512 QByteArray name() const
513 { return m_name; }
514
parentAliasType515 Scope *parent() const
516 { return m_parent; }
517
toAliasTypeAliasType518 virtual AliasType *toAliasType() const
519 { return const_cast<AliasType*>(this); }
520 private:
521 QByteArray m_name;
522 Scope *m_parent;
523 };
524
525 struct Argument: public Item
526 {
ArgumentArgument527 Argument()
528 : m_parent(0), m_type(0) {}
529
typeArgument530 Type *type() const
531 { return m_type; }
532
setTypeArgument533 void setType(Type *type)
534 { m_type = type; }
535
nameArgument536 QByteArray name() const
537 { return m_name; }
538
setNameArgument539 void setName(const QByteArray &name)
540 { m_name = name; }
541
nameTokenArgument542 TokenEngine::TokenRef nameToken() const
543 { return m_nameToken; }
544
setNameTokenArgument545 void setNameToken(TokenEngine::TokenRef nameToken)
546 { m_nameToken = nameToken; }
547
parentArgument548 virtual FunctionMember *parent() const
549 { return m_parent; }
550
setParentArgument551 void setParent(FunctionMember *parent)
552 { m_parent = parent; }
553
554 private:
555 FunctionMember *m_parent;
556 Type *m_type;
557 QByteArray m_name;
558 TokenEngine::TokenRef m_nameToken;
559 };
560
561 struct FunctionMember: public Member
562 {
FunctionMemberFunctionMember563 inline FunctionMember()
564 : m_returnType(0),
565 m_functionBodyScope(0),
566 m_signal(0),
567 m_virtual(0), m_abstract(0) { m_slot = 0; }
568
toFunctionMemberFunctionMember569 virtual FunctionMember *toFunctionMember() const
570 { return const_cast<FunctionMember*>(this); }
571
returnTypeFunctionMember572 Type *returnType() const
573 { return m_returnType; }
574
setReturnTypeFunctionMember575 void setReturnType(Type *type)
576 { m_returnType = type; }
577
argumentsFunctionMember578 const Collection<Argument> arguments() const
579 { return m_arguments; }
580
addArgumentFunctionMember581 void addArgument(Argument *argument)
582 { m_arguments.insert(argument->name(), argument); }
583
setFunctionBodyScopeFunctionMember584 void setFunctionBodyScope(BlockScope *functionBodyScope)
585 { m_functionBodyScope = functionBodyScope; }
586
functionBodyScopeFunctionMember587 BlockScope *functionBodyScope() const
588 {return m_functionBodyScope;}
589
isSignalFunctionMember590 bool isSignal() const
591 { return m_signal; }
592
setSignalFunctionMember593 void setSignal(bool b)
594 { m_signal = b; }
595
isSlotFunctionMember596 bool isSlot() const
597 { return m_slot; }
598
setSlotFunctionMember599 void setSlot(bool b)
600 { m_slot = b; }
601
isVirtualFunctionMember602 bool isVirtual() const
603 { return m_virtual; }
604
setVirtualFunctionMember605 void setVirtual(bool b)
606 { m_virtual = b; }
607
isAbstractFunctionMember608 bool isAbstract() const
609 { return m_abstract; }
610
setAbstractFunctionMember611 void setAbstract(bool b)
612 { m_abstract = b; }
613
614 private:
615 Type *m_returnType;
616 Collection<Argument> m_arguments;
617 BlockScope *m_functionBodyScope;
618 uint m_signal: 1;
619 uint m_slot: 1;
620 uint m_virtual: 1;
621 uint m_abstract: 1;
622 };
623
624 struct VariableMember: public Member
625 {
VariableMemberVariableMember626 VariableMember()
627 : m_type(0) {}
628
typeVariableMember629 Type *type() const
630 { return m_type; }
631
setTypeVariableMember632 void setType(Type *type)
633 { m_type = type; }
634
toVariableMemberVariableMember635 virtual VariableMember *toVariableMember() const
636 { return const_cast<VariableMember*>(this); }
637
638 private:
639 Type *m_type;
640 };
641
642 struct UsingDeclarationMember: public Member
643 {
UsingDeclarationMemberUsingDeclarationMember644 UsingDeclarationMember()
645 : m_member(0) {}
646
toUsingDeclarationMemberUsingDeclarationMember647 virtual UsingDeclarationMember *toUsingDeclarationMember() const
648 { return const_cast<UsingDeclarationMember*>(this); }
649
memberUsingDeclarationMember650 Member *member() const
651 { return m_member; }
652
setMemberUsingDeclarationMember653 void setMember(Member *member)
654 { m_member = member; }
655
656 private:
657 Member *m_member;
658 };
659
660 struct NamespaceMember: public Member
661 {
NamespaceMemberNamespaceMember662 NamespaceMember()
663 :m_namespaceScope(0) {}
664
toNamespaceMemberNamespaceMember665 virtual NamespaceMember *toNamespaceMember() const
666 { return const_cast<NamespaceMember*>(this); }
667
namespaceScopeNamespaceMember668 NamespaceScope *namespaceScope() const
669 { return m_namespaceScope; }
670
setNamespaceScopeNamespaceMember671 void setNamespaceScope(NamespaceScope *namespaceScope)
672 { m_namespaceScope = namespaceScope; }
673 private:
674 NamespaceScope *m_namespaceScope;
675 };
676
677 struct TypeMember: public Member
678 {
TypeMemberTypeMember679 TypeMember()
680 :m_type(0) {}
681
toTypeMemberTypeMember682 virtual TypeMember *toTypeMember() const
683 { return const_cast<TypeMember*>(this); }
684
typeTypeMember685 Type *type() const
686 { return m_type; }
687
setTypeTypeMember688 void setType(Type *type)
689 { m_type = type; }
690 private:
691 Type *m_type;
692
693 };
694
695 struct NameUse: public Item
696 {
NameUseNameUse697 NameUse()
698 : m_declaration(0), m_parent(0) {}
699
nameNameUse700 QByteArray name() const
701 { return m_name; }
702
setNameNameUse703 void setName(const QByteArray &name)
704 { m_name = name; }
705
nameTokenNameUse706 TokenEngine::TokenRef nameToken() const
707 { return m_nameToken; }
708
setNameTokenNameUse709 void setNameToken(TokenEngine::TokenRef nameToken)
710 { m_nameToken = nameToken; }
711
parentNameUse712 Scope *parent() const
713 { return m_parent; }
714
setParentNameUse715 void setParent(Scope *parent)
716 { m_parent = parent; }
717
declarationNameUse718 Member *declaration() const
719 { return m_declaration; }
720
setDeclarationNameUse721 void setDeclaration(Member *parent)
722 { m_declaration = parent; }
723
724 private:
725 QByteArray m_name;
726 TokenEngine::TokenRef m_nameToken;
727 Member *m_declaration;
728 Scope *m_parent;
729 };
730
731 struct UsingDirectiveLink: public Item
732 {
UsingDirectiveLinkUsingDirectiveLink733 UsingDirectiveLink()
734 : m_parent(0), m_targetNamespace(0), m_insertionNamespace(0) {}
735
nameUsingDirectiveLink736 QByteArray name() const
737 { return QByteArray(); }
738
parentUsingDirectiveLink739 Scope *parent() const
740 { return m_parent; }
741
setParentUsingDirectiveLink742 void setParent(Scope *parent)
743 { m_parent = parent; }
744
targetNamespaceUsingDirectiveLink745 NamespaceScope *targetNamespace() const
746 { return m_targetNamespace; }
747
setTargetNamespaceUsingDirectiveLink748 void setTargetNamespace(NamespaceScope *targetNamespace)
749 { m_targetNamespace = targetNamespace; }
750
insertionNamespaceUsingDirectiveLink751 NamespaceScope *insertionNamespace() const
752 { return m_insertionNamespace; }
753
setInsertionNamespaceUsingDirectiveLink754 void setInsertionNamespace(NamespaceScope *insertionNamespace)
755 { m_insertionNamespace = insertionNamespace; }
756 private:
757 Scope *m_parent;
758 // targetNamespace is the namespace specified by the using directive.
759 NamespaceScope *m_targetNamespace;
760 // m_insertionNamespace is the namespace where the names from
761 // targetNamespace will be inserted. The C++ standard (7.3.4.1)
762 // defines this as the nearest namespace that includes both m_parent
763 // and m_targetNamespace.
764 NamespaceScope *m_insertionNamespace;
765 };
766
767 template <class T>
Create(TypedPool<CodeModel::Item> * p)768 T *Create(TypedPool<CodeModel::Item> *p)
769 {
770 return new (p->allocate(sizeof(T))) T();
771 }
772
773 } // namespace CodeModel
774
775 QT_END_NAMESPACE
776
777 #endif // CODEMODEL_H
778