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