save the modifier list in ClassModelItem
[lqt.git] / cpptoxml / parser / binder.cpp
blob6434cda100b97de0af61a02e4203b3ac304214c5
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 ****************************************************************************/
25 #include "binder.h"
26 #include "lexer.h"
27 #include "control.h"
28 #include "symbol.h"
29 #include "codemodel_finder.h"
30 #include "class_compiler.h"
31 #include "compiler_utils.h"
32 #include "tokens.h"
33 #include "dumptree.h"
35 #include <iostream>
37 #include <qdebug.h>
39 Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control)
40 : _M_model(__model),
41 _M_location(__location),
42 _M_token_stream(&_M_location.token_stream),
43 _M_control(__control),
44 _M_current_function_type(CodeModel::Normal),
45 type_cc(this),
46 name_cc(this),
47 decl_cc(this)
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();
58 Binder::~Binder()
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);
69 visit(node);
70 FileModelItem result = _M_current_file;
72 _M_current_file = old; // restore
74 return result;
77 ScopeModelItem Binder::currentScope()
79 if (_M_current_class)
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;
91 return old;
94 CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType)
96 CodeModel::FunctionType old = _M_current_function_type;
97 _M_current_function_type = functionType;
98 return old;
101 CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy)
103 CodeModel::AccessPolicy old = _M_current_access;
104 _M_current_access = accessPolicy;
105 return old;
108 NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item)
110 NamespaceModelItem old = _M_current_namespace;
111 _M_current_namespace = item;
112 return old;
115 ClassModelItem Binder::changeCurrentClass(ClassModelItem item)
117 ClassModelItem old = _M_current_class;
118 _M_current_class = item;
119 return old;
122 FunctionDefinitionModelItem Binder::changeCurrentFunction(FunctionDefinitionModelItem item)
124 FunctionDefinitionModelItem old = _M_current_function;
125 _M_current_function = item;
126 return old;
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))
138 case Token_class:
139 return CodeModel::Private;
141 case Token_struct:
142 case Token_union:
143 return CodeModel::Public;
145 default:
146 return CodeModel::Public;
150 CodeModel::ClassType Binder::decode_class_type(std::size_t index) const
152 switch (decode_token(index))
154 case Token_class:
155 return CodeModel::Class;
156 case Token_struct:
157 return CodeModel::Struct;
158 case Token_union:
159 return CodeModel::Union;
160 default:
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;
174 if (it == 0)
175 return;
177 it = it->toFront();
178 const ListNode<std::size_t> *end = it;
182 switch (decode_token(it->element))
184 default:
185 break;
187 case Token_public:
188 changeCurrentAccess(CodeModel::Public);
189 changeCurrentFunctionType(CodeModel::Normal);
190 break;
191 case Token_protected:
192 changeCurrentAccess(CodeModel::Protected);
193 changeCurrentFunctionType(CodeModel::Normal);
194 break;
195 case Token_private:
196 changeCurrentAccess(CodeModel::Private);
197 changeCurrentFunctionType(CodeModel::Normal);
198 break;
199 case Token_signals:
200 changeCurrentAccess(CodeModel::Protected);
201 changeCurrentFunctionType(CodeModel::Signal);
202 break;
203 case Token_slots:
204 changeCurrentFunctionType(CodeModel::Slot);
205 break;
207 it = it->next;
209 while (it != end);
212 void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node)
214 visit(node->type_specifier);
216 if (const ListNode<InitDeclaratorAST*> *it = node->init_declarators)
218 it = it->toFront();
219 const ListNode<InitDeclaratorAST*> *end = it;
222 InitDeclaratorAST *init_declarator = it->element;
223 declare_symbol(node, init_declarator);
224 it = it->next;
226 while (it != end);
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;
241 return;
244 CodeModelFinder finder(model(), this);
245 ScopeModelItem symbolScope = finder.resolveScope(id, currentScope());
246 if (! symbolScope)
248 name_cc.run(id);
249 std::cerr << "** WARNING scope not found for symbol:"
250 << qPrintable(name_cc.name()) << std::endl;
251 return;
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);
271 // build the type
272 TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
273 declarator,
274 this);
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);
288 if (p.defaultValue)
289 arg->setDefaultValueExpression(p.defaultValueExpression);
290 fun->addArgument(arg);
293 fun->setScope(symbolScope->qualifiedName());
294 symbolScope->addFunction(fun);
296 else
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,
305 declarator,
306 this);
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);
343 if (! functionScope)
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*"
349 << std::endl;
350 return;
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,
368 declarator, this);
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);
389 if (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..
400 if (! declared)
402 functionScope->addFunction(prototype);
404 else
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;
419 if (it == 0) {
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);
423 return;
426 TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList());
428 it = it->toFront();
429 const ListNode<TemplateParameterAST*> *end = it;
431 TemplateParameterList templateParameters;
432 do {
433 TemplateParameterAST *parameter = it->element;
434 TypeParameterAST *type_parameter = parameter->type_parameter;
436 NameAST *name;
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);
454 return;
458 name = parameter->parameter_declaration->declarator->id;
459 } else {
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);
471 return;
473 assert(tk == Token_typename || tk == Token_class);
475 name = type_parameter->name;
478 TemplateParameterModelItem p = model()->create<TemplateParameterModelItem>();
479 name_cc.run(name);
480 p->setName(name_cc.name());
482 _M_current_template_parameters.append(p);
483 it = it->next;
484 } while (it != end);
486 visit(node->declaration);
488 changeTemplateParameters(savedTemplateParameters);
491 void Binder::visitTypedef(TypedefAST *node)
493 const ListNode<InitDeclaratorAST*> *it = node->init_declarators;
494 if (it == 0)
495 return;
497 it = it->toFront();
498 const ListNode<InitDeclaratorAST*> *end = it;
502 InitDeclaratorAST *init_declarator = it->element;
503 it = it->next;
505 Q_ASSERT(init_declarator->declarator != 0);
507 // the name
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;
519 continue;
522 // build the type
523 TypeInfo typeInfo = CompilerUtils::typeDescription (node->type_specifier,
524 init_declarator->declarator,
525 this);
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);
552 while (it != end);
555 void Binder::visitNamespace(NamespaceAST *node)
557 bool anonymous = (node->namespace_name == 0);
559 ScopeModelItem scope = currentScope();
561 NamespaceModelItem old;
562 if (! anonymous)
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()));
571 if (!ns)
573 ns = _M_model->create<NamespaceModelItem>();
574 updateItemPosition (ns->toItem(), node);
575 ns->setName(name);
576 ns->setScope(scope->qualifiedName());
578 old = changeCurrentNamespace(ns);
580 _M_context.append(name);
583 DefaultVisitor::visitNamespace(node);
585 if (! anonymous)
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())
605 return;
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);
614 class_cc.run(node);
616 if (class_cc.name().endsWith('>') && !class_cc.name().contains('<'))
618 // TODO parser/lexer bug in case of template<> Class<8>
619 return;
622 if (class_cc.name().isEmpty())
624 // anonymous not supported
625 return;
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());
636 TypeInfo info;
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();
653 name += "<";
654 for (int i = 0; i<_M_current_template_parameters.size(); ++i)
656 if (i != 0)
657 name += ",";
659 name += _M_current_template_parameters.at(i)->name();
662 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();
703 if (name.isEmpty())
705 // anonymous enum
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);
724 _M_current_enum = 0;
727 static QString strip_preprocessor_lines(const QString &name)
729 QStringList lst = name.split("\n");
730 QString s;
731 for (int i=0; i<lst.size(); ++i) {
732 if (!lst.at(i).startsWith('#'))
733 s += lst.at(i);
735 return s.trimmed();
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)
785 if (it == 0)
786 return;
788 it = it->toFront();
789 const ListNode<std::size_t> *end = it;
793 switch (decode_token(it->element))
795 default:
796 break;
798 case Token_friend:
799 item->setFriend(true);
800 break;
801 case Token_auto:
802 item->setAuto(true);
803 break;
804 case Token_register:
805 item->setRegister(true);
806 break;
807 case Token_static:
808 item->setStatic(true);
809 break;
810 case Token_extern:
811 item->setExtern(true);
812 break;
813 case Token_mutable:
814 item->setMutable(true);
815 break;
817 it = it->next;
819 while (it != end);
822 void Binder::applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item)
824 if (it == 0)
825 return;
827 it = it->toFront();
828 const ListNode<std::size_t> *end = it;
832 switch (decode_token(it->element))
834 default:
835 break;
837 case Token_inline:
838 item->setInline(true);
839 break;
841 case Token_virtual:
842 item->setVirtual(true);
843 break;
845 case Token_explicit:
846 item->setExplicit(true);
847 break;
849 case Token_Q_INVOKABLE:
850 item->setInvokable(true);
851 break;
853 it = it->next;
855 while (it != end);
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...
864 return type;
866 else if (_M_qualified_types.contains(type.qualifiedName().join(".")))
868 return type;
870 else
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;
880 else
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;
889 ctx.removeLast();
890 ctx.append (base);
892 TypeInfo qualified = qualifyType (type, ctx);
893 if (qualified != type)
894 return qualified;
898 QStringList copy = context;
899 copy.removeLast();
900 return qualifyType(type, copy);
905 void Binder::updateItemPosition(CodeModelItem item, AST *node)
907 QString filename;
908 int line, column;
910 assert (node != 0);
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;