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 ****************************************************************************/
29 #include "codemodel_finder.h"
30 #include "class_compiler.h"
31 #include "compiler_utils.h"
39 Binder::Binder(CodeModel
*__model
, LocationManager
&__location
, Control
*__control
)
41 _M_location(__location
),
42 _M_token_stream(&_M_location
.token_stream
),
43 _M_control(__control
),
44 _M_current_function_type(CodeModel::Normal
),
49 _M_qualified_types
["char"] = QString();
50 _M_qualified_types
["double"] = QString();
51 _M_qualified_types
["float"] = QString();
52 _M_qualified_types
["int"] = QString();
53 _M_qualified_types
["long"] = QString();
54 _M_qualified_types
["short"] = QString();
55 _M_qualified_types
["void"] = QString();
62 FileModelItem
Binder::run(AST
*node
)
64 FileModelItem old
= _M_current_file
;
65 _M_current_access
= CodeModel::Public
;
67 _M_current_file
= model()->create
<FileModelItem
>();
68 updateItemPosition (_M_current_file
->toItem(), node
);
70 FileModelItem result
= _M_current_file
;
72 _M_current_file
= old
; // restore
77 ScopeModelItem
Binder::currentScope()
80 return model_static_cast
<ScopeModelItem
>(_M_current_class
);
81 else if (_M_current_namespace
)
82 return model_static_cast
<ScopeModelItem
>(_M_current_namespace
);
84 return model_static_cast
<ScopeModelItem
>(_M_current_file
);
87 TemplateParameterList
Binder::changeTemplateParameters(TemplateParameterList templateParameters
)
89 TemplateParameterList old
= _M_current_template_parameters
;
90 _M_current_template_parameters
= templateParameters
;
94 CodeModel::FunctionType
Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType
)
96 CodeModel::FunctionType old
= _M_current_function_type
;
97 _M_current_function_type
= functionType
;
101 CodeModel::AccessPolicy
Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy
)
103 CodeModel::AccessPolicy old
= _M_current_access
;
104 _M_current_access
= accessPolicy
;
108 NamespaceModelItem
Binder::changeCurrentNamespace(NamespaceModelItem item
)
110 NamespaceModelItem old
= _M_current_namespace
;
111 _M_current_namespace
= item
;
115 ClassModelItem
Binder::changeCurrentClass(ClassModelItem item
)
117 ClassModelItem old
= _M_current_class
;
118 _M_current_class
= item
;
122 FunctionDefinitionModelItem
Binder::changeCurrentFunction(FunctionDefinitionModelItem item
)
124 FunctionDefinitionModelItem old
= _M_current_function
;
125 _M_current_function
= item
;
129 int Binder::decode_token(std::size_t index
) const
131 return _M_token_stream
->kind(index
);
134 CodeModel::AccessPolicy
Binder::decode_access_policy(std::size_t index
) const
136 switch (decode_token(index
))
139 return CodeModel::Private
;
143 return CodeModel::Public
;
146 return CodeModel::Public
;
150 CodeModel::ClassType
Binder::decode_class_type(std::size_t index
) const
152 switch (decode_token(index
))
155 return CodeModel::Class
;
157 return CodeModel::Struct
;
159 return CodeModel::Union
;
161 std::cerr
<< "** WARNING unrecognized class type" << std::endl
;
163 return CodeModel::Class
;
166 const NameSymbol
*Binder::decode_symbol(std::size_t index
) const
168 return _M_token_stream
->symbol(index
);
171 void Binder::visitAccessSpecifier(AccessSpecifierAST
*node
)
173 const ListNode
<std::size_t> *it
= node
->specs
;
178 const ListNode
<std::size_t> *end
= it
;
182 switch (decode_token(it
->element
))
188 changeCurrentAccess(CodeModel::Public
);
189 changeCurrentFunctionType(CodeModel::Normal
);
191 case Token_protected
:
192 changeCurrentAccess(CodeModel::Protected
);
193 changeCurrentFunctionType(CodeModel::Normal
);
196 changeCurrentAccess(CodeModel::Private
);
197 changeCurrentFunctionType(CodeModel::Normal
);
200 changeCurrentAccess(CodeModel::Protected
);
201 changeCurrentFunctionType(CodeModel::Signal
);
204 changeCurrentFunctionType(CodeModel::Slot
);
212 void Binder::visitSimpleDeclaration(SimpleDeclarationAST
*node
)
214 visit(node
->type_specifier
);
216 if (const ListNode
<InitDeclaratorAST
*> *it
= node
->init_declarators
)
219 const ListNode
<InitDeclaratorAST
*> *end
= it
;
222 InitDeclaratorAST
*init_declarator
= it
->element
;
223 declare_symbol(node
, init_declarator
);
230 void Binder::declare_symbol(SimpleDeclarationAST
*node
, InitDeclaratorAST
*init_declarator
)
232 DeclaratorAST
*declarator
= init_declarator
->declarator
;
234 while (declarator
&& declarator
->sub_declarator
)
235 declarator
= declarator
->sub_declarator
;
237 NameAST
*id
= declarator
->id
;
238 if (! declarator
->id
)
240 std::cerr
<< "** WARNING expected a declarator id" << std::endl
;
244 CodeModelFinder
finder(model(), this);
245 ScopeModelItem symbolScope
= finder
.resolveScope(id
, currentScope());
249 std::cerr
<< "** WARNING scope not found for symbol:"
250 << qPrintable(name_cc
.name()) << std::endl
;
254 decl_cc
.run(declarator
);
256 if (decl_cc
.isFunction())
258 name_cc
.run(id
->unqualified_name
);
260 FunctionModelItem fun
= model()->create
<FunctionModelItem
>();
261 updateItemPosition (fun
->toItem(), node
);
262 fun
->setAccessPolicy(_M_current_access
);
263 fun
->setFunctionType(_M_current_function_type
);
264 fun
->setName(name_cc
.name());
265 fun
->setAbstract(init_declarator
->initializer
!= 0);
266 fun
->setConstant(declarator
->fun_cv
!= 0);
267 fun
->setTemplateParameters(_M_current_template_parameters
);
268 applyStorageSpecifiers(node
->storage_specifiers
, model_static_cast
<MemberModelItem
>(fun
));
269 applyFunctionSpecifiers(node
->function_specifiers
, fun
);
272 TypeInfo typeInfo
= CompilerUtils::typeDescription(node
->type_specifier
,
276 fun
->setType(qualifyType(typeInfo
, symbolScope
->qualifiedName()));
279 fun
->setVariadics (decl_cc
.isVariadics ());
281 // ... and the signature
282 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
284 ArgumentModelItem arg
= model()->create
<ArgumentModelItem
>();
285 arg
->setType(qualifyType(p
.type
, _M_context
));
286 arg
->setName(p
.name
);
287 arg
->setDefaultValue(p
.defaultValue
);
289 arg
->setDefaultValueExpression(p
.defaultValueExpression
);
290 fun
->addArgument(arg
);
293 fun
->setScope(symbolScope
->qualifiedName());
294 symbolScope
->addFunction(fun
);
298 VariableModelItem var
= model()->create
<VariableModelItem
>();
299 updateItemPosition (var
->toItem(), node
);
300 var
->setTemplateParameters(_M_current_template_parameters
);
301 var
->setAccessPolicy(_M_current_access
);
302 name_cc
.run(id
->unqualified_name
);
303 var
->setName(name_cc
.name());
304 TypeInfo typeInfo
= CompilerUtils::typeDescription(node
->type_specifier
,
307 if (declarator
!= init_declarator
->declarator
308 && init_declarator
->declarator
->parameter_declaration_clause
!= 0)
310 typeInfo
.setFunctionPointer (true);
311 decl_cc
.run (init_declarator
->declarator
);
312 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
313 typeInfo
.addArgument(p
.type
);
316 var
->setType(qualifyType(typeInfo
, _M_context
));
317 applyStorageSpecifiers(node
->storage_specifiers
, model_static_cast
<MemberModelItem
>(var
));
319 var
->setScope(symbolScope
->qualifiedName());
320 symbolScope
->addVariable(var
);
324 void Binder::visitFunctionDefinition(FunctionDefinitionAST
*node
)
326 Q_ASSERT(node
->init_declarator
!= 0);
328 ScopeModelItem scope
= currentScope();
330 InitDeclaratorAST
*init_declarator
= node
->init_declarator
;
331 DeclaratorAST
*declarator
= init_declarator
->declarator
;
333 // in the case of "void (func)()" or "void ((func))()" we need to
334 // skip to the inner most. This is in line with how the declarator
335 // node is generated in 'parser.cpp'
336 while (declarator
&& declarator
->sub_declarator
)
337 declarator
= declarator
->sub_declarator
;
338 Q_ASSERT(declarator
->id
);
340 CodeModelFinder
finder(model(), this);
342 ScopeModelItem functionScope
= finder
.resolveScope(declarator
->id
, scope
);
345 name_cc
.run(declarator
->id
);
346 std::cerr
<< "** WARNING scope not found for function definition:"
347 << qPrintable(name_cc
.name()) << std::endl
348 << "\tdefinition *ignored*"
353 decl_cc
.run(declarator
);
355 Q_ASSERT(! decl_cc
.id().isEmpty());
357 FunctionDefinitionModelItem
358 old
= changeCurrentFunction(_M_model
->create
<FunctionDefinitionModelItem
>());
359 _M_current_function
->setScope(functionScope
->qualifiedName());
360 updateItemPosition (_M_current_function
->toItem(), node
);
362 Q_ASSERT(declarator
->id
->unqualified_name
!= 0);
363 name_cc
.run(declarator
->id
->unqualified_name
);
364 QString unqualified_name
= name_cc
.name();
366 _M_current_function
->setName(unqualified_name
);
367 TypeInfo tmp_type
= CompilerUtils::typeDescription(node
->type_specifier
,
370 _M_current_function
->setType(qualifyType(tmp_type
, _M_context
));
371 _M_current_function
->setAccessPolicy(_M_current_access
);
372 _M_current_function
->setFunctionType(_M_current_function_type
);
373 _M_current_function
->setConstant(declarator
->fun_cv
!= 0);
374 _M_current_function
->setTemplateParameters(_M_current_template_parameters
);
376 applyStorageSpecifiers(node
->storage_specifiers
,
377 model_static_cast
<MemberModelItem
>(_M_current_function
));
378 applyFunctionSpecifiers(node
->function_specifiers
,
379 model_static_cast
<FunctionModelItem
>(_M_current_function
));
381 _M_current_function
->setVariadics (decl_cc
.isVariadics ());
383 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
385 ArgumentModelItem arg
= model()->create
<ArgumentModelItem
>();
386 arg
->setType(qualifyType(p
.type
, functionScope
->qualifiedName()));
387 arg
->setName(p
.name
);
388 arg
->setDefaultValue(p
.defaultValue
);
390 arg
->setDefaultValueExpression(p
.defaultValueExpression
);
391 _M_current_function
->addArgument(arg
);
394 functionScope
->addFunctionDefinition(_M_current_function
);
396 FunctionModelItem prototype
= model_static_cast
<FunctionModelItem
>(_M_current_function
);
397 FunctionModelItem declared
= functionScope
->declaredFunction(prototype
);
399 // try to find a function declaration for this definition..
402 functionScope
->addFunction(prototype
);
406 applyFunctionSpecifiers(node
->function_specifiers
, declared
);
408 // fix the function type and the access policy
409 _M_current_function
->setAccessPolicy(declared
->accessPolicy());
410 _M_current_function
->setFunctionType(declared
->functionType());
413 changeCurrentFunction(old
);
416 void Binder::visitTemplateDeclaration(TemplateDeclarationAST
*node
)
418 const ListNode
<TemplateParameterAST
*> *it
= node
->template_parameters
;
420 // QtScript: we want to visit the declaration still, so that
421 // e.g. QMetaTypeId<Foo> is added to the code model
422 visit(node
->declaration
);
426 TemplateParameterList savedTemplateParameters
= changeTemplateParameters(TemplateParameterList());
429 const ListNode
<TemplateParameterAST
*> *end
= it
;
431 TemplateParameterList templateParameters
;
433 TemplateParameterAST
*parameter
= it
->element
;
434 TypeParameterAST
*type_parameter
= parameter
->type_parameter
;
437 if (!type_parameter
) {
438 // A hacky hack to work around missing support for parameter declarations in
439 // templates. We just need the to get the name of the variable, since we
440 // aren't actually compiling these anyway. We are still not supporting much
441 // more, but we are refusing to fail for a few more declarations
442 if (parameter
->parameter_declaration
== 0 ||
443 parameter
->parameter_declaration
->declarator
== 0 ||
444 parameter
->parameter_declaration
->declarator
->id
== 0) {
446 /*std::cerr << "** WARNING template declaration not supported ``";
447 Token const &tk = _M_token_stream->token ((int) node->start_token);
448 Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
450 std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
451 << std::endl << std::endl;*/
453 changeTemplateParameters(savedTemplateParameters
);
458 name
= parameter
->parameter_declaration
->declarator
->id
;
460 int tk
= decode_token(type_parameter
->type
);
461 if (tk
!= Token_typename
&& tk
!= Token_class
)
463 /*std::cerr << "** WARNING template declaration not supported ``";
464 Token const &tk = _M_token_stream->token ((int) node->start_token);
465 Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
467 std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
468 << std::endl << std::endl;*/
470 changeTemplateParameters(savedTemplateParameters
);
473 assert(tk
== Token_typename
|| tk
== Token_class
);
475 name
= type_parameter
->name
;
478 TemplateParameterModelItem p
= model()->create
<TemplateParameterModelItem
>();
480 p
->setName(name_cc
.name());
482 _M_current_template_parameters
.append(p
);
486 visit(node
->declaration
);
488 changeTemplateParameters(savedTemplateParameters
);
491 void Binder::visitTypedef(TypedefAST
*node
)
493 const ListNode
<InitDeclaratorAST
*> *it
= node
->init_declarators
;
498 const ListNode
<InitDeclaratorAST
*> *end
= it
;
502 InitDeclaratorAST
*init_declarator
= it
->element
;
505 Q_ASSERT(init_declarator
->declarator
!= 0);
508 decl_cc
.run (init_declarator
->declarator
);
509 QString alias_name
= decl_cc
.id ();
511 if (alias_name
.isEmpty ())
513 std::cerr
<< "** WARNING anonymous typedef not supported! ``";
514 Token
const &tk
= _M_token_stream
->token ((int) node
->start_token
);
515 Token
const &end_tk
= _M_token_stream
->token ((int) node
->end_token
);
517 std::cerr
<< std::string (&tk
.text
[tk
.position
], end_tk
.position
- tk
.position
) << "''"
518 << std::endl
<< std::endl
;
523 TypeInfo typeInfo
= CompilerUtils::typeDescription (node
->type_specifier
,
524 init_declarator
->declarator
,
526 DeclaratorAST
*decl
= init_declarator
->declarator
;
527 while (decl
&& decl
->sub_declarator
)
528 decl
= decl
->sub_declarator
;
530 if (decl
!= init_declarator
->declarator
531 && init_declarator
->declarator
->parameter_declaration_clause
!= 0)
533 typeInfo
.setFunctionPointer (true);
534 decl_cc
.run (init_declarator
->declarator
);
535 foreach (DeclaratorCompiler::Parameter p
, decl_cc
.parameters())
536 typeInfo
.addArgument(p
.type
);
539 ScopeModelItem scope
= currentScope();
540 DeclaratorAST
*declarator
= init_declarator
->declarator
;
541 CodeModelFinder
finder(model(), this);
542 ScopeModelItem typedefScope
= finder
.resolveScope(declarator
->id
, scope
);
544 TypeAliasModelItem typeAlias
= model ()->create
<TypeAliasModelItem
> ();
545 updateItemPosition (typeAlias
->toItem (), node
);
546 typeAlias
->setName (alias_name
);
547 typeAlias
->setType (qualifyType (typeInfo
, currentScope ()->qualifiedName ()));
548 typeAlias
->setScope (typedefScope
->qualifiedName());
549 _M_qualified_types
[typeAlias
->qualifiedName().join(".")] = QString();
550 currentScope ()->addTypeAlias (typeAlias
);
555 void Binder::visitNamespace(NamespaceAST
*node
)
557 bool anonymous
= (node
->namespace_name
== 0);
559 ScopeModelItem scope
= currentScope();
561 NamespaceModelItem old
;
564 QString name
= decode_symbol(node
->namespace_name
)->as_string();
566 QStringList qualified_name
= scope
->qualifiedName();
567 qualified_name
+= name
;
568 NamespaceModelItem ns
=
569 model_safe_cast
<NamespaceModelItem
>(_M_model
->findItem(qualified_name
,
570 _M_current_file
->toItem()));
573 ns
= _M_model
->create
<NamespaceModelItem
>();
574 updateItemPosition (ns
->toItem(), node
);
576 ns
->setScope(scope
->qualifiedName());
578 old
= changeCurrentNamespace(ns
);
580 _M_context
.append(name
);
583 DefaultVisitor::visitNamespace(node
);
587 Q_ASSERT(scope
->kind() == _CodeModelItem::Kind_Namespace
588 || scope
->kind() == _CodeModelItem::Kind_File
);
590 _M_context
.removeLast();
592 if (NamespaceModelItem ns
= model_static_cast
<NamespaceModelItem
>(scope
))
594 ns
->addNamespace(_M_current_namespace
);
597 changeCurrentNamespace(old
);
601 void Binder::visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST
*node
)
603 name_cc
.run(node
->name
);
604 if (name_cc
.name().isEmpty())
607 ScopeModelItem scope
= currentScope();
608 _M_qualified_types
[(scope
->qualifiedName() + name_cc
.qualifiedName()).join(".") ] = QString();
611 void Binder::visitClassSpecifier(ClassSpecifierAST
*node
)
613 ClassCompiler
class_cc(this);
616 if (class_cc
.name().endsWith('>') && !class_cc
.name().contains('<'))
618 // TODO parser/lexer bug in case of template<> Class<8>
622 if (class_cc
.name().isEmpty())
624 // anonymous not supported
628 Q_ASSERT(node
->name
!= 0 && node
->name
->unqualified_name
!= 0);
630 ScopeModelItem scope
= currentScope();
632 ClassModelItem old
= changeCurrentClass(_M_model
->create
<ClassModelItem
>());
633 updateItemPosition (_M_current_class
->toItem(), node
);
634 _M_current_class
->setName(class_cc
.name());
637 QStringList baseClasses
= class_cc
.baseClasses();
638 QStringList baseModifiers
= class_cc
.baseModifiers();
639 for (int i
=0; i
<baseClasses
.size(); ++i
)
641 info
.setQualifiedName(baseClasses
.at(i
).split("::"));
642 baseClasses
[i
] = qualifyType(info
, scope
->qualifiedName()).qualifiedName().join("::");
645 _M_current_class
->setBaseClasses(baseClasses
);
646 _M_current_class
->setBaseModifiers(baseModifiers
);
647 _M_current_class
->setClassType(decode_class_type(node
->class_key
));
648 _M_current_class
->setTemplateParameters(_M_current_template_parameters
);
650 if (! _M_current_template_parameters
.isEmpty())
652 QString name
= _M_current_class
->name();
654 for (int i
= 0; i
<_M_current_template_parameters
.size(); ++i
)
659 name
+= _M_current_template_parameters
.at(i
)->name();
663 _M_current_class
->setName(name
);
666 CodeModel::AccessPolicy oldAccessPolicy
= changeCurrentAccess(decode_access_policy(node
->class_key
));
667 CodeModel::FunctionType oldFunctionType
= changeCurrentFunctionType(CodeModel::Normal
);
669 _M_current_class
->setScope(scope
->qualifiedName());
670 _M_qualified_types
[_M_current_class
->qualifiedName().join(".")] = QString();
672 scope
->addClass(_M_current_class
);
674 name_cc
.run(node
->name
->unqualified_name
);
675 _M_context
.append(name_cc
.name());
676 visitNodes(this, node
->member_specs
);
677 _M_context
.removeLast();
679 changeCurrentClass(old
);
680 changeCurrentAccess(oldAccessPolicy
);
681 changeCurrentFunctionType(oldFunctionType
);
684 void Binder::visitLinkageSpecification(LinkageSpecificationAST
*node
)
686 DefaultVisitor::visitLinkageSpecification(node
);
689 void Binder::visitUsing(UsingAST
*node
)
691 DefaultVisitor::visitUsing(node
);
694 void Binder::visitEnumSpecifier(EnumSpecifierAST
*node
)
696 CodeModelFinder
finder(model(), this);
697 ScopeModelItem scope
= currentScope();
698 ScopeModelItem enumScope
= finder
.resolveScope(node
->name
, scope
);
700 name_cc
.run(node
->name
);
701 QString name
= name_cc
.name();
706 QString key
= _M_context
.join("::");
707 int current
= ++_M_anonymous_enums
[key
];
708 name
+= QLatin1String("enum_");
709 name
+= QString::number(current
);
712 _M_current_enum
= model()->create
<EnumModelItem
>();
713 _M_current_enum
->setAccessPolicy(_M_current_access
);
714 updateItemPosition (_M_current_enum
->toItem(), node
);
715 _M_current_enum
->setName(name
);
716 _M_current_enum
->setScope(enumScope
->qualifiedName());
718 _M_qualified_types
[_M_current_enum
->qualifiedName().join(".")] = QString();
720 enumScope
->addEnum(_M_current_enum
);
722 DefaultVisitor::visitEnumSpecifier(node
);
727 static QString
strip_preprocessor_lines(const QString
&name
)
729 QStringList lst
= name
.split("\n");
731 for (int i
=0; i
<lst
.size(); ++i
) {
732 if (!lst
.at(i
).startsWith('#'))
738 void Binder::visitEnumerator(EnumeratorAST
*node
)
740 Q_ASSERT(_M_current_enum
!= 0);
741 EnumeratorModelItem e
= model()->create
<EnumeratorModelItem
>();
742 updateItemPosition (e
->toItem(), node
);
743 e
->setName(decode_symbol(node
->id
)->as_string());
745 if (ExpressionAST
*expr
= node
->expression
)
747 const Token
&start_token
= _M_token_stream
->token((int) expr
->start_token
);
748 const Token
&end_token
= _M_token_stream
->token((int) expr
->end_token
);
750 e
->setValue(strip_preprocessor_lines(QString::fromUtf8(&start_token
.text
[start_token
.position
],
751 (int) (end_token
.position
- start_token
.position
)).trimmed()).remove(' '));
754 _M_current_enum
->addEnumerator(e
);
757 void Binder::visitUsingDirective(UsingDirectiveAST
*node
)
759 DefaultVisitor::visitUsingDirective(node
);
762 void Binder::visitQEnums(QEnumsAST
*node
)
764 const Token
&start
= _M_token_stream
->token((int) node
->start_token
);
765 const Token
&end
= _M_token_stream
->token((int) node
->end_token
);
766 QStringList enum_list
= QString::fromLatin1(start
.text
+ start
.position
,
767 end
.position
- start
.position
).split(' ');
769 ScopeModelItem scope
= currentScope();
770 for (int i
=0; i
<enum_list
.size(); ++i
)
771 scope
->addEnumsDeclaration(enum_list
.at(i
));
774 void Binder::visitQProperty(QPropertyAST
*node
)
776 const Token
&start
= _M_token_stream
->token((int) node
->start_token
);
777 const Token
&end
= _M_token_stream
->token((int) node
->end_token
);
778 QString property
= QString::fromLatin1(start
.text
+ start
.position
,
779 end
.position
- start
.position
);
780 _M_current_class
->addPropertyDeclaration(property
);
783 void Binder::applyStorageSpecifiers(const ListNode
<std::size_t> *it
, MemberModelItem item
)
789 const ListNode
<std::size_t> *end
= it
;
793 switch (decode_token(it
->element
))
799 item
->setFriend(true);
805 item
->setRegister(true);
808 item
->setStatic(true);
811 item
->setExtern(true);
814 item
->setMutable(true);
822 void Binder::applyFunctionSpecifiers(const ListNode
<std::size_t> *it
, FunctionModelItem item
)
828 const ListNode
<std::size_t> *end
= it
;
832 switch (decode_token(it
->element
))
838 item
->setInline(true);
842 item
->setVirtual(true);
846 item
->setExplicit(true);
849 case Token_Q_INVOKABLE
:
850 item
->setInvokable(true);
858 TypeInfo
Binder::qualifyType(const TypeInfo
&type
, const QStringList
&context
) const
860 // ### Potentially improve to use string list in the name table to
861 if (context
.size() == 0)
863 // ### We can assume that this means global namespace for now...
866 else if (_M_qualified_types
.contains(type
.qualifiedName().join(".")))
872 QStringList expanded
= context
;
873 expanded
<< type
.qualifiedName();
874 if (_M_qualified_types
.contains(expanded
.join(".")))
876 TypeInfo modified_type
= type
;
877 modified_type
.setQualifiedName(expanded
);
878 return modified_type
;
882 CodeModelItem scope
= model ()->findItem (context
, _M_current_file
->toItem ());
884 if (ClassModelItem klass
= model_dynamic_cast
<ClassModelItem
> (scope
))
886 foreach (QString base
, klass
->baseClasses ())
888 QStringList ctx
= context
;
892 TypeInfo qualified
= qualifyType (type
, ctx
);
893 if (qualified
!= type
)
898 QStringList copy
= context
;
900 return qualifyType(type
, copy
);
905 void Binder::updateItemPosition(CodeModelItem item
, AST
*node
)
911 _M_location
.positionAt (_M_token_stream
->position(node
->start_token
), &line
, &column
, &filename
);
912 item
->setFileName (filename
);
915 // kate: space-indent on; indent-width 2; replace-tabs on;