From 9732e0c744e45a67094fc6ce08bdadb1f9a08d4a Mon Sep 17 00:00:00 2001 From: Hugo Lima Date: Mon, 17 Aug 2009 17:32:08 -0300 Subject: The genesis... --- parser/codemodel.cpp | 932 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 932 insertions(+) create mode 100644 parser/codemodel.cpp (limited to 'parser/codemodel.cpp') diff --git a/parser/codemodel.cpp b/parser/codemodel.cpp new file mode 100644 index 000000000..ecc8e3036 --- /dev/null +++ b/parser/codemodel.cpp @@ -0,0 +1,932 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2002-2005 Roberto Raggi + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#include "codemodel.h" + +// --------------------------------------------------------------------------- +CodeModel::CodeModel() + : _M_creation_id(0) +{ + _M_globalNamespace = create(); +} + +CodeModel::~CodeModel() +{ +} + +void CodeModel::wipeout() +{ + _M_globalNamespace = create(); + _M_files.clear(); +} + +FileList CodeModel::files() const +{ + return _M_files.values(); +} + +NamespaceModelItem CodeModel::globalNamespace() const +{ + return _M_globalNamespace; +} + +void CodeModel::addFile(FileModelItem item) +{ + _M_creation_id = 0; // reset the creation id + _M_files.insert(item->name(), item); +} + +void CodeModel::removeFile(FileModelItem item) +{ + QHash::Iterator it = _M_files.find(item->name()); + + if (it != _M_files.end() && it.value() == item) + _M_files.erase(it); +} + +FileModelItem CodeModel::findFile(const QString &name) const +{ + return _M_files.value(name); +} + +QHash CodeModel::fileMap() const +{ + return _M_files; +} + +CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, CodeModelItem scope) const +{ + for (int i = 0; i < qualifiedName.size(); ++i) { + // ### Extend to look for members etc too. + const QString &name = qualifiedName.at(i); + + if (NamespaceModelItem ns = model_dynamic_cast(scope)) { + if (NamespaceModelItem tmp_ns = ns->findNamespace(name)) { + scope = tmp_ns; + continue; + } + } + + if (ScopeModelItem ss = model_dynamic_cast(scope)) { + if (ClassModelItem cs = ss->findClass(name)) { + scope = cs; + } else if (EnumModelItem es = ss->findEnum(name)) { + if (i == qualifiedName.size() - 1) + return es->toItem(); + } else if (TypeAliasModelItem tp = ss->findTypeAlias(name)) { + if (i == qualifiedName.size() - 1) + return tp->toItem(); + } else { + // If we don't find the name in the scope chain we + // need to return an empty item to indicate failure... + return CodeModelItem(); + } + } + } + + return scope; +} + + +// --------------------------------------------------------------------------- +TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs) +{ + TypeInfo __result = __lhs; + + __result.setConstant(__result.isConstant() || __rhs.isConstant()); + __result.setVolatile(__result.isVolatile() || __rhs.isVolatile()); + __result.setReference(__result.isReference() || __rhs.isReference()); + __result.setIndirections(__result.indirections() + __rhs.indirections()); + __result.setArrayElements(__result.arrayElements() + __rhs.arrayElements()); + + return __result; +} + +TypeInfo TypeInfo::resolveType(TypeInfo const &__type, CodeModelItem __scope) +{ + CodeModel *__model = __scope->model(); + Q_ASSERT(__model != 0); + + CodeModelItem __item = __model->findItem(__type.qualifiedName(), __scope); + + // Copy the type and replace with the proper qualified name. This + // only makes sence to do if we're actually getting a resolved + // type with a namespace. We only get this if the returned type + // has more than 2 entries in the qualified name... This test + // could be improved by returning if the type was found or not. + TypeInfo otherType(__type); + if (__item && __item->qualifiedName().size() > 1) { + otherType.setQualifiedName(__item->qualifiedName()); + } + + if (TypeAliasModelItem __alias = model_dynamic_cast (__item)) + return resolveType(TypeInfo::combine(__alias->type(), otherType), __scope); + + return otherType; +} + +QString TypeInfo::toString() const +{ + QString tmp; + + tmp += m_qualifiedName.join("::"); + if (isConstant()) + tmp += QLatin1String(" const"); + + if (isVolatile()) + tmp += QLatin1String(" volatile"); + + if (indirections()) + tmp += QString(indirections(), QLatin1Char('*')); + + if (isReference()) + tmp += QLatin1Char('&'); + + if (isFunctionPointer()) { + tmp += QLatin1String(" (*)("); + for (int i = 0; i < m_arguments.count(); ++i) { + if (i != 0) + tmp += QLatin1String(", "); + + tmp += m_arguments.at(i).toString(); + } + tmp += QLatin1String(")"); + } + + foreach(QString elt, arrayElements()) { + tmp += QLatin1String("["); + tmp += elt; + tmp += QLatin1String("]"); + } + + return tmp; +} + +bool TypeInfo::operator==(const TypeInfo &other) +{ + if (arrayElements().count() != other.arrayElements().count()) + return false; + +#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break + for (int i = 0; i < arrayElements().count(); ++i) { + QString elt1 = arrayElements().at(i).trimmed(); + QString elt2 = other.arrayElements().at(i).trimmed(); + + if (elt1 != elt2) + return false; + } +#endif + + return flags == other.flags + && m_qualifiedName == other.m_qualifiedName + && (!m_functionPointer || m_arguments == other.m_arguments); +} + +// --------------------------------------------------------------------------- +_CodeModelItem::_CodeModelItem(CodeModel *model, int kind) + : _M_model(model), + _M_kind(kind), + _M_startLine(0), + _M_startColumn(0), + _M_endLine(0), + _M_endColumn(0), + _M_creation_id(0) +{ +} + +_CodeModelItem::~_CodeModelItem() +{ +} + +CodeModelItem _CodeModelItem::toItem() const +{ + return CodeModelItem(const_cast<_CodeModelItem*>(this)); +} + +int _CodeModelItem::kind() const +{ + return _M_kind; +} + +void _CodeModelItem::setKind(int kind) +{ + _M_kind = kind; +} + +QStringList _CodeModelItem::qualifiedName() const +{ + QStringList q = scope(); + + if (!name().isEmpty()) + q += name(); + + return q; +} + +QString _CodeModelItem::name() const +{ + return _M_name; +} + +void _CodeModelItem::setName(const QString &name) +{ + _M_name = name; +} + +QStringList _CodeModelItem::scope() const +{ + return _M_scope; +} + +void _CodeModelItem::setScope(const QStringList &scope) +{ + _M_scope = scope; +} + +QString _CodeModelItem::fileName() const +{ + return _M_fileName; +} + +void _CodeModelItem::setFileName(const QString &fileName) +{ + _M_fileName = fileName; +} + +FileModelItem _CodeModelItem::file() const +{ + return model()->findFile(fileName()); +} + +void _CodeModelItem::getStartPosition(int *line, int *column) +{ + *line = _M_startLine; + *column = _M_startColumn; +} + +void _CodeModelItem::setStartPosition(int line, int column) +{ + _M_startLine = line; + _M_startColumn = column; +} + +void _CodeModelItem::getEndPosition(int *line, int *column) +{ + *line = _M_endLine; + *column = _M_endColumn; +} + +void _CodeModelItem::setEndPosition(int line, int column) +{ + _M_endLine = line; + _M_endColumn = column; +} + +// --------------------------------------------------------------------------- +QStringList _ClassModelItem::baseClasses() const +{ + return _M_baseClasses; +} + +void _ClassModelItem::setBaseClasses(const QStringList &baseClasses) +{ + _M_baseClasses = baseClasses; +} + +TemplateParameterList _ClassModelItem::templateParameters() const +{ + return _M_templateParameters; +} + +void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters) +{ + _M_templateParameters = templateParameters; +} + +void _ClassModelItem::addBaseClass(const QString &baseClass) +{ + _M_baseClasses.append(baseClass); +} + +void _ClassModelItem::removeBaseClass(const QString &baseClass) +{ + _M_baseClasses.removeAt(_M_baseClasses.indexOf(baseClass)); +} + +bool _ClassModelItem::extendsClass(const QString &name) const +{ + return _M_baseClasses.contains(name); +} + +void _ClassModelItem::setClassType(CodeModel::ClassType type) +{ + _M_classType = type; +} + +CodeModel::ClassType _ClassModelItem::classType() const +{ + return _M_classType; +} + +void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration) +{ + _M_propertyDeclarations << propertyDeclaration; +} + + +// --------------------------------------------------------------------------- +FunctionModelItem _ScopeModelItem::declaredFunction(FunctionModelItem item) +{ + FunctionList function_list = findFunctions(item->name()); + + foreach(FunctionModelItem fun, function_list) { + if (fun->isSimilar(item)) + return fun; + } + + return FunctionModelItem(); +} + +ClassList _ScopeModelItem::classes() const +{ + return _M_classes.values(); +} + +TypeAliasList _ScopeModelItem::typeAliases() const +{ + return _M_typeAliases.values(); +} + +VariableList _ScopeModelItem::variables() const +{ + return _M_variables.values(); +} + +FunctionList _ScopeModelItem::functions() const +{ + return _M_functions.values(); +} + +void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration) +{ + _M_enumsDeclarations << enumsDeclaration; +} + +FunctionDefinitionList _ScopeModelItem::functionDefinitions() const +{ + return _M_functionDefinitions.values(); +} + +EnumList _ScopeModelItem::enums() const +{ + return _M_enums.values(); +} + +void _ScopeModelItem::addClass(ClassModelItem item) +{ + QString name = item->name(); + int idx = name.indexOf("<"); + if (idx > 0) + _M_classes.insert(name.left(idx), item); + _M_classes.insert(name, item); +} + +void _ScopeModelItem::addFunction(FunctionModelItem item) +{ + _M_functions.insert(item->name(), item); +} + +void _ScopeModelItem::addFunctionDefinition(FunctionDefinitionModelItem item) +{ + _M_functionDefinitions.insert(item->name(), item); +} + +void _ScopeModelItem::addVariable(VariableModelItem item) +{ + _M_variables.insert(item->name(), item); +} + +void _ScopeModelItem::addTypeAlias(TypeAliasModelItem item) +{ + _M_typeAliases.insert(item->name(), item); +} + +void _ScopeModelItem::addEnum(EnumModelItem item) +{ + _M_enums.insert(item->name(), item); +} + +void _ScopeModelItem::removeClass(ClassModelItem item) +{ + QHash::Iterator it = _M_classes.find(item->name()); + + if (it != _M_classes.end() && it.value() == item) + _M_classes.erase(it); +} + +void _ScopeModelItem::removeFunction(FunctionModelItem item) +{ + QMultiHash::Iterator it = _M_functions.find(item->name()); + + while (it != _M_functions.end() && it.key() == item->name() + && it.value() != item) { + ++it; + } + + if (it != _M_functions.end() && it.value() == item) { + _M_functions.erase(it); + } +} + +void _ScopeModelItem::removeFunctionDefinition(FunctionDefinitionModelItem item) +{ + QMultiHash::Iterator it = _M_functionDefinitions.find(item->name()); + + while (it != _M_functionDefinitions.end() && it.key() == item->name() + && it.value() != item) { + ++it; + } + + if (it != _M_functionDefinitions.end() && it.value() == item) { + _M_functionDefinitions.erase(it); + } +} + +void _ScopeModelItem::removeVariable(VariableModelItem item) +{ + QHash::Iterator it = _M_variables.find(item->name()); + + if (it != _M_variables.end() && it.value() == item) + _M_variables.erase(it); +} + +void _ScopeModelItem::removeTypeAlias(TypeAliasModelItem item) +{ + QHash::Iterator it = _M_typeAliases.find(item->name()); + + if (it != _M_typeAliases.end() && it.value() == item) + _M_typeAliases.erase(it); +} + +void _ScopeModelItem::removeEnum(EnumModelItem item) +{ + QHash::Iterator it = _M_enums.find(item->name()); + + if (it != _M_enums.end() && it.value() == item) + _M_enums.erase(it); +} + +ClassModelItem _ScopeModelItem::findClass(const QString &name) const +{ + return _M_classes.value(name); +} + +VariableModelItem _ScopeModelItem::findVariable(const QString &name) const +{ + return _M_variables.value(name); +} + +TypeAliasModelItem _ScopeModelItem::findTypeAlias(const QString &name) const +{ + return _M_typeAliases.value(name); +} + +EnumModelItem _ScopeModelItem::findEnum(const QString &name) const +{ + return _M_enums.value(name); +} + +FunctionList _ScopeModelItem::findFunctions(const QString &name) const +{ + return _M_functions.values(name); +} + +FunctionDefinitionList _ScopeModelItem::findFunctionDefinitions(const QString &name) const +{ + return _M_functionDefinitions.values(name); +} + +// --------------------------------------------------------------------------- +NamespaceList _NamespaceModelItem::namespaces() const +{ + return _M_namespaces.values(); +} +void _NamespaceModelItem::addNamespace(NamespaceModelItem item) +{ + _M_namespaces.insert(item->name(), item); +} +void _NamespaceModelItem::removeNamespace(NamespaceModelItem item) +{ + QHash::Iterator it = _M_namespaces.find(item->name()); + + if (it != _M_namespaces.end() && it.value() == item) + _M_namespaces.erase(it); +} + +NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const +{ + return _M_namespaces.value(name); +} + +// --------------------------------------------------------------------------- +TypeInfo _ArgumentModelItem::type() const +{ + return _M_type; +} + +void _ArgumentModelItem::setType(const TypeInfo &type) +{ + _M_type = type; +} + +bool _ArgumentModelItem::defaultValue() const +{ + return _M_defaultValue; +} + +void _ArgumentModelItem::setDefaultValue(bool defaultValue) +{ + _M_defaultValue = defaultValue; +} + +// --------------------------------------------------------------------------- +bool _FunctionModelItem::isSimilar(FunctionModelItem other) const +{ + if (name() != other->name()) + return false; + + if (isConstant() != other->isConstant()) + return false; + + if (isVariadics() != other->isVariadics()) + return false; + + if (arguments().count() != other->arguments().count()) + return false; + + // ### check the template parameters + + for (int i = 0; i < arguments().count(); ++i) { + ArgumentModelItem arg1 = arguments().at(i); + ArgumentModelItem arg2 = other->arguments().at(i); + + if (arg1->type() != arg2->type()) + return false; + } + + return true; +} + +ArgumentList _FunctionModelItem::arguments() const +{ + return _M_arguments; +} + +void _FunctionModelItem::addArgument(ArgumentModelItem item) +{ + _M_arguments.append(item); +} + +void _FunctionModelItem::removeArgument(ArgumentModelItem item) +{ + _M_arguments.removeAt(_M_arguments.indexOf(item)); +} + +CodeModel::FunctionType _FunctionModelItem::functionType() const +{ + return _M_functionType; +} + +void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType) +{ + _M_functionType = functionType; +} + +bool _FunctionModelItem::isVariadics() const +{ + return _M_isVariadics; +} + +void _FunctionModelItem::setVariadics(bool isVariadics) +{ + _M_isVariadics = isVariadics; +} + +bool _FunctionModelItem::isVirtual() const +{ + return _M_isVirtual; +} + +void _FunctionModelItem::setVirtual(bool isVirtual) +{ + _M_isVirtual = isVirtual; +} + +bool _FunctionModelItem::isInline() const +{ + return _M_isInline; +} + +void _FunctionModelItem::setInline(bool isInline) +{ + _M_isInline = isInline; +} + +bool _FunctionModelItem::isExplicit() const +{ + return _M_isExplicit; +} + +void _FunctionModelItem::setExplicit(bool isExplicit) +{ + _M_isExplicit = isExplicit; +} + +bool _FunctionModelItem::isAbstract() const +{ + return _M_isAbstract; +} + +void _FunctionModelItem::setAbstract(bool isAbstract) +{ + _M_isAbstract = isAbstract; +} + +// Qt +bool _FunctionModelItem::isInvokable() const +{ + return _M_isInvokable; +} + +void _FunctionModelItem::setInvokable(bool isInvokable) +{ + _M_isInvokable = isInvokable; +} + +// --------------------------------------------------------------------------- +TypeInfo _TypeAliasModelItem::type() const +{ + return _M_type; +} + +void _TypeAliasModelItem::setType(const TypeInfo &type) +{ + _M_type = type; +} + +// --------------------------------------------------------------------------- +CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const +{ + return _M_accessPolicy; +} + +void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) +{ + _M_accessPolicy = accessPolicy; +} + +EnumeratorList _EnumModelItem::enumerators() const +{ + return _M_enumerators; +} + +void _EnumModelItem::addEnumerator(EnumeratorModelItem item) +{ + _M_enumerators.append(item); +} + +void _EnumModelItem::removeEnumerator(EnumeratorModelItem item) +{ + _M_enumerators.removeAt(_M_enumerators.indexOf(item)); +} + +// --------------------------------------------------------------------------- +QString _EnumeratorModelItem::value() const +{ + return _M_value; +} + +void _EnumeratorModelItem::setValue(const QString &value) +{ + _M_value = value; +} + +// --------------------------------------------------------------------------- +TypeInfo _TemplateParameterModelItem::type() const +{ + return _M_type; +} + +void _TemplateParameterModelItem::setType(const TypeInfo &type) +{ + _M_type = type; +} + +bool _TemplateParameterModelItem::defaultValue() const +{ + return _M_defaultValue; +} + +void _TemplateParameterModelItem::setDefaultValue(bool defaultValue) +{ + _M_defaultValue = defaultValue; +} + +// --------------------------------------------------------------------------- +ScopeModelItem _ScopeModelItem::create(CodeModel *model) +{ + ScopeModelItem item(new _ScopeModelItem(model)); + return item; +} + +ClassModelItem _ClassModelItem::create(CodeModel *model) +{ + ClassModelItem item(new _ClassModelItem(model)); + return item; +} + +NamespaceModelItem _NamespaceModelItem::create(CodeModel *model) +{ + NamespaceModelItem item(new _NamespaceModelItem(model)); + return item; +} + +FileModelItem _FileModelItem::create(CodeModel *model) +{ + FileModelItem item(new _FileModelItem(model)); + return item; +} + +ArgumentModelItem _ArgumentModelItem::create(CodeModel *model) +{ + ArgumentModelItem item(new _ArgumentModelItem(model)); + return item; +} + +FunctionModelItem _FunctionModelItem::create(CodeModel *model) +{ + FunctionModelItem item(new _FunctionModelItem(model)); + return item; +} + +FunctionDefinitionModelItem _FunctionDefinitionModelItem::create(CodeModel *model) +{ + FunctionDefinitionModelItem item(new _FunctionDefinitionModelItem(model)); + return item; +} + +VariableModelItem _VariableModelItem::create(CodeModel *model) +{ + VariableModelItem item(new _VariableModelItem(model)); + return item; +} + +TypeAliasModelItem _TypeAliasModelItem::create(CodeModel *model) +{ + TypeAliasModelItem item(new _TypeAliasModelItem(model)); + return item; +} + +EnumModelItem _EnumModelItem::create(CodeModel *model) +{ + EnumModelItem item(new _EnumModelItem(model)); + return item; +} + +EnumeratorModelItem _EnumeratorModelItem::create(CodeModel *model) +{ + EnumeratorModelItem item(new _EnumeratorModelItem(model)); + return item; +} + +TemplateParameterModelItem _TemplateParameterModelItem::create(CodeModel *model) +{ + TemplateParameterModelItem item(new _TemplateParameterModelItem(model)); + return item; +} + +// --------------------------------------------------------------------------- +TypeInfo _MemberModelItem::type() const +{ + return _M_type; +} + +void _MemberModelItem::setType(const TypeInfo &type) +{ + _M_type = type; +} + +CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const +{ + return _M_accessPolicy; +} + +void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) +{ + _M_accessPolicy = accessPolicy; +} + +bool _MemberModelItem::isStatic() const +{ + return _M_isStatic; +} + +void _MemberModelItem::setStatic(bool isStatic) +{ + _M_isStatic = isStatic; +} + +bool _MemberModelItem::isConstant() const +{ + return _M_isConstant; +} + +void _MemberModelItem::setConstant(bool isConstant) +{ + _M_isConstant = isConstant; +} + +bool _MemberModelItem::isVolatile() const +{ + return _M_isVolatile; +} + +void _MemberModelItem::setVolatile(bool isVolatile) +{ + _M_isVolatile = isVolatile; +} + +bool _MemberModelItem::isAuto() const +{ + return _M_isAuto; +} + +void _MemberModelItem::setAuto(bool isAuto) +{ + _M_isAuto = isAuto; +} + +bool _MemberModelItem::isFriend() const +{ + return _M_isFriend; +} + +void _MemberModelItem::setFriend(bool isFriend) +{ + _M_isFriend = isFriend; +} + +bool _MemberModelItem::isRegister() const +{ + return _M_isRegister; +} + +void _MemberModelItem::setRegister(bool isRegister) +{ + _M_isRegister = isRegister; +} + +bool _MemberModelItem::isExtern() const +{ + return _M_isExtern; +} + +void _MemberModelItem::setExtern(bool isExtern) +{ + _M_isExtern = isExtern; +} + +bool _MemberModelItem::isMutable() const +{ + return _M_isMutable; +} + +void _MemberModelItem::setMutable(bool isMutable) +{ + _M_isMutable = isMutable; +} + +// kate: space-indent on; indent-width 2; replace-tabs on; + -- cgit v1.2.3