aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken2/ApiExtractor/parser/binder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken2/ApiExtractor/parser/binder.cpp')
-rw-r--r--sources/shiboken2/ApiExtractor/parser/binder.cpp866
1 files changed, 0 insertions, 866 deletions
diff --git a/sources/shiboken2/ApiExtractor/parser/binder.cpp b/sources/shiboken2/ApiExtractor/parser/binder.cpp
deleted file mode 100644
index 709f86c56..000000000
--- a/sources/shiboken2/ApiExtractor/parser/binder.cpp
+++ /dev/null
@@ -1,866 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of PySide2.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "binder.h"
-#include "lexer.h"
-#include "control.h"
-#include "symbol.h"
-#include "codemodel_finder.h"
-#include "class_compiler.h"
-#include "compiler_utils.h"
-#include "tokens.h"
-#include "dumptree.h"
-
-#include <iostream>
-#include <QDebug>
-
-Binder::Binder(CodeModel *__model, LocationManager &__location, Control *__control)
- : _M_model(__model),
- _M_location(__location),
- _M_token_stream(&_M_location.token_stream),
- _M_control(__control),
- _M_current_function_type(CodeModel::Normal),
- type_cc(this),
- name_cc(this),
- decl_cc(this)
-{
- _M_qualified_types.insert(QLatin1String("char"), QString());
- _M_qualified_types.insert(QLatin1String("double"), QString());
- _M_qualified_types.insert(QLatin1String("float"), QString());
- _M_qualified_types.insert(QLatin1String("int"), QString());
- _M_qualified_types.insert(QLatin1String("long"), QString());
- _M_qualified_types.insert(QLatin1String("short"), QString());
- _M_qualified_types.insert(QLatin1String("void"), QString());
-}
-
-Binder::~Binder()
-{
-}
-
-FileModelItem Binder::run(AST *node)
-{
- FileModelItem old = _M_current_file;
- _M_current_access = CodeModel::Public;
-
- _M_current_file.reset(new _FileModelItem(model()));
- updateItemPosition(_M_current_file, node);
- visit(node);
- FileModelItem result = _M_current_file;
-
- _M_current_file = old; // restore
-
- return result;
-}
-
-ScopeModelItem Binder::currentScope()
-{
- if (_M_current_class)
- return _M_current_class;
- else if (_M_current_namespace)
- return _M_current_namespace;
-
- return _M_current_file;
-}
-
-TemplateParameterList Binder::changeTemplateParameters(TemplateParameterList templateParameters)
-{
- TemplateParameterList old = _M_current_template_parameters;
- _M_current_template_parameters = templateParameters;
- return old;
-}
-
-CodeModel::FunctionType Binder::changeCurrentFunctionType(CodeModel::FunctionType functionType)
-{
- CodeModel::FunctionType old = _M_current_function_type;
- _M_current_function_type = functionType;
- return old;
-}
-
-CodeModel::AccessPolicy Binder::changeCurrentAccess(CodeModel::AccessPolicy accessPolicy)
-{
- CodeModel::AccessPolicy old = _M_current_access;
- _M_current_access = accessPolicy;
- return old;
-}
-
-NamespaceModelItem Binder::changeCurrentNamespace(NamespaceModelItem item)
-{
- NamespaceModelItem old = _M_current_namespace;
- _M_current_namespace = item;
- return old;
-}
-
-ClassModelItem Binder::changeCurrentClass(ClassModelItem item)
-{
- ClassModelItem old = _M_current_class;
- _M_current_class = item;
- return old;
-}
-
-FunctionModelItem Binder::changeCurrentFunction(FunctionModelItem item)
-{
- FunctionModelItem old = _M_current_function;
- _M_current_function = item;
- return old;
-}
-
-int Binder::decode_token(std::size_t index) const
-{
- return _M_token_stream->kind(index);
-}
-
-CodeModel::AccessPolicy Binder::decode_access_policy(std::size_t index) const
-{
- switch (decode_token(index)) {
- case Token_class:
- return CodeModel::Private;
-
- case Token_struct:
- case Token_union:
- return CodeModel::Public;
-
- default:
- return CodeModel::Public;
- }
-}
-
-CodeModel::ClassType Binder::decode_class_type(std::size_t index) const
-{
- switch (decode_token(index)) {
- case Token_class:
- return CodeModel::Class;
- case Token_struct:
- return CodeModel::Struct;
- case Token_union:
- return CodeModel::Union;
- default:
- std::cerr << "** WARNING unrecognized class type" << std::endl;
- }
- return CodeModel::Class;
-}
-
-const NameSymbol *Binder::decode_symbol(std::size_t index) const
-{
- return _M_token_stream->symbol(index);
-}
-
-void Binder::visitAccessSpecifier(AccessSpecifierAST *node)
-{
- const ListNode<std::size_t> *it = node->specs;
- if (!it)
- return;
-
- it = it->toFront();
- const ListNode<std::size_t> *end = it;
-
- do {
- switch (decode_token(it->element)) {
- default:
- break;
-
- case Token_public:
- changeCurrentAccess(CodeModel::Public);
- changeCurrentFunctionType(CodeModel::Normal);
- break;
- case Token_protected:
- changeCurrentAccess(CodeModel::Protected);
- changeCurrentFunctionType(CodeModel::Normal);
- break;
- case Token_private:
- changeCurrentAccess(CodeModel::Private);
- changeCurrentFunctionType(CodeModel::Normal);
- break;
- case Token_signals:
- changeCurrentAccess(CodeModel::Protected);
- changeCurrentFunctionType(CodeModel::Signal);
- break;
- case Token_slots:
- changeCurrentFunctionType(CodeModel::Slot);
- break;
- }
- it = it->next;
- } while (it != end);
-}
-
-void Binder::visitSimpleDeclaration(SimpleDeclarationAST *node)
-{
- visit(node->type_specifier);
-
- if (const ListNode<InitDeclaratorAST*> *it = node->init_declarators) {
- it = it->toFront();
- const ListNode<InitDeclaratorAST*> *end = it;
- do {
- InitDeclaratorAST *init_declarator = it->element;
- declare_symbol(node, init_declarator);
- it = it->next;
- } while (it != end);
- }
-}
-
-void Binder::declare_symbol(SimpleDeclarationAST *node, InitDeclaratorAST *init_declarator)
-{
- DeclaratorAST *declarator = init_declarator->declarator;
-
- while (declarator && declarator->sub_declarator)
- declarator = declarator->sub_declarator;
-
- NameAST *id = declarator->id;
- if (!declarator->id) {
- std::cerr << "** WARNING expected a declarator id" << std::endl;
- return;
- }
-
- CodeModelFinder finder(model(), this);
- ScopeModelItem symbolScope = finder.resolveScope(id, currentScope());
- if (!symbolScope) {
- name_cc.run(id);
- std::cerr << "** WARNING scope not found for symbol:"
- << qPrintable(name_cc.name()) << std::endl;
- return;
- }
-
- decl_cc.run(declarator);
-
- if (decl_cc.isFunction()) {
- name_cc.run(id->unqualified_name);
-
- FunctionModelItem fun(new _FunctionModelItem(model(), name_cc.name()));
- updateItemPosition(fun, node);
- fun->setAccessPolicy(_M_current_access);
- fun->setFunctionType(_M_current_function_type);
- fun->setAbstract(init_declarator->initializer != 0);
- fun->setConstant(declarator->fun_cv != 0);
- fun->setTemplateParameters(_M_current_template_parameters);
- applyStorageSpecifiers(node->storage_specifiers, fun);
- applyFunctionSpecifiers(node->function_specifiers, fun);
-
- // build the type
- TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
- declarator,
- this);
-
- fun->setType(qualifyType(typeInfo, symbolScope->qualifiedName()));
-
-
- fun->setVariadics(decl_cc.isVariadics());
-
- // ... and the signature
- foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) {
- ArgumentModelItem arg(new _ArgumentModelItem(model(), p.name));
- arg->setType(qualifyType(p.type, _M_context));
- arg->setDefaultValue(p.defaultValue);
- if (p.defaultValue)
- arg->setDefaultValueExpression(p.defaultValueExpression);
- fun->addArgument(arg);
- }
-
- fun->setScope(symbolScope->qualifiedName());
- symbolScope->addFunction(fun);
- } else {
- VariableModelItem var(new _VariableModelItem(model()));
- updateItemPosition(var, node);
- var->setTemplateParameters(_M_current_template_parameters);
- var->setAccessPolicy(_M_current_access);
- name_cc.run(id->unqualified_name);
- var->setName(name_cc.name());
- // Possible bug, because second parameter uses declarator instead of
- // init_declarator->declarator like in DeclaratorCompiler::visitParameterDeclaration,
- // but it doesn't seem to affect anything because the generator doesn't currently use
- // variable declarations, only function declarations (because it cares about the API only,
- // variable declarations are not exposed to the target language).
- // See PYSIDE-455.
- TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
- declarator,
- this);
- if (declarator != init_declarator->declarator
- && init_declarator->declarator->parameter_declaration_clause) {
- typeInfo.setFunctionPointer(true);
- decl_cc.run(init_declarator->declarator);
- foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters())
- typeInfo.addArgument(p.type);
- }
-
- var->setType(qualifyType(typeInfo, _M_context));
- applyStorageSpecifiers(node->storage_specifiers, var);
-
- var->setScope(symbolScope->qualifiedName());
- symbolScope->addVariable(var);
- }
-}
-
-void Binder::visitFunctionDefinition(FunctionDefinitionAST *node)
-{
- Q_ASSERT(node->init_declarator);
-
- ScopeModelItem scope = currentScope();
-
- InitDeclaratorAST *init_declarator = node->init_declarator;
- DeclaratorAST *declarator = init_declarator->declarator;
-
- // in the case of "void (func)()" or "void ((func))()" we need to
- // skip to the inner most. This is in line with how the declarator
- // node is generated in 'parser.cpp'
- while (declarator && declarator->sub_declarator)
- declarator = declarator->sub_declarator;
- if (!declarator->id) {
- std::cerr << "** WARNING temp hack for Qt 5.6.0: "
- << "skipped a class that inherits from a private class"
- << std::endl;
- return;
- }
- Q_ASSERT(declarator->id);
-
- CodeModelFinder finder(model(), this);
-
- ScopeModelItem functionScope = finder.resolveScope(declarator->id, scope);
- if (!functionScope) {
- name_cc.run(declarator->id);
- std::cerr << "** WARNING scope not found for function definition:"
- << qPrintable(name_cc.name()) << std::endl
- << "\tdefinition *ignored*"
- << std::endl;
- return;
- }
-
- decl_cc.run(declarator);
-
- Q_ASSERT(!decl_cc.id().isEmpty());
-
- FunctionModelItem
- old = changeCurrentFunction(FunctionModelItem(new _FunctionModelItem(_M_model)));
- _M_current_function->setScope(functionScope->qualifiedName());
- updateItemPosition(_M_current_function, node);
-
- Q_ASSERT(declarator->id->unqualified_name);
- name_cc.run(declarator->id->unqualified_name);
- QString unqualified_name = name_cc.name();
-
- _M_current_function->setName(unqualified_name);
- TypeInfo tmp_type = CompilerUtils::typeDescription(node->type_specifier,
- declarator, this);
-
- _M_current_function->setType(qualifyType(tmp_type, _M_context));
- _M_current_function->setAccessPolicy(_M_current_access);
- _M_current_function->setFunctionType(_M_current_function_type);
- _M_current_function->setConstant(declarator->fun_cv);
- _M_current_function->setTemplateParameters(_M_current_template_parameters);
-
- applyStorageSpecifiers(node->storage_specifiers,
- _M_current_function);
- applyFunctionSpecifiers(node->function_specifiers,
- _M_current_function);
-
- _M_current_function->setVariadics(decl_cc.isVariadics());
-
- foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters()) {
- ArgumentModelItem arg(new _ArgumentModelItem(model(), p.name));
- arg->setType(qualifyType(p.type, functionScope->qualifiedName()));
- arg->setDefaultValue(p.defaultValue);
- if (p.defaultValue)
- arg->setDefaultValueExpression(p.defaultValueExpression);
- _M_current_function->addArgument(arg);
- }
-
- FunctionModelItem prototype = _M_current_function;
- FunctionModelItem declared = functionScope->declaredFunction(prototype);
-
- // try to find a function declaration for this definition..
- if (!declared) {
- functionScope->addFunction(prototype);
- } else {
- applyFunctionSpecifiers(node->function_specifiers, declared);
-
- // fix the function type and the access policy
- _M_current_function->setAccessPolicy(declared->accessPolicy());
- _M_current_function->setFunctionType(declared->functionType());
- }
-
- changeCurrentFunction(old);
-}
-
-void Binder::visitTemplateDeclaration(TemplateDeclarationAST *node)
-{
- const ListNode<TemplateParameterAST*> *it = node->template_parameters;
- if (!it) {
- // QtScript: we want to visit the declaration still, so that
- // e.g. QMetaTypeId<Foo> is added to the code model
- visit(node->declaration);
- return;
- }
-
- TemplateParameterList savedTemplateParameters = changeTemplateParameters(TemplateParameterList());
-
- it = it->toFront();
- const ListNode<TemplateParameterAST*> *end = it;
-
- TemplateParameterList templateParameters;
- do {
- TemplateParameterAST *parameter = it->element;
- TypeParameterAST *type_parameter = parameter->type_parameter;
-
- NameAST *name;
- if (!type_parameter) {
- // A hacky hack to work around missing support for parameter declarations in
- // templates. We just need the to get the name of the variable, since we
- // aren't actually compiling these anyway. We are still not supporting much
- // more, but we are refusing to fail for a few more declarations
- if (!parameter->parameter_declaration ||
- !parameter->parameter_declaration->declarator ||
- !parameter->parameter_declaration->declarator->id) {
-
- /*std::cerr << "** WARNING template declaration not supported ``";
- Token const &tk = _M_token_stream->token ((int) node->start_token);
- Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
-
- std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
- << std::endl << std::endl;*/
-
- changeTemplateParameters(savedTemplateParameters);
- return;
-
- }
-
- name = parameter->parameter_declaration->declarator->id;
- } else {
- int tk = decode_token(type_parameter->type);
- if (tk != Token_typename && tk != Token_class) {
- /*std::cerr << "** WARNING template declaration not supported ``";
- Token const &tk = _M_token_stream->token ((int) node->start_token);
- Token const &end_tk = _M_token_stream->token ((int) node->declaration->start_token);
-
- std::cerr << std::string (&tk.text[tk.position], (end_tk.position) - tk.position) << "''"
- << std::endl << std::endl;*/
-
- changeTemplateParameters(savedTemplateParameters);
- return;
- }
- assert(tk == Token_typename || tk == Token_class);
-
- name = type_parameter->name;
- }
-
-
- name_cc.run(name);
- const TemplateParameterModelItem p(new _TemplateParameterModelItem(model(), name_cc.name()));
- _M_current_template_parameters.append(p);
- it = it->next;
- } while (it != end);
-
- visit(node->declaration);
-
- changeTemplateParameters(savedTemplateParameters);
-}
-
-void Binder::visitTypedef(TypedefAST *node)
-{
- const ListNode<InitDeclaratorAST*> *it = node->init_declarators;
- if (!it)
- return;
-
- it = it->toFront();
- const ListNode<InitDeclaratorAST*> *end = it;
-
- do {
- InitDeclaratorAST *init_declarator = it->element;
- it = it->next;
-
- Q_ASSERT(init_declarator->declarator);
-
- // the name
- decl_cc.run(init_declarator->declarator);
- QString alias_name = decl_cc.id();
-
- if (alias_name.isEmpty()) {
- std::cerr << "** WARNING anonymous typedef not supported! ``";
- Token const &tk = _M_token_stream->token((int) node->start_token);
- Token const &end_tk = _M_token_stream->token((int) node->end_token);
-
- std::cerr << std::string(&tk.text[tk.position], end_tk.position - tk.position) << "''"
- << std::endl << std::endl;
- continue;
- }
-
- // build the type
- TypeInfo typeInfo = CompilerUtils::typeDescription(node->type_specifier,
- init_declarator->declarator,
- this);
- DeclaratorAST *decl = init_declarator->declarator;
- while (decl && decl->sub_declarator)
- decl = decl->sub_declarator;
-
- if (decl != init_declarator->declarator
- && init_declarator->declarator->parameter_declaration_clause) {
- typeInfo.setFunctionPointer(true);
- decl_cc.run(init_declarator->declarator);
- foreach (const DeclaratorCompiler::Parameter &p, decl_cc.parameters())
- typeInfo.addArgument(p.type);
- }
-
- ScopeModelItem scope = currentScope();
- DeclaratorAST *declarator = init_declarator->declarator;
- CodeModelFinder finder(model(), this);
- ScopeModelItem typedefScope = finder.resolveScope(declarator->id, scope);
-
- TypeDefModelItem typeDef(new _TypeDefModelItem(model()));
- updateItemPosition(typeDef, node);
- typeDef->setName(alias_name);
- typeDef->setType(qualifyType(typeInfo, currentScope()->qualifiedName()));
- typeDef->setScope(typedefScope->qualifiedName());
- _M_qualified_types[typeDef->qualifiedName().join(QLatin1Char('.'))] = QString();
- currentScope()->addTypeDef(typeDef);
- } while (it != end);
-}
-
-void Binder::visitNamespace(NamespaceAST *node)
-{
- bool anonymous = (node->namespace_name == 0);
-
- ScopeModelItem scope = currentScope();
-
- NamespaceModelItem old;
- if (!anonymous) {
- QString name = decode_symbol(node->namespace_name)->as_string();
-
- QStringList qualified_name = scope->qualifiedName();
- qualified_name += name;
- const CodeModelItem nsI = _M_model->findItem(qualified_name, _M_current_file);
- NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(nsI);
- if (!ns) {
- ns.reset(new _NamespaceModelItem(_M_model));
- updateItemPosition(ns, node);
- ns->setName(name);
- ns->setScope(scope->qualifiedName());
- }
- old = changeCurrentNamespace(ns);
-
- _M_context.append(name);
- }
-
- DefaultVisitor::visitNamespace(node);
-
- if (!anonymous) {
- Q_ASSERT(scope->kind() == _CodeModelItem::Kind_Namespace
- || scope->kind() == _CodeModelItem::Kind_File);
-
- _M_context.removeLast();
-
- if (const NamespaceModelItem ns = qSharedPointerDynamicCast<_NamespaceModelItem>(scope))
- ns->addNamespace(_M_current_namespace);
-
- changeCurrentNamespace(old);
- }
-}
-
-void Binder::visitForwardDeclarationSpecifier(ForwardDeclarationSpecifierAST *node)
-{
- name_cc.run(node->name);
- if (name_cc.name().isEmpty())
- return;
-
- ScopeModelItem scope = currentScope();
- _M_qualified_types[(scope->qualifiedName() + name_cc.qualifiedName()).join(QLatin1Char('.'))] = QString();
-}
-
-void Binder::visitClassSpecifier(ClassSpecifierAST *node)
-{
- ClassCompiler class_cc(this);
- class_cc.run(node);
-
- if (class_cc.name().isEmpty()) {
- // anonymous not supported
- return;
- }
-
- Q_ASSERT(node->name && node->name->unqualified_name);
-
- ScopeModelItem scope = currentScope();
-
- ClassModelItem old = changeCurrentClass(ClassModelItem(new _ClassModelItem(_M_model)));
- updateItemPosition(_M_current_class, node);
- _M_current_class->setName(class_cc.name());
-
- QStringList baseClasses = class_cc.baseClasses();
- TypeInfo info;
- for (int i = 0; i < baseClasses.size(); ++i) {
- info.setQualifiedName(baseClasses.at(i).split(QLatin1String("::")));
- baseClasses[i] = qualifyType(info, scope->qualifiedName()).qualifiedName().join(QLatin1String("::"));
- }
-
- _M_current_class->setBaseClasses(baseClasses);
- _M_current_class->setClassType(decode_class_type(node->class_key));
- _M_current_class->setTemplateParameters(_M_current_template_parameters);
-
- if (!_M_current_template_parameters.isEmpty()) {
- QString name = _M_current_class->name();
- name += QLatin1Char('<');
- for (int i = 0; i < _M_current_template_parameters.size(); ++i) {
- if (i > 0)
- name += QLatin1Char(',');
-
- name += _M_current_template_parameters.at(i)->name();
- }
-
- name += QLatin1Char('>');
- _M_current_class->setName(name);
- }
-
- CodeModel::AccessPolicy oldAccessPolicy = changeCurrentAccess(decode_access_policy(node->class_key));
- CodeModel::FunctionType oldFunctionType = changeCurrentFunctionType(CodeModel::Normal);
-
- _M_current_class->setScope(scope->qualifiedName());
- _M_qualified_types[_M_current_class->qualifiedName().join(QLatin1Char('.'))] = QString();
-
- scope->addClass(_M_current_class);
-
- name_cc.run(node->name->unqualified_name);
- _M_context.append(name_cc.name());
- visitNodes(this, node->member_specs);
- _M_context.removeLast();
-
- changeCurrentClass(old);
- changeCurrentAccess(oldAccessPolicy);
- changeCurrentFunctionType(oldFunctionType);
-}
-
-void Binder::visitLinkageSpecification(LinkageSpecificationAST *node)
-{
- DefaultVisitor::visitLinkageSpecification(node);
-}
-
-void Binder::visitUsing(UsingAST *node)
-{
- DefaultVisitor::visitUsing(node);
-}
-
-void Binder::visitEnumSpecifier(EnumSpecifierAST *node)
-{
- CodeModelFinder finder(model(), this);
- ScopeModelItem scope = currentScope();
- ScopeModelItem enumScope = finder.resolveScope(node->name, scope);
-
- name_cc.run(node->name);
- QString name = name_cc.name();
-
- bool isAnonymous = name.isEmpty();
- if (isAnonymous) {
- // anonymous enum
- QString key = _M_context.join(QLatin1String("::"));
- int current = ++_M_anonymous_enums[key];
- name += QLatin1String("enum_");
- name += QString::number(current);
- }
-
- _M_current_enum.reset(new _EnumModelItem(model()));
- _M_current_enum->setAccessPolicy(_M_current_access);
- updateItemPosition(_M_current_enum, node);
- _M_current_enum->setName(name);
- _M_current_enum->setAnonymous(isAnonymous);
- _M_current_enum->setScope(enumScope->qualifiedName());
-
- _M_qualified_types[_M_current_enum->qualifiedName().join(QLatin1Char('.'))] = QString();
-
- enumScope->addEnum(_M_current_enum);
-
- DefaultVisitor::visitEnumSpecifier(node);
-
- _M_current_enum.clear();
-}
-
-static QString strip_preprocessor_lines(const QString &name)
-{
- QStringList lst = name.split(QLatin1Char('\n'));
- QString s;
- for (int i = 0; i < lst.size(); ++i) {
- if (!lst.at(i).startsWith(QLatin1Char('#')))
- s += lst.at(i);
- }
- return s.trimmed();
-}
-
-void Binder::visitEnumerator(EnumeratorAST *node)
-{
- Q_ASSERT(_M_current_enum);
- EnumeratorModelItem e(new _EnumeratorModelItem(model()));
- updateItemPosition(e, node);
- e->setName(decode_symbol(node->id)->as_string());
-
- if (ExpressionAST *expr = node->expression) {
- const Token &start_token = _M_token_stream->token((int) expr->start_token);
- const Token &end_token = _M_token_stream->token((int) expr->end_token);
- const QString token = QString::fromUtf8(&start_token.text[start_token.position],
- (int)(end_token.position - start_token.position));
- QString lines = strip_preprocessor_lines(token.trimmed());
- lines.remove(QLatin1Char(' '));
- e->setValue(lines);
- }
-
- _M_current_enum->addEnumerator(e);
-}
-
-void Binder::visitUsingDirective(UsingDirectiveAST *node)
-{
- DefaultVisitor::visitUsingDirective(node);
-}
-
-void Binder::visitQEnums(QEnumsAST *node)
-{
- const Token &start = _M_token_stream->token((int) node->start_token);
- const Token &end = _M_token_stream->token((int) node->end_token);
- QStringList enum_list = QString::fromLatin1(start.text + start.position,
- end.position - start.position).split(QLatin1Char(' '));
-
- ScopeModelItem scope = currentScope();
- for (int i = 0; i < enum_list.size(); ++i)
- scope->addEnumsDeclaration(enum_list.at(i));
-}
-
-void Binder::visitQProperty(QPropertyAST *node)
-{
- const Token &start = _M_token_stream->token((int) node->start_token);
- const Token &end = _M_token_stream->token((int) node->end_token);
- QString property = QString::fromLatin1(start.text + start.position,
- end.position - start.position);
- _M_current_class->addPropertyDeclaration(property);
-}
-
-void Binder::applyStorageSpecifiers(const ListNode<std::size_t> *it, MemberModelItem item)
-{
- if (!it)
- return;
-
- it = it->toFront();
- const ListNode<std::size_t> *end = it;
-
- do {
- switch (decode_token(it->element)) {
- default:
- break;
-
- case Token_friend:
- item->setFriend(true);
- break;
- case Token_auto:
- item->setAuto(true);
- break;
- case Token_register:
- item->setRegister(true);
- break;
- case Token_static:
- item->setStatic(true);
- break;
- case Token_extern:
- item->setExtern(true);
- break;
- case Token_mutable:
- item->setMutable(true);
- break;
- }
- it = it->next;
- } while (it != end);
-}
-
-void Binder::applyFunctionSpecifiers(const ListNode<std::size_t> *it, FunctionModelItem item)
-{
- if (!it)
- return;
-
- it = it->toFront();
- const ListNode<std::size_t> *end = it;
-
- do {
- switch (decode_token(it->element)) {
- default:
- break;
-
- case Token_inline:
- item->setInline(true);
- break;
-
- case Token_virtual:
- item->setVirtual(true);
- break;
-
- case Token_explicit:
- item->setExplicit(true);
- break;
-
- case Token_Q_INVOKABLE:
- item->setInvokable(true);
- break;
- }
- it = it->next;
- } while (it != end);
-}
-
-TypeInfo Binder::qualifyType(const TypeInfo &type, const QStringList &context) const
-{
- // ### Potentially improve to use string list in the name table to
- if (!context.size()) {
- // ### We can assume that this means global namespace for now...
- return type;
- } else if (_M_qualified_types.contains(type.qualifiedName().join(QLatin1Char('.')))) {
- return type;
- } else {
- QStringList expanded = context;
- expanded << type.qualifiedName();
- if (_M_qualified_types.contains(expanded.join(QLatin1Char('.')))) {
- TypeInfo modified_type = type;
- modified_type.setQualifiedName(expanded);
- return modified_type;
- } else {
- CodeModelItem scope = model()->findItem(context, _M_current_file);
-
- if (ClassModelItem klass = qSharedPointerDynamicCast<_ClassModelItem>(scope)) {
- foreach (const QString &base, klass->baseClasses()) {
- QStringList ctx = context;
- ctx.removeLast();
- ctx.append(base);
-
- TypeInfo qualified = qualifyType(type, ctx);
- if (qualified != type)
- return qualified;
- }
- }
-
- QStringList copy = context;
- copy.removeLast();
- return qualifyType(type, copy);
- }
- }
-}
-
-void Binder::updateItemPosition(CodeModelItem item, AST *node)
-{
- QString filename;
- int line, column;
-
- assert(node);
- _M_location.positionAt(_M_token_stream->position(node->start_token), &line, &column, &filename);
- item->setFileName(filename);
-}