Add rpp files
[rpp.git] / src / binder.cpp
blobfd2d0e0565e95c0c99148a27c44d7d251f02e094
1 /****************************************************************************
2 **
3 ** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.
4 **
5 ** This file is part of Qt Jambi.
6 **
7 ** ** This file may be used under the terms of the GNU General Public
8 ** License version 2.0 as published by the Free Software Foundation
9 ** and appearing in the file LICENSE.GPL included in the packaging of
10 ** this file. Please review the following information to ensure GNU
11 ** General Public Licensing requirements will be met:
12 ** http://www.trolltech.com/products/qt/opensource.html
14 ** If you are unsure which license is appropriate for your use, please
15 ** review the following information:
16 ** http://www.trolltech.com/products/qt/licensing.html or contact the
17 ** 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 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
27 /* This file is part of KDevelop
28 Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
29 Copyright (C) 2005 Trolltech AS
31 This library is free software; you can redistribute it and/or
32 modify it under the terms of the GNU Library General Public
33 License version 2 as published by the Free Software Foundation.
35 This library is distributed in the hope that it will be useful,
36 but WITHOUT ANY WARRANTY; without even the implied warranty of
37 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
38 Library General Public License for more details.
40 You should have received a copy of the GNU Library General Public License
41 along with this library; see the file COPYING.LIB. If not, write to
42 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
43 Boston, MA 02110-1301, USA.
46 #include "binder.h"
47 #include "lexer.h"
48 #include "control.h"
49 #include "symbol.h"
50 #include "codemodel_finder.h"
51 #include "class_compiler.h"
52 #include "compiler_utils.h"
53 #include "tokens.h"
54 #include "dumptree.h"
56 #include <iostream>
58 #include <qdebug.h>
60 Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control)
61 : _M_model(__model),
62 _M_location(__location),
63 _M_token_stream(&_M_location.token_stream),
64 _M_control(__control),
65 _M_current_function_type(CodeModel::Normal),
66 type_cc(this),
67 name_cc(this),
68 decl_cc(this)
70 _M_qualified_types["char"] = QString();
71 _M_qualified_types["double"] = QString();
72 _M_qualified_types["float"] = QString();
73 _M_qualified_types["int"] = QString();
74 _M_qualified_types["long"] = QString();
75 _M_qualified_types["short"] = QString();
76 _M_qualified_types["void"] = QString();
79 Binder::~Binder()
83 FileModelItem Binder::run(AST *node)
85 FileModelItem old = _M_current_file;
86 _M_current_access = CodeModel::Public;
88 _M_current_file = model()->create<FileModelItem>();
89 updateItemPosition (_M_current_file->toItem(), node);
90 visit(node);
91 FileModelItem result = _M_current_file;
93 _M_current_file = old; // restore
95 return result;
98 ScopeModelItem Binder::currentScope()
100 if (_M_current_class)
101 return model_static_cast<ScopeModelItem>(_M_current_class);
102 else if (_M_current_namespace)
103 return model_static_cast<ScopeModelItem>(_M_current_namespace);
105 return model_static_cast<ScopeModelItem>(_M_current_file);
108 TemplateParameterList Binder::changeTemplateParameters(TemplateParameterList templateParameters)
110 TemplateParameterList old = _M_current_template_parameters;
111 _M_current_template_parameters = templateParameters;
112 return old;
115 CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType)
117 CodeModel::FunctionType old = _M_current_function_type;
118 _M_current_function_type = functionType;
119 return old;
122 CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy)
124 CodeModel::AccessPolicy old = _M_current_access;
125 _M_current_access = accessPolicy;
126 return old;
129 NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item)
131 NamespaceModelItem old = _M_current_namespace;
132 _M_current_namespace = item;
133 return old;
136 ClassModelItem Binder::changeCurrentClass(ClassModelItem item)
138 ClassModelItem old = _M_current_class;
139 _M_current_class = item;
140 return old;
143 FunctionDefinitionModelItem Binder::changeCurrentFunction(FunctionDefinitionModelItem item)
145 FunctionDefinitionModelItem old = _M_current_function;
146 _M_current_function = item;
147 return old;
150 int Binder::decode_token(std::size_t index) const
152 return _M_token_stream->kind(index);
155 CodeModel::AccessPolicy Binder::decode_access_policy(std::size_t index) const
157 switch (decode_token(index))
159 case Token_class:
160 return CodeModel::Private;
162 case Token_struct:
163 case Token_union:
164 return CodeModel::Public;
166 default:
167 return CodeModel::Public;
171 CodeModel::ClassType Binder::decode_class_type(std::size_t index) const
173 switch (decode_token(index))
175 case Token_class:
176 return CodeModel::Class;
177 case Token_struct:
178 return CodeModel::Struct;
179 case Token_union:
180 return CodeModel::Union;
181 default:
182 std::cerr << "** WARNING unrecognized class type" << std::endl;
184 return CodeModel::Class;
187 const NameSymbol *Binder::decode_symbol(std::size_t index) const
189 return _M_token_stream->symbol(index);
192 void Binder::visitAccessSpecifier(AccessSpecifierAST *node)
194 const ListNode<std::size_t> *it = node->specs;
195 if (it == 0)
196 return;
198 it = it->toFront();
199 const ListNode<std::size_t> *end = it;
203 switch (decode_token(it->element))
205 default:
206 break;
208 case Token_public:
209 changeCurrentAccess(CodeModel::Public);
210 changeCurrentFunctionType(CodeModel::Normal);
211 break;
212 case Token_protected:
213 changeCurrentAccess(CodeModel::Protected);
214 changeCurrentFunctionType(CodeModel::Normal);
215 break;
216 case Token_private:
217 changeCurrentAccess(CodeModel::Private);
218 changeCurrentFunctionType(CodeModel::Normal);
219 break;
220 case Token_signals:
221 changeCurrentAccess(CodeModel::Protected);
222 changeCurrentFunctionType(CodeModel::Signal);
223 break;
224 case Token_slots:
225 changeCurrentFunctionType(CodeModel::Slot);
226 break;
228 it = it->next;
230 while (it != end);
233 void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node)
235 visit(node->type_specifier);
237 if (const ListNode<InitDeclaratorAST*> *it = node->init_declarators)
239 it = it->toFront();
240 const ListNode<InitDeclaratorAST*> *end = it;
243 InitDeclaratorAST *init_declarator = it->element;
244 declare_symbol(node, init_declarator);
245 it = it->next;
247 while (it != end);
251 void Binder::declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator)
253 DeclaratorAST *declarator = init_declarator->declarator;
255 while (declarator && declarator->sub_declarator)
256 declarator = declarator->sub_declarator;
258 NameAST *id = declarator->id;
259 if (! declarator->id)
261 std::cerr << "** WARNING expected a declarator id" << std::endl;
262 return;
265 CodeModelFinder finder(model(), this);
266 ScopeModelItem symbolScope = finder.resolveScope(id, currentScope());
267 if (! symbolScope)
269 name_cc.run(id);
270 std::cerr << "** WARNING scope not found for symbol:"
271 << qPrintable(name_cc.name()) << std::endl;
272 return;
275 decl_cc.run(declarator);
277 if (decl_cc.isFunction())
279 name_cc.run(id->unqualified_name);
281 FunctionModelItem fun = model()->create<FunctionModelItem>();
282 updateItemPosition (fun->toItem(), node);
283 fun->setAccessPolicy(_M_current_access);
284 fun->setFunctionType(_M_current_function_type);
285 fun->setName(name_cc.name());
286 fun->setAbstract(init_declarator->initializer != 0);
287 fun->setConstant(declarator->fun_cv != 0);
288 fun->setTemplateParameters(_M_current_template_parameters);
289 applyStorageSpecifiers(node->storage_specifiers, model_static_cast<MemberModelItem>(fun));
290 applyFunctionSpecifiers(node->function_specifiers, fun);
292 // build the type
293 TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
294 declarator,
295 this);
297 fun->setType(qualifyType(typeInfo, symbolScope->qualifiedName()));
300 fun->setVariadics (decl_cc.isVariadics ());
302 // ... and the signature
303 foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
305 ArgumentModelItem arg = model()->create<ArgumentModelItem>();
306 arg->setType(qualifyType(p.type, _M_context));
307 arg->setName(p.name);
308 arg->setDefaultValue(p.defaultValue);
309 if (p.defaultValue)
310 arg->setDefaultValueExpression(p.defaultValueExpression);
311 fun->addArgument(arg);
314 fun->setScope(symbolScope->qualifiedName());
315 symbolScope->addFunction(fun);
317 else
319 VariableModelItem var = model()->create<VariableModelItem>();
320 updateItemPosition (var->toItem(), node);
321 var->setTemplateParameters(_M_current_template_parameters);
322 var->setAccessPolicy(_M_current_access);
323 name_cc.run(id->unqualified_name);
324 var->setName(name_cc.name());
325 TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
326 declarator,
327 this);
328 if (declarator != init_declarator->declarator
329 && init_declarator->declarator->parameter_declaration_clause != 0)
331 typeInfo.setFunctionPointer (true);
332 decl_cc.run (init_declarator->declarator);
333 foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
334 typeInfo.addArgument(p.type);
337 var->setType(qualifyType(typeInfo, _M_context));
338 applyStorageSpecifiers(node->storage_specifiers, model_static_cast<MemberModelItem>(var));
340 var->setScope(symbolScope->qualifiedName());
341 symbolScope->addVariable(var);
345 void Binder::visitFunctionDefinition(FunctionDefinitionAST *node)
347 Q_ASSERT(node->init_declarator != 0);
349 ScopeModelItem scope = currentScope();
351 InitDeclaratorAST *init_declarator = node->init_declarator;
352 DeclaratorAST *declarator = init_declarator->declarator;
354 CodeModelFinder finder(model(), this);
356 ScopeModelItem functionScope = finder.resolveScope(declarator->id, scope);
357 if (! functionScope)
359 name_cc.run(declarator->id);
360 std::cerr << "** WARNING scope not found for function definition:"
361 << qPrintable(name_cc.name()) << std::endl
362 << "\tdefinition *ignored*"
363 << std::endl;
364 return;
367 decl_cc.run(declarator);
369 Q_ASSERT(! decl_cc.id().isEmpty());
371 FunctionDefinitionModelItem
372 old = changeCurrentFunction(_M_model->create<FunctionDefinitionModelItem>());
373 _M_current_function->setScope(functionScope->qualifiedName());
374 updateItemPosition (_M_current_function->toItem(), node);
376 Q_ASSERT(declarator->id->unqualified_name != 0);
377 name_cc.run(declarator->id->unqualified_name);
378 QString unqualified_name = name_cc.name();
380 _M_current_function->setName(unqualified_name);
381 TypeInfo tmp_type = CompilerUtils::typeDescription(node->type_specifier,
382 declarator, this);
384 _M_current_function->setType(qualifyType(tmp_type, _M_context));
385 _M_current_function->setAccessPolicy(_M_current_access);
386 _M_current_function->setFunctionType(_M_current_function_type);
387 _M_current_function->setConstant(declarator->fun_cv != 0);
388 _M_current_function->setTemplateParameters(_M_current_template_parameters);
390 applyStorageSpecifiers(node->storage_specifiers,
391 model_static_cast<MemberModelItem>(_M_current_function));
392 applyFunctionSpecifiers(node->function_specifiers,
393 model_static_cast<FunctionModelItem>(_M_current_function));
395 _M_current_function->setVariadics (decl_cc.isVariadics ());
397 foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
399 ArgumentModelItem arg = model()->create<ArgumentModelItem>();
400 arg->setType(qualifyType(p.type, functionScope->qualifiedName()));
401 arg->setName(p.name);
402 arg->setDefaultValue(p.defaultValue);
403 if (p.defaultValue)
404 arg->setDefaultValueExpression(p.defaultValueExpression);
405 _M_current_function->addArgument(arg);
408 functionScope->addFunctionDefinition(_M_current_function);
410 FunctionModelItem prototype = model_static_cast<FunctionModelItem>(_M_current_function);
411 FunctionModelItem declared = functionScope->declaredFunction(prototype);
413 // try to find a function declaration for this definition..
414 if (! declared)
416 functionScope->addFunction(prototype);
418 else
420 applyFunctionSpecifiers(node->function_specifiers, declared);
422 // fix the function type and the access policy
423 _M_current_function->setAccessPolicy(declared->accessPolicy());
424 _M_current_function->setFunctionType(declared->functionType());
427 changeCurrentFunction(old);
430 void Binder::visitTemplateDeclaration(TemplateDeclarationAST *node)
432 const ListNode<TemplateParameterAST*> *it = node->template_parameters;
433 if (it == 0)
434 return;
436 TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList());
438 it = it->toFront();
439 const ListNode<TemplateParameterAST*> *end = it;
441 TemplateParameterList templateParameters;
444 TemplateParameterAST *parameter = it->element;
445 TypeParameterAST *type_parameter = parameter->type_parameter;
446 if (! type_parameter)
448 // std::cerr << "** WARNING template declaration not supported ``";
449 // Token const &tk = _M_token_stream->token ((int) node->start_token);
450 // Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
452 // std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
453 // << std::endl << std::endl;
455 changeTemplateParameters(savedTemplateParameters);
456 return;
458 assert(type_parameter != 0);
460 TemplateParameterModelItem p = model()->create<TemplateParameterModelItem>();
461 int tk = decode_token(type_parameter->type);
462 if (tk != Token_typename && tk != Token_class)
464 // std::cerr << "** WARNING template declaration not supported ``";
465 // Token const &tk = _M_token_stream->token ((int) node->start_token);
466 // Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
468 // std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
469 // << std::endl << std::endl;
471 changeTemplateParameters(savedTemplateParameters);
472 return;
474 assert(tk == Token_typename || tk == Token_class);
476 name_cc.run(type_parameter->name);
477 p->setName(name_cc.name());
479 _M_current_template_parameters.append(p);
480 it = it->next;
482 while (it != end);
484 visit(node->declaration);
486 changeTemplateParameters(savedTemplateParameters);
489 void Binder::visitTypedef(TypedefAST *node)
491 const ListNode<InitDeclaratorAST*> *it = node->init_declarators;
492 if (it == 0)
493 return;
495 it = it->toFront();
496 const ListNode<InitDeclaratorAST*> *end = it;
500 InitDeclaratorAST *init_declarator = it->element;
501 it = it->next;
503 Q_ASSERT(init_declarator->declarator != 0);
505 // the name
506 decl_cc.run (init_declarator->declarator);
507 QString alias_name = decl_cc.id ();
509 if (alias_name.isEmpty ())
511 std::cerr << "** WARNING anonymous typedef not supported! ``";
512 Token const &tk = _M_token_stream->token ((int) node->start_token);
513 Token const &end_tk = _M_token_stream->token ((int) node->end_token);
515 std::cerr << std::string (&tk.text[tk.position], end_tk.position - tk.position) << "''"
516 << std::endl << std::endl;
517 continue;
520 // build the type
521 TypeInfo typeInfo = CompilerUtils::typeDescription (node->type_specifier,
522 init_declarator->declarator,
523 this);
524 DeclaratorAST *decl = init_declarator->declarator;
525 while (decl && decl->sub_declarator)
526 decl = decl->sub_declarator;
528 if (decl != init_declarator->declarator
529 && init_declarator->declarator->parameter_declaration_clause != 0)
531 typeInfo.setFunctionPointer (true);
532 decl_cc.run (init_declarator->declarator);
533 foreach (DeclaratorCompiler::Parameter p, decl_cc.parameters())
534 typeInfo.addArgument(p.type);
537 ScopeModelItem scope = currentScope();
538 DeclaratorAST *declarator = init_declarator->declarator;
539 CodeModelFinder finder(model(), this);
540 ScopeModelItem typedefScope = finder.resolveScope(declarator->id, scope);
542 TypeAliasModelItem typeAlias = model ()->create<TypeAliasModelItem> ();
543 updateItemPosition (typeAlias->toItem (), node);
544 typeAlias->setName (alias_name);
545 typeAlias->setType (qualifyType (typeInfo, currentScope ()->qualifiedName ()));
546 typeAlias->setScope (typedefScope->qualifiedName());
547 _M_qualified_types[typeAlias->qualifiedName().join(".")] = QString();
548 currentScope ()->addTypeAlias (typeAlias);
550 while (it != end);
553 void Binder::visitNamespace(NamespaceAST *node)
555 bool anonymous = (node->namespace_name == 0);
557 ScopeModelItem scope = currentScope();
559 NamespaceModelItem old;
560 if (! anonymous)
562 QString name = decode_symbol(node->namespace_name)->as_string();
564 QStringList qualified_name = scope->qualifiedName();
565 qualified_name += name;
566 NamespaceModelItem ns =
567 model_safe_cast<NamespaceModelItem>(_M_model->findItem(qualified_name,
568 _M_current_file->toItem()));
569 if (!ns)
571 ns = _M_model->create<NamespaceModelItem>();
572 updateItemPosition (ns->toItem(), node);
573 ns->setName(name);
574 ns->setScope(scope->qualifiedName());
576 old = changeCurrentNamespace(ns);
578 _M_context.append(name);
581 DefaultVisitor::visitNamespace(node);
583 if (! anonymous)
585 Q_ASSERT(scope->kind() == _CodeModelItem::Kind_Namespace
586 || scope->kind() == _CodeModelItem::Kind_File);
588 _M_context.removeLast();
590 if (NamespaceModelItem ns = model_static_cast<NamespaceModelItem>(scope))
592 ns->addNamespace(_M_current_namespace);
595 changeCurrentNamespace(old);
599 void Binder::visitClassSpecifier(ClassSpecifierAST *node)
601 ClassCompiler class_cc(this);
602 class_cc.run(node);
604 if (class_cc.name().isEmpty())
606 // anonymous not supported
607 return;
610 Q_ASSERT(node->name != 0 && node->name->unqualified_name != 0);
612 ScopeModelItem scope = currentScope();
614 ClassModelItem old = changeCurrentClass(_M_model->create<ClassModelItem>());
615 updateItemPosition (_M_current_class->toItem(), node);
616 _M_current_class->setName(class_cc.name());
617 _M_current_class->setBaseClasses(class_cc.baseClasses());
618 _M_current_class->setClassType(decode_class_type(node->class_key));
619 _M_current_class->setTemplateParameters(_M_current_template_parameters);
621 if (! _M_current_template_parameters.isEmpty())
623 QString name = _M_current_class->name();
624 name += "<";
625 for (int i = 0; i<_M_current_template_parameters.size(); ++i)
627 if (i != 0)
628 name += ",";
630 name += _M_current_template_parameters.at(i)->name();
633 name += ">";
634 _M_current_class->setName(name);
637 CodeModel::AccessPolicy oldAccessPolicy = changeCurrentAccess(decode_access_policy(node->class_key));
638 CodeModel::FunctionType oldFunctionType = changeCurrentFunctionType(CodeModel::Normal);
640 _M_current_class->setScope(scope->qualifiedName());
641 _M_qualified_types[_M_current_class->qualifiedName().join(".")] = QString();
642 scope->addClass(_M_current_class);
644 name_cc.run(node->name->unqualified_name);
645 _M_context.append(name_cc.name());
646 visitNodes(this, node->member_specs);
647 _M_context.removeLast();
649 changeCurrentClass(old);
650 changeCurrentAccess(oldAccessPolicy);
651 changeCurrentFunctionType(oldFunctionType);
654 void Binder::visitLinkageSpecification(LinkageSpecificationAST *node)
656 DefaultVisitor::visitLinkageSpecification(node);
659 void Binder::visitUsing(UsingAST *node)
661 DefaultVisitor::visitUsing(node);
664 void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
666 CodeModelFinder finder(model(), this);
667 ScopeModelItem scope = currentScope();
668 ScopeModelItem enumScope = finder.resolveScope(node->name, scope);
670 name_cc.run(node->name);
671 QString name = name_cc.name();
673 if (name.isEmpty())
675 // anonymous enum
676 QString key = _M_context.join("::");
677 int current = ++_M_anonymous_enums[key];
678 name += QLatin1String("enum_");
679 name += QString::number(current);
682 _M_current_enum = model()->create<EnumModelItem>();
683 _M_current_enum->setAccessPolicy(_M_current_access);
684 updateItemPosition (_M_current_enum->toItem(), node);
685 _M_current_enum->setName(name);
686 _M_current_enum->setScope(enumScope->qualifiedName());
688 _M_qualified_types[_M_current_enum->qualifiedName().join(".")] = QString();
690 enumScope->addEnum(_M_current_enum);
692 DefaultVisitor::visitEnumSpecifier(node);
694 _M_current_enum = 0;
697 void Binder::visitEnumerator(EnumeratorAST *node)
699 Q_ASSERT(_M_current_enum != 0);
700 EnumeratorModelItem e = model()->create<EnumeratorModelItem>();
701 updateItemPosition (e->toItem(), node);
702 e->setName(decode_symbol(node->id)->as_string());
704 if (ExpressionAST *expr = node->expression)
706 const Token &start_token = _M_token_stream->token((int) expr->start_token);
707 const Token &end_token = _M_token_stream->token((int) expr->end_token);
709 e->setValue(QString::fromUtf8(&start_token.text[start_token.position],
710 (int) (end_token.position - start_token.position)).trimmed());
713 _M_current_enum->addEnumerator(e);
716 void Binder::visitUsingDirective(UsingDirectiveAST *node)
718 DefaultVisitor::visitUsingDirective(node);
721 void Binder::visitQProperty(QPropertyAST *node)
723 const Token &start = _M_token_stream->token((int) node->start_token);
724 const Token &end = _M_token_stream->token((int) node->end_token);
725 QString property = QString::fromLatin1(start.text + start.position,
726 end.position - start.position);
727 _M_current_class->addPropertyDeclaration(property);
730 void Binder::applyStorageSpecifiers(const ListNode<std::size_t> *it, MemberModelItem item)
732 if (it == 0)
733 return;
735 it = it->toFront();
736 const ListNode<std::size_t> *end = it;
740 switch (decode_token(it->element))
742 default:
743 break;
745 case Token_friend:
746 item->setFriend(true);
747 break;
748 case Token_auto:
749 item->setAuto(true);
750 break;
751 case Token_register:
752 item->setRegister(true);
753 break;
754 case Token_static:
755 item->setStatic(true);
756 break;
757 case Token_extern:
758 item->setExtern(true);
759 break;
760 case Token_mutable:
761 item->setMutable(true);
762 break;
764 it = it->next;
766 while (it != end);
769 void Binder::applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item)
771 if (it == 0)
772 return;
774 it = it->toFront();
775 const ListNode<std::size_t> *end = it;
779 switch (decode_token(it->element))
781 default:
782 break;
784 case Token_inline:
785 item->setInline(true);
786 break;
788 case Token_virtual:
789 item->setVirtual(true);
790 break;
792 case Token_explicit:
793 item->setExplicit(true);
794 break;
796 it = it->next;
798 while (it != end);
801 TypeInfo Binder::qualifyType(const TypeInfo &type, const QStringList &context) const
803 // ### Potentially improve to use string list in the name table to
804 if (context.size() == 0)
806 // ### We can assume that this means global namespace for now...
807 return type;
809 else if (_M_qualified_types.contains(type.qualifiedName().join(".")))
811 return type;
813 else
815 QStringList expanded = context;
816 expanded << type.qualifiedName();
817 if (_M_qualified_types.contains(expanded.join(".")))
819 TypeInfo modified_type = type;
820 modified_type.setQualifiedName(expanded);
821 return modified_type;
823 else
825 CodeModelItem scope = model ()->findItem (context, _M_current_file->toItem ());
827 if (ClassModelItem klass = model_dynamic_cast<ClassModelItem> (scope))
829 foreach (QString base, klass->baseClasses ())
831 QStringList ctx = context;
832 ctx.removeLast();
833 ctx.append (base);
835 TypeInfo qualified = qualifyType (type, ctx);
836 if (qualified != type)
837 return qualified;
841 QStringList copy = context;
842 copy.removeLast();
843 return qualifyType(type, copy);
848 void Binder::updateItemPosition(CodeModelItem item, AST *node)
850 QString filename;
851 int line, column;
853 assert (node != 0);
854 _M_location.positionAt (_M_token_stream->position(node->start_token), &line, &column, &filename);
855 item->setFileName (filename);
858 // kate: space-indent on; indent-width 2; replace-tabs on;